8000 Allow decoration of service locators · symfony/symfony@d20d9a7 · GitHub
[go: up one dir, main page]

Skip to content

Commit d20d9a7

Browse files
committed
Allow decoration of service locators
1 parent d835a8c commit d20d9a7

File tree

3 files changed

+61
-2
lines changed

3 files changed

+61
-2
lines changed

src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,13 @@ public function process(ContainerBuilder $container)
6666
$decoratingDefinition = $decoratingDefinitions[$inner];
6767
$definition->setTags(array_merge($decoratingDefinition->getTags(), $definition->getTags()));
6868
$decoratingDefinition->setTags([]);
69+
if ($definition->hasTag('container.service_locator')) {
70+
// container.service_locator has special logic and it must not be transferred out to decorator
71+
foreach ($definition->getTag('container.service_locator') as $attributes) {
72+
$decoratingDefinition->addTag('container.service_locator', $attributes);
73+
}
74+
$definition->clearTag('container.service_locator');
75+
}
6976
$decoratingDefinitions[$inner] = $definition;
7077
}
7178

src/Symfony/Component/DependencyInjection/Tests/Compiler/DecoratorServicePassTest.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,25 @@ public function testProcessMovesTagsFromDecoratedDefinitionToDecoratingDefinitio
167167
$this->assertEquals(['bar' => ['attr' => 'baz']], $container->getDefinition('deco2')->getTags());
168168
}
169169

170+
public function testProcessLeavesServiceLocatorTagOnOriginalDefinition()
171+
{
172+
$container = new ContainerBuilder();
173+
$container
174+
->register('foo')
175+
->setTags(['container.service_locator' => [0 => []], 'bar' => ['attr' => 'baz']])
176+
;
177+
$container
178+
->register('baz')
179+
->setTags(['foobar' => ['attr' => 'bar']])
180+
->setDecoratedService('foo')
181+
;
182+
183+
$this->process($container);
184+
185+
$this->assertEquals(['container.service_locator' => [0 => []]], $container->getDefinition('baz.inner')->getTags());
186+
$this->assertEquals(['bar' => ['attr' => 'baz'], 'foobar' => ['attr' => 'bar']], $container->getDefinition('baz')->getTags());
187+
}
188+
170189
protected function process(ContainerBuilder $container)
171190
{
172191
$repeatedPass = new DecoratorServicePass();

src/Symfony/Component/DependencyInjection/Tests/Compiler/IntegrationTest.php

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
use Symfony\Component\DependencyInjection\Tests\Fixtures\BarTagClass;
2525
use Symfony\Component\DependencyInjection\Tests\Fixtures\FooBarTaggedClass;
2626
use Symfony\Component\DependencyInjection\Tests\Fixtures\FooTagClass;
27+
use Symfony\Contracts\Service\ServiceProviderInterface;
2728

2829
/**
2930
* This class tests the integration of the different compiler passes.
@@ -145,16 +146,24 @@ public function testCanDecorateServiceSubscriber()
145146
public function testCanDecorateServiceLocator()
146147
{
147148
$container = new ContainerBuilder();
149+
150+
$container->register('foo', 'stdClass')->setPublic(true);
151+
148152
$container->register(ServiceLocator::class)
149153
->addTag('container.service_locator')
154+
->setArguments([[new Reference('foo')]])
150155
;
151156

152157
$container->register(DecoratedServiceLocator::class)
153-
->setDecoratedService(ServiceLocator::class);
158+
->setDecoratedService(ServiceLocator::class)
159+
->setPublic(true)
160+
->setArguments([new Reference(DecoratedServiceLocator::class.'.inner')])
161+
;
154162

155163
$container->compile();
156164

157165
$this->assertInstanceOf(DecoratedServiceLocator::class, $container->get(DecoratedServiceLocator::class));
166+
$this->assertSame($container->get('foo'), $container->get(DecoratedServiceLocator::class)->get('foo'));
158167
}
159168

160169
/**
@@ -431,8 +440,32 @@ class DecoratedServiceSubscriber
431440
{
432441
}
433442

434-
class DecoratedServiceLocator
443+
class DecoratedServiceLocator implements ServiceProviderInterface
435444
{
445+
/**
446+
* @var ServiceLocator
447+
*/
448+
private $locator;
449+
450+
public function __construct(ServiceLocator $locator)
451+
{
452+
$this->locator = $locator;
453+
}
454+
455+
public function get($id)
456+
{
457+
return $this->locator->get($id);
458+
}
459+
460+
public function has($id): bool
461+
{
462+
return $this->locator->has($id);
463+
}
464+
465+
public function getProvidedServices(): array
466+
{
467+
return $this->locator->getProvidedServices();
468+
}
436469
}
437470

438471
class IntegrationTestStub extends IntegrationTestStubParent

0 commit comments

Comments
 (0)
0