[DependencyInjection] throw proper exception when decorating a synthetic service
This commit is contained in:
parent
63e42698d9
commit
b763a29514
@ -14,6 +14,7 @@ namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
use Symfony\Component\DependencyInjection\Alias;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
@ -59,6 +60,7 @@ class DecoratorServicePass implements CompilerPassInterface
|
||||
$public = $alias->isPublic();
|
||||
$private = $alias->isPrivate();
|
||||
$container->setAlias($renamedId, new Alias((string) $alias, false));
|
||||
$decoratedDefinition = $container->findDefinition($alias);
|
||||
} elseif ($container->hasDefinition($inner)) {
|
||||
$decoratedDefinition = $container->getDefinition($inner);
|
||||
$public = $decoratedDefinition->isPublic();
|
||||
@ -72,10 +74,15 @@ class DecoratorServicePass implements CompilerPassInterface
|
||||
} elseif (ContainerInterface::NULL_ON_INVALID_REFERENCE === $invalidBehavior) {
|
||||
$public = $definition->isPublic();
|
||||
$private = $definition->isPrivate();
|
||||
$decoratedDefinition = null;
|
||||
} else {
|
||||
throw new ServiceNotFoundException($inner, $id);
|
||||
}
|
||||
|
||||
if ($decoratedDefinition && $decoratedDefinition->isSynthetic()) {
|
||||
throw new InvalidArgumentException(sprintf('A synthetic service cannot be decorated: service "%s" cannot decorate "%s".', $id, $inner));
|
||||
}
|
||||
|
||||
if (isset($decoratingDefinitions[$inner])) {
|
||||
$decoratingDefinition = $decoratingDefinitions[$inner];
|
||||
|
||||
|
@ -16,6 +16,7 @@ use Symfony\Component\DependencyInjection\Alias;
|
||||
use Symfony\Component\DependencyInjection\Compiler\DecoratorServicePass;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
|
||||
|
||||
class DecoratorServicePassTest extends TestCase
|
||||
@ -262,6 +263,23 @@ class DecoratorServicePassTest extends TestCase
|
||||
$this->assertEquals(['bar' => ['attr' => 'baz'], 'foobar' => ['attr' => 'bar']], $container->getDefinition('baz')->getTags());
|
||||
}
|
||||
|
||||
public function testCannotDecorateSyntheticService()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
$container
|
||||
->register('foo')
|
||||
->setSynthetic(true)
|
||||
;
|
||||
$container
|
||||
->register('baz')
|
||||
->setDecoratedService('foo')
|
||||
;
|
||||
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('A synthetic service cannot be decorated: service "baz" cannot decorate "foo".');
|
||||
$this->process($container);
|
||||
}
|
||||
|
||||
protected function process(ContainerBuilder $container)
|
||||
{
|
||||
$repeatedPass = new DecoratorServicePass();
|
||||
|
Reference in New Issue
Block a user