Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 8c74562

Browse filesBrowse files
bug #34998 [DI] fix auto-binding service providers to their service subscribers (nicolas-grekas)
This PR was merged into the 4.3 branch. Discussion ---------- [DI] fix auto-binding service providers to their service subscribers | Q | A | ------------- | --- | Branch? | 4.3 | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | Fix https://github.com/orgs/symfony/projects/1#card-30503621 | License | MIT | Doc PR | - Spotted during a workshop at SymfonyLive Sao Paulo if I recall well :) Commits ------- 6c2ceb0 [DI] fix auto-binding service providers to their service subscribers
2 parents 672fbf5 + 6c2ceb0 commit 8c74562
Copy full SHA for 8c74562

File tree

3 files changed

+45
-1
lines changed
Filter options

3 files changed

+45
-1
lines changed

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Compiler/RegisterServiceSubscribersPass.php
+11-1Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,14 @@
1111

1212
namespace Symfony\Component\DependencyInjection\Compiler;
1313

14+
use Psr\Container\ContainerInterface as PsrContainerInterface;
15+
use Symfony\Component\DependencyInjection\Argument\BoundArgument;
1416
use Symfony\Component\DependencyInjection\ContainerInterface;
1517
use Symfony\Component\DependencyInjection\Definition;
1618
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
1719
use Symfony\Component\DependencyInjection\Reference;
1820
use Symfony\Component\DependencyInjection\TypedReference;
21+
use Symfony\Contracts\Service\ServiceProviderInterface;
1922
use Symfony\Contracts\Service\ServiceSubscriberInterface;
2023

2124
/**
@@ -105,7 +108,14 @@ protected function processValue($value, $isRoot = false)
105108
throw new InvalidArgumentException(sprintf('Service %s not exist in the map returned by "%s::getSubscribedServices()" for service "%s".', $message, $class, $this->currentId));
106109
}
107110

108-
$value->addTag('container.service_subscriber.locator', ['id' => (string) ServiceLocatorTagPass::register($this->container, $subscriberMap, $this->currentId)]);
111+
$locatorRef = ServiceLocatorTagPass::register($this->container, $subscriberMap, $this->currentId);
112+
113+
$value->addTag('container.service_subscriber.locator', ['id' => (string) $locatorRef]);
114+
115+
$value->setBindings([
116+
PsrContainerInterface::class => new BoundArgument($locatorRef, false),
117+
ServiceProviderInterface::class => new BoundArgument($locatorRef, false),
118+
] + $value->getBindings());
109119

110120
return parent::processValue($value);
111121
}

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Compiler/RegisterServiceSubscribersPassTest.php
+29Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
1717
use Symfony\Component\DependencyInjection\Compiler\AutowirePass;
1818
use Symfony\Component\DependencyInjection\Compiler\RegisterServiceSubscribersPass;
19+
use Symfony\Component\DependencyInjection\Compiler\ResolveBindingsPass;
1920
use Symfony\Component\DependencyInjection\Compiler\ResolveServiceSubscribersPass;
2021
use Symfony\Component\DependencyInjection\ContainerBuilder;
2122
use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -235,4 +236,32 @@ public static function getSubscribedServices()
235236
];
236237
$this->assertEquals($expected, $container->getDefinition((string) $locator->getFactory()[0])->getArgument(0));
237238
}
239+
240+
public function testBinding()
241+
{
242+
$container = new ContainerBuilder();
243+
244+
$container->register('foo', TestServiceSubscriber::class)
245+
->addMethodCall('setServiceProvider')
246+
->addTag('container.service_subscriber')
247+
;
248+
249+
(new RegisterServiceSubscribersPass())->process($container);
250+
(new ResolveBindingsPass())->process($container);
251+
252+
$foo = $container->getDefinition('foo');
253+
$locator = $container->getDefinition((string) $foo->getMethodCalls()[0][1][0]);
254+
255+
$this->assertFalse($locator->isPublic());
256+
$this->assertSame(ServiceLocator::class, $locator->getClass());
257+
258+
$expected = [
259+
TestServiceSubscriber::class => new ServiceClosureArgument(new TypedReference(TestServiceSubscriber::class, TestServiceSubscriber::class)),
260+
CustomDefinition::class => new ServiceClosureArgument(new TypedReference(CustomDefinition::class, CustomDefinition::class, ContainerInterface::IGNORE_ON_INVALID_REFERENCE)),
261+
'bar' => new ServiceClosureArgument(new TypedReference(CustomDefinition::class, CustomDefinition::class, ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, 'bar')),
262+
'baz' => new ServiceClosureArgument(new TypedReference(CustomDefinition::class, CustomDefinition::class, ContainerInterface::IGNORE_ON_INVALID_REFERENCE, 'baz')),
263+
];
264+
265+
$this->assertEquals($expected, $container->getDefinition((string) $locator->getFactory()[0])->getArgument(0));
266+
}
238267
}

‎src/Symfony/Component/DependencyInjection/Tests/Fixtures/TestServiceSubscriber.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Fixtures/TestServiceSubscriber.php
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Symfony\Component\DependencyInjection\Tests\Fixtures;
44

5+
use Symfony\Contracts\Service\ServiceProviderInterface;
56
use Symfony\Contracts\Service\ServiceSubscriberInterface;
67

78
class TestServiceSubscriber implements ServiceSubscriberInterface
@@ -10,6 +11,10 @@ public function __construct($container)
1011
{
1112
}
1213

14+
public function setServiceProvider(ServiceProviderInterface $container)
15+
{
16+
}
17+
1318
public static function getSubscribedServices()
1419
{
1520
return [

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.