Skip to content

Navigation Menu

Sign in
Appearance settings

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 4d8bb18

Browse filesBrowse files
mateuszsipnicolas-grekas
authored andcommitted
[DI][Contracts] add and implement ServiceProviderInterface
1 parent d4326b2 commit 4d8bb18
Copy full SHA for 4d8bb18
Expand file treeCollapse file tree

14 files changed

+112
-9
lines changed

‎src/Symfony/Component/DependencyInjection/Argument/ServiceLocator.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Argument/ServiceLocator.php
+11-1Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,13 @@ class ServiceLocator extends BaseServiceLocator
2222
{
2323
private $factory;
2424
private $serviceMap;
25+
private $serviceTypes;
2526

26-
public function __construct(\Closure $factory, array $serviceMap)
27+
public function __construct(\Closure $factory, array $serviceMap, array $serviceTypes = null)
2728
{
2829
$this->factory = $factory;
2930
$this->serviceMap = $serviceMap;
31+
$this->serviceTypes = $serviceTypes;
3032
parent::__construct($serviceMap);
3133
}
3234

@@ -37,4 +39,12 @@ public function get($id)
3739
{
3840
return isset($this->serviceMap[$id]) ? ($this->factory)(...$this->serviceMap[$id]) : parent::get($id);
3941
}
42+
43+
/**
44+
* {@inheritdoc}
45+
*/
46+
public function getProvidedServices(): array
47+
{
48+
return $this->serviceTypes ?? $this->serviceTypes = array_map(function () { return '?'; }, $this->serviceMap);
49+
}
4050
}

‎src/Symfony/Component/DependencyInjection/CHANGELOG.md

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/CHANGELOG.md
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ CHANGELOG
1010
* added support for deprecating aliases
1111
* made `ContainerParametersResource` final and not implement `Serializable` anymore
1212
* added ability to define an index for a tagged collection
13+
* made `ServiceLocator` implement `ServiceProviderInterface`
1314

1415
4.2.0
1516
-----

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Compiler/ResolveServiceSubscribersPass.php
+2-1Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use Psr\Container\ContainerInterface;
1515
use Symfony\Component\DependencyInjection\Definition;
1616
use Symfony\Component\DependencyInjection\Reference;
17+
use Symfony\Contracts\Service\ServiceProviderInterface;
1718

1819
/**
1920
* Compiler pass to inject their service locator to service subscribers.
@@ -26,7 +27,7 @@ class ResolveServiceSubscribersPass extends AbstractRecursivePass
2627

2728
protected function processValue($value, $isRoot = false)
2829
{
29-
if ($value instanceof Reference && $this->serviceLocator && ContainerInterface::class === (string) $value) {
30+
if ($value instanceof Reference && $this->serviceLocator && \in_array((string) $value, [ContainerInterface::class, ServiceProviderInterface::class], true)) {
3031
return new Reference($this->serviceLocator);
3132
}
3233

‎src/Symfony/Component/DependencyInjection/ContainerBuilder.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/ContainerBuilder.php
+3-2Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1234,13 +1234,14 @@ private function doResolveServices($value, array &$inlineServices = [], $isConst
12341234
return $count;
12351235
});
12361236
} elseif ($value instanceof ServiceLocatorArgument) {
1237-
$refs = [];
1237+
$refs = $types = [];
12381238
foreach ($value->getValues() as $k => $v) {
12391239
if ($v) {
12401240
$refs[$k] = [$v];
1241+
$types[$k] = $v instanceof TypedReference ? $v->getType() : '?';
12411242
}
12421243
}
1243-
$value = new ServiceLocator(\Closure::fromCallable([$this, 'resolveServices']), $refs);
1244+
$value = new ServiceLocator(\Closure::fromCallable([$this, 'resolveServices']), $refs, $types);
12441245
} elseif ($value instanceof Reference) {
12451246
$value = $this->doGet((string) $value, $value->getInvalidBehavior(), $inlineServices, $isConstructorArgument);
12461247
} elseif ($value instanceof Definition) {

‎src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php
+3-1Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1546,6 +1546,7 @@ private function dumpValue($value, bool $interpolate = true): string
15461546

15471547
if ($value instanceof ServiceLocatorArgument) {
15481548
$serviceMap = '';
1549+
$serviceTypes = '';
15491550
foreach ($value->getValues() as $k => $v) {
15501551
if (!$v) {
15511552
continue;
@@ -1559,11 +1560,12 @@ private function dumpValue($value, bool $interpolate = true): string
15591560
$this->export(ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE !== $v->getInvalidBehavior() && !\is_string($load) ? $this->generateMethodName($id).($load ? '.php' : '') : null),
15601561
$this->export($load)
15611562
);
1563+
$serviceTypes .= sprintf("\n %s => %s,", $this->export($k), $this->export($v instanceof TypedReference ? $v->getType() : '?'));
15621564
$this->locatedIds[$id] = true;
15631565
}
15641566
$this->addGetService = true;
15651567

1566-
return sprintf('new \%s($this->getService, [%s%s])', ServiceLocator::class, $serviceMap, $serviceMap ? "\n " : '');
1568+
return sprintf('new \%s($this->getService, [%s%s], [%s%s])', ServiceLocator::class, $serviceMap, $serviceMap ? "\n " : '', $serviceTypes, $serviceTypes ? "\n " : '');
15671569
}
15681570
} finally {
15691571
list($this->definitionVariables, $this->referenceVariables) = $scope;

‎src/Symfony/Component/DependencyInjection/ServiceLocator.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/ServiceLocator.php
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,19 @@
1212
namespace Symfony\Component\DependencyInjection;
1313

1414
use Psr\Container\ContainerExceptionInterface;
15-
use Psr\Container\ContainerInterface as PsrContainerInterface;
1615
use Psr\Container\NotFoundExceptionInterface;
1716
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
1817
use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException;
1918
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
2019
use Symfony\Contracts\Service\ServiceLocatorTrait;
20+
use Symfony\Contracts\Service\ServiceProviderInterface;
2121
use Symfony\Contracts\Service\ServiceSubscriberInterface;
2222

2323
/**
2424
* @author Robin Chalas <robin.chalas@gmail.com>
2525
* @author Nicolas Grekas <p@tchwork.com>
2626
*/
27-
class ServiceLocator implements PsrContainerInterface
27+
class ServiceLocator implements ServiceProviderInterface
2828
{
2929
use ServiceLocatorTrait {
3030
get as private doGet;

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_rot13_env.php
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ protected function getContainer_EnvVarProcessorsLocatorService()
7272
{
7373
return $this->services['container.env_var_processors_locator'] = new \Symfony\Component\DependencyInjection\Argument\ServiceLocator($this->getService, [
7474
'rot13' => ['services', 'Symfony\\Component\\DependencyInjection\\Tests\\Dumper\\Rot13EnvVarProcessor', 'getRot13EnvVarProcessorService', false],
75+
], [
76+
'rot13' => '?',
7577
]);
7678
}
7779

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_service_locator_argument.php
+6Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,12 @@ protected function getBarService()
7272
'foo3' => [false, 'foo3', 'getFoo3Service', false],
7373
'foo4' => ['privates', 'foo4', NULL, 'BOOM'],
7474
'foo5' => ['services', 'foo5', NULL, false],
75+
], [
76+
'foo1' => '?',
77+
'foo2' => '?',
78+
'foo3' => '?',
79+
'foo4' => '?',
80+
'foo5' => '?',
7581
]);
7682

7783
return $instance;

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_subscriber.php
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,11 @@ protected function getFooServiceService()
7575
'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber' => ['services', 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber', 'getTestServiceSubscriberService', false],
7676
'bar' => ['services', 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber', 'getTestServiceSubscriberService', false],
7777
'baz' => ['privates', 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition', 'getCustomDefinitionService', false],
78+
], [
79+
'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition' => 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition',
80+
'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber' => 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber',
81+
'bar' => 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition',
82+
'baz' => 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition',
7883
]))->withContext('foo_service', $this));
7984
}
8085

‎src/Symfony/Component/DependencyInjection/Tests/ServiceLocatorTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/ServiceLocatorTest.php
+15Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,21 @@ public function testInvoke()
8686
$this->assertSame('baz', $locator('bar'));
8787
$this->assertNull($locator('dummy'), '->__invoke() should return null on invalid service');
8888
}
89+
90+
public function testProvidesServicesInformation()
91+
{
92+
$locator = new ServiceLocator([
93+
'foo' => function () { return 'bar'; },
94+
'bar' => function (): string { return 'baz'; },
95+
'baz' => function (): ?string { return 'zaz'; },
96+
]);
97+
98+
$this->assertSame($locator->getProvidedServices(), [
99+
'foo' => '?',
100+
'bar' => 'string',
101+
'baz' => '?string',
102+
]);
103+
}
89104
}
90105

91106
class SomeServiceSubscriber implements ServiceSubscriberInterface

0 commit comments

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