bug #33670 [DI] Service locators can't be decorated (malarzm)
This PR was squashed before being merged into the 4.3 branch.
Discussion
----------
[DI] Service locators can't be decorated
| Q | A
| ------------- | ---
| Branch? | 4.3
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets | n/a
| License | MIT
| Doc PR | n/a
This popped up while I was trying to update my work project as we have decorated the `messenger.receiver_locator` service. Not sure if this is a regression in DI or a change in messenger that caused the issue thus I'm not marking this as a BC break.
Exception while trying to compile the container:
```
Invalid definition for service "Symfony\Component\DependencyInjection\Tests\Compiler\DecoratedServiceLocator": an array of references is expected as first argument when the "container.service_locator" tag is set.
```
Expected result: service locator can be decorated.
Commits
-------
343282b9d4
[DI] Service locators can't be decorated
This commit is contained in:
commit
672fbf5a2b
@ -52,14 +52,14 @@ class PassConfig
|
|||||||
new ValidateEnvPlaceholdersPass(),
|
new ValidateEnvPlaceholdersPass(),
|
||||||
new ResolveChildDefinitionsPass(),
|
new ResolveChildDefinitionsPass(),
|
||||||
new RegisterServiceSubscribersPass(),
|
new RegisterServiceSubscribersPass(),
|
||||||
new DecoratorServicePass(),
|
|
||||||
new ResolveParameterPlaceHoldersPass(false),
|
new ResolveParameterPlaceHoldersPass(false),
|
||||||
new ResolveFactoryClassPass(),
|
|
||||||
new ResolveNamedArgumentsPass(),
|
new ResolveNamedArgumentsPass(),
|
||||||
new AutowireRequiredMethodsPass(),
|
|
||||||
new ResolveBindingsPass(),
|
new ResolveBindingsPass(),
|
||||||
new ServiceLocatorTagPass(),
|
new ServiceLocatorTagPass(),
|
||||||
new CheckDefinitionValidityPass(),
|
new CheckDefinitionValidityPass(),
|
||||||
|
new DecoratorServicePass(),
|
||||||
|
new ResolveFactoryClassPass(),
|
||||||
|
new AutowireRequiredMethodsPass(),
|
||||||
new AutowirePass(false),
|
new AutowirePass(false),
|
||||||
new ResolveTaggedIteratorArgumentPass(),
|
new ResolveTaggedIteratorArgumentPass(),
|
||||||
new ResolveServiceSubscribersPass(),
|
new ResolveServiceSubscribersPass(),
|
||||||
|
@ -24,6 +24,7 @@ use Symfony\Component\DependencyInjection\ServiceSubscriberInterface;
|
|||||||
use Symfony\Component\DependencyInjection\Tests\Fixtures\BarTagClass;
|
use Symfony\Component\DependencyInjection\Tests\Fixtures\BarTagClass;
|
||||||
use Symfony\Component\DependencyInjection\Tests\Fixtures\FooBarTaggedClass;
|
use Symfony\Component\DependencyInjection\Tests\Fixtures\FooBarTaggedClass;
|
||||||
use Symfony\Component\DependencyInjection\Tests\Fixtures\FooTagClass;
|
use Symfony\Component\DependencyInjection\Tests\Fixtures\FooTagClass;
|
||||||
|
use Symfony\Contracts\Service\ServiceProviderInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class tests the integration of the different compiler passes.
|
* This class tests the integration of the different compiler passes.
|
||||||
@ -142,6 +143,29 @@ class IntegrationTest extends TestCase
|
|||||||
$this->assertInstanceOf(DecoratedServiceSubscriber::class, $container->get(ServiceSubscriberStub::class));
|
$this->assertInstanceOf(DecoratedServiceSubscriber::class, $container->get(ServiceSubscriberStub::class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testCanDecorateServiceLocator()
|
||||||
|
{
|
||||||
|
$container = new ContainerBuilder();
|
||||||
|
|
||||||
|
$container->register('foo', 'stdClass')->setPublic(true);
|
||||||
|
|
||||||
|
$container->register(ServiceLocator::class)
|
||||||
|
->addTag('container.service_locator')
|
||||||
|
->setArguments([[new Reference('foo')]])
|
||||||
|
;
|
||||||
|
|
||||||
|
$container->register(DecoratedServiceLocator::class)
|
||||||
|
->setDecoratedService(ServiceLocator::class)
|
||||||
|
->setPublic(true)
|
||||||
|
->setArguments([new Reference(DecoratedServiceLocator::class.'.inner')])
|
||||||
|
;
|
||||||
|
|
||||||
|
$container->compile();
|
||||||
|
|
||||||
|
$this->assertInstanceOf(DecoratedServiceLocator::class, $container->get(DecoratedServiceLocator::class));
|
||||||
|
$this->assertSame($container->get('foo'), $container->get(DecoratedServiceLocator::class)->get('foo'));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider getYamlCompileTests
|
* @dataProvider getYamlCompileTests
|
||||||
*/
|
*/
|
||||||
@ -416,6 +440,34 @@ class DecoratedServiceSubscriber
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class DecoratedServiceLocator implements ServiceProviderInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var ServiceLocator
|
||||||
|
*/
|
||||||
|
private $locator;
|
||||||
|
|
||||||
|
public function __construct(ServiceLocator $locator)
|
||||||
|
{
|
||||||
|
$this->locator = $locator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get($id)
|
||||||
|
{
|
||||||
|
return $this->locator->get($id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function has($id): bool
|
||||||
|
{
|
||||||
|
return $this->locator->has($id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getProvidedServices(): array
|
||||||
|
{
|
||||||
|
return $this->locator->getProvidedServices();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class IntegrationTestStub extends IntegrationTestStubParent
|
class IntegrationTestStub extends IntegrationTestStubParent
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user