8000 [DI] Allow service subscribers to leverage autowiring to know where t… · symfony/symfony@e407b3d · GitHub
[go: up one dir, main page]

Skip to content

Commit e407b3d

Browse files
[DI] Allow service subscribers to leverage autowiring to know where the locator should be injected
1 parent ac5cfee commit e407b3d

File tree

6 files changed

+65
-26
lines changed

6 files changed

+65
-26
lines changed

src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
<service id="twig.cache_warmer" class="Symfony\Bundle\TwigBundle\CacheWarmer\TemplateCacheCacheWarmer" public="false">
3030
<tag name="kernel.cache_warmer" />
3131
<tag name="container.service_subscriber" id="twig" />
32-
<argument type="service" id="container" />
32+
<argument type="service" id="Psr\Container\ContainerInterface" />
3333
<argument type="service" id="templating.finder" on-invalid="ignore" />
3434
<argument type="collection" /> <!-- Twig paths -->
3535
</service>

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ public function __construct()
5959
new RegisterServiceSubscribersPass(),
6060
new ResolveNamedArgumentsPass(),
6161
new AutowirePass(),
62+
new ResolveServiceSubscribersPass(),
6263
new ResolveReferencesToAliasesPass(),
6364
new ResolveInvalidReferencesPass(),
6465
new AnalyzeServiceReferencesPass(true),

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

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,8 @@
2525
*/
2626
class RegisterServiceSubscribersPass extends AbstractRecursivePass
2727
{
28-
private $serviceLocator;
29-
3028
protected function processValue($value, $isRoot = false)
3129
{
32-
if ($value instanceof Reference && $this->serviceLocator && 'container' === (string) $value) {
33-
return new Reference($this->serviceLocator);
34-
}
35-
3630
if (!$value instanceof Definition || $value->isAbstract() || $value->isSynthetic() || !$value->hasTag('container.service_subscriber')) {
3731
return parent::processValue($value, $isRoot);
3832
}
@@ -100,13 +94,8 @@ protected function processValue($value, $isRoot = false)
10094
throw new InvalidArgumentException(sprintf('Service %s not exist in the map returned by "%s::getSubscribedServices()" for service "%s".', $message, $class, $this->currentId));
10195
}
10296

103-
$serviceLocator = $this->serviceLocator;
104-
$this->serviceLocator = (string) ServiceLocatorTagPass::register($this->container, $subscriberMap);
97+
$value->addTag('container.service_subscriber.locator', array('id' => (string) ServiceLocatorTagPass::register($this->container, $subscriberMap)));
10598

106-
try {
107-
return parent::processValue($value);
108-
} finally {
109-
$this->serviceLocator = $serviceLocator;
110-
}
99+
return parent::processValue($value);
111100
}
112101
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\DependencyInjection\Compiler;
13+
14+
use Psr\Container\ContainerInterface;
15+
use Symfony\Component\DependencyInjection\Definition;
16+
use Symfony\Component\DependencyInjection\Reference;
17+
18+
/**
19+
* Compiler pass to inject their service locator to service subscribers.
20+
*
21+
* @author Nicolas Grekas <p@tchwork.com>
22+
*/
23+
class ResolveServiceSubscribersPass extends AbstractRecursivePass
24+
{
25+
private $serviceLocator;
26+
27+
protected function processValue($value, $isRoot = false)
28+
{
29+
if ($value instanceof Reference && $this->serviceLocator && ContainerInterface::class === (string) $value) {
30+
return new Reference($this->serviceLocator);
31+
}
32+
33+
if (!$value instanceof Definition) {
34+
return parent::processValue($value, $isRoot);
35+
}
36+
37+
$serviceLocator = $this->serviceLocator;
38+
$this->serviceLocator = $value->hasTag('container.service_subscriber.locator') ? $value->getTag('container.service_subscriber.locator')[0]['id'] : null;
39+
40+
try {
41+
return parent::processValue($value);
42+
} finally {
43+
$this->serviceLocator = $serviceLocator;
44+
}
45+
}
46+
}

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

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@
1212
namespace Symfony\Component\DependencyInjection\Tests\Compiler;
1313

1414
use PHPUnit\Framework\TestCase;
15+
use Psr\Container\ContainerInterface as PsrContainerInterface;
1516
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
1617
use Symfony\Component\DependencyInjection\Compiler\RegisterServiceSubscribersPass;
18+
use Symfony\Component\DependencyInjection\Compiler\ResolveServiceSubscribersPass;
1719
use Symfony\Component\DependencyInjection\ContainerBuilder;
1820
use Symfony\Component\DependencyInjection\ContainerInterface;
1921
use Symfony\Component\DependencyInjection\Reference;
@@ -38,8 +40,8 @@ public function testInvalidClass()
3840
->addTag('container.service_subscriber')
3941
;
4042

41-
$pass = new RegisterServiceSubscribersPass();
42-
$pass->process($container);
43+
(new RegisterServiceSubscribersPass())->process($container);
44+
(new ResolveServiceSubscribersPass())->process($container);
4345
}
4446

4547
/**
@@ -54,21 +56,21 @@ public function testInvalidAttributes()
5456
->addTag('container.service_subscriber', array('bar' => '123'))
5557
;
5658

57-
$pass = new RegisterServiceSubscribersPass();
58-
$pass->process($container);
59+
(new RegisterServiceSubscribersPass())->process($container);
60+
(new ResolveServiceSubscribersPass())->process($container);
5961
}
6062

6163
public function testNoAttributes()
6264
{
6365
$container = new ContainerBuilder();
6466

6567
$container->register('foo', TestServiceSubscriber::class)
66-
->addArgument(new Reference('container'))
68+
->addArgument(new Reference(PsrContainerInterface::class))
6769
->addTag('container.service_subscriber')
6870
;
6971

70-
$pass = new RegisterServiceSubscribersPass();
71-
$pass->process($container);
72+
(new RegisterServiceSubscribersPass())->process($container);
73+
(new ResolveServiceSubscribersPass())->process($container);
7274

7375
$foo = $container->getDefinition('foo');
7476
$locator = $container->getDefinition((string) $foo->getArgument(0));
@@ -92,13 +94,13 @@ public function testWithAttributes()
9294

9395
$container->register('foo', TestServiceSubscriber::class)
9496
->setAutowired(true)
95-
->addArgument(new Reference('container'))
97+
->addArgument(new Reference(PsrContainerInterface::class))
9698
->addTag('container.service_subscriber', array('key' => 'bar', 'id' => 'bar'))
9799
->addTag('container.service_subscriber', array('key' => 'bar', 'id' => 'baz')) // should be ignored: the first wins
98100
;
99101

100-
$pass = new RegisterServiceSubscribersPass();
101-
$pass->process($container);
102+
(new RegisterServiceSubscribersPass())->process($container);
103+
(new ResolveServiceSubscribersPass())->process($container);
102104

103105
$foo = $container->getDefinition('foo');
104106
$locator = $container->getDefinition((string) $foo->getArgument(0));
@@ -125,7 +127,7 @@ public function testExtraServiceSubscriber()
125127
$container = new ContainerBuilder();
126128
$container->register('foo_service', TestServiceSubscriber::class)
127129
->setAutowired(true)
128-
->addArgument(new Reference('container'))
130+
->addArgument(new Reference(PsrContainerInterface::class))
129131
->addTag('container.service_subscriber', array(
130132
'key' => 'test',
131133
'id' => TestServiceSubscriber::class,

src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use DummyProxyDumper;
1515
use PHPUnit\Framework\TestCase;
16+
use Psr\Container\ContainerInterface;
1617
use Symfony\Component\Config\FileLocator;
1718
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
1819
use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
@@ -560,7 +561,7 @@ public function testServiceSubscriber()
560561
$container = new ContainerBuilder();
561562
$container->register('foo_service', TestServiceSubscriber::class)
562563
->setAutowired(true)
563-
->addArgument(new Reference('container'))
564+
->addArgument(new Reference(ContainerInterface::class))
564565
->addTag('container.service_subscriber', array(
565566
'key' => 'bar',
566567
'id' => TestServiceSubscriber::class,

0 commit comments

Comments
 (0)
0