diff --git a/src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php b/src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php index 3b8086d0931e6..185a097ebe20b 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php @@ -42,7 +42,7 @@ public function process(ContainerBuilder $container) $tagsToKeep = $container->hasParameter('container.behavior_describing_tags') ? $container->getParameter('container.behavior_describing_tags') - : ['container.do_not_inline', 'container.service_locator', 'container.service_subscriber']; + : ['container.do_not_inline', 'container.service_locator', 'container.service_subscriber', 'container.service_subscriber.locator']; foreach ($definitions as [$id, $definition]) { $decoratedService = $definition->getDecoratedService(); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/DecoratorServicePassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/DecoratorServicePassTest.php index 9a456335569d4..2ec9b41ba9f53 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/DecoratorServicePassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/DecoratorServicePassTest.php @@ -249,7 +249,7 @@ public function testProcessLeavesServiceSubscriberTagOnOriginalDefinition() $container = new ContainerBuilder(); $container ->register('foo') - ->setTags(['container.service_subscriber' => [], 'bar' => ['attr' => 'baz']]) + ->setTags(['container.service_subscriber' => [], 'container.service_subscriber.locator' => [], 'bar' => ['attr' => 'baz']]) ; $container ->register('baz') @@ -259,7 +259,7 @@ public function testProcessLeavesServiceSubscriberTagOnOriginalDefinition() $this->process($container); - $this->assertEquals(['container.service_subscriber' => []], $container->getDefinition('baz.inner')->getTags()); + $this->assertEquals(['container.service_subscriber' => [], 'container.service_subscriber.locator' => []], $container->getDefinition('baz.inner')->getTags()); $this->assertEquals(['bar' => ['attr' => 'baz'], 'foobar' => ['attr' => 'bar']], $container->getDefinition('baz')->getTags()); } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/IntegrationTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/IntegrationTest.php index 5a2b603d41f56..713f1b859ebfe 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/IntegrationTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/IntegrationTest.php @@ -12,6 +12,7 @@ namespace Symfony\Component\DependencyInjection\Tests\Compiler; use PHPUnit\Framework\TestCase; +use Psr\Container\ContainerInterface; use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\Alias; use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument; @@ -129,7 +130,7 @@ public function testProcessInlinesWhenThereAreMultipleReferencesButFromTheSameDe $this->assertFalse($container->hasDefinition('c'), 'Service C was not inlined.'); } - public function testCanDecorateServiceSubscriber() + public function testCanDecorateServiceSubscriberUsingBinding() { $container = new ContainerBuilder(); $container->register(ServiceSubscriberStub::class) @@ -137,11 +138,33 @@ public function testCanDecorateServiceSubscriber() ->setPublic(true); $container->register(DecoratedServiceSubscriber::class) + ->setProperty('inner', new Reference(DecoratedServiceSubscriber::class.'.inner')) ->setDecoratedService(ServiceSubscriberStub::class); $container->compile(); $this->assertInstanceOf(DecoratedServiceSubscriber::class, $container->get(ServiceSubscriberStub::class)); + $this->assertInstanceOf(ServiceSubscriberStub::class, $container->get(ServiceSubscriberStub::class)->inner); + $this->assertInstanceOf(ServiceLocator::class, $container->get(ServiceSubscriberStub::class)->inner->container); + } + + public function testCanDecorateServiceSubscriberReplacingArgument() + { + $container = new ContainerBuilder(); + $container->register(ServiceSubscriberStub::class) + ->setArguments([new Reference(ContainerInterface::class)]) + ->addTag('container.service_subscriber') + ->setPublic(true); + + $container->register(DecoratedServiceSubscriber::class) + ->setProperty('inner', new Reference(DecoratedServiceSubscriber::class.'.inner')) + ->setDecoratedService(ServiceSubscriberStub::class); + + $container->compile(); + + $this->assertInstanceOf(DecoratedServiceSubscriber::class, $container->get(ServiceSubscriberStub::class)); + $this->assertInstanceOf(ServiceSubscriberStub::class, $container->get(ServiceSubscriberStub::class)->inner); + $this->assertInstanceOf(ServiceLocator::class, $container->get(ServiceSubscriberStub::class)->inner->container); } public function testCanDecorateServiceLocator() @@ -515,6 +538,13 @@ public function testTaggedServiceLocatorWithDefaultIndex() class ServiceSubscriberStub implements ServiceSubscriberInterface { + public $container; + + public function __construct(ContainerInterface $container) + { + $this->container = $container; + } + public static function getSubscribedServices(): array { return []; @@ -523,6 +553,7 @@ public static function getSubscribedServices(): array class DecoratedServiceSubscriber { + public $inner; } class DecoratedServiceLocator implements ServiceProviderInterface