Skip to content

Commit a5b4efb

Browse files
[DI] Add ServiceLocatorArgument to generate array-based locators optimized for OPcache shared memory
1 parent 0e9ded3 commit a5b4efb

36 files changed

+533
-198
lines changed

src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Symfony\Component\DependencyInjection\Alias;
1818
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
1919
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
20+
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
2021
use Symfony\Component\DependencyInjection\ContainerBuilder;
2122
use Symfony\Component\DependencyInjection\Definition;
2223
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
@@ -334,6 +335,8 @@ protected function describeContainerDefinition(Definition $definition, array $op
334335
$argumentsInformation[] = sprintf('Service(%s)', (string) $argument);
335336
} elseif ($argument instanceof IteratorArgument) {
336337
$argumentsInformation[] = sprintf('Iterator (%d element(s))', count($argument->getValues()));
338+
} elseif ($argument instanceof ServiceLocatorArgument) {
339+
$argumentsInformation[] = sprintf('Service locator (%d element(s))', count($argument->getValues()));
337340
} elseif ($argument instanceof Definition) {
338341
$argumentsInformation[] = 'Inlined Service';
339342
} else {

src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/XmlDescriptor.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use Symfony\Component\DependencyInjection\Alias;
1515
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
1616
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
17+
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
1718
use Symfony\Component\DependencyInjection\ContainerBuilder;
1819
use Symfony\Component\DependencyInjection\Definition;
1920
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
@@ -387,8 +388,8 @@ private function getArgumentNodes(array $arguments, \DOMDocument $dom)
387388
if ($argument instanceof Reference) {
388389
$argumentXML->setAttribute('type', 'service');
389390
$argumentXML->setAttribute('id', (string) $argument);
390-
} elseif ($argument instanceof IteratorArgument) {
391-
$argumentXML->setAttribute('type', 'iterator');
391+
} elseif ($argument instanceof IteratorArgument || $argument instanceof ServiceLocatorArgument) {
392+
$argumentXML->setAttribute('type', $argument instanceof IteratorArgument ? 'iterator' : 'service_locator');
392393

393394
foreach ($this->getArgumentNodes($argument->getValues(), $dom) as $childArgumentXML) {
394395
$argumentXML->appendChild($childArgumentXML);

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TestServiceContainerWeakRefPass.php

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111

1212
namespace Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler;
1313

14-
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
1514
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
15+
use Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass;
1616
use Symfony\Component\DependencyInjection\ContainerBuilder;
1717
use Symfony\Component\DependencyInjection\Reference;
1818

@@ -32,7 +32,7 @@ public function process(ContainerBuilder $container)
3232

3333
foreach ($definitions as $id => $definition) {
3434
if ($id && '.' !== $id[0] && (!$definition->isPublic() || $definition->isPrivate()) && !$definition->getErrors() && !$definition->isAbstract()) {
35-
$privateServices[$id] = new ServiceClosureArgument(new Reference($id, ContainerBuilder::IGNORE_ON_UNINITIALIZED_REFERENCE));
35+
$privateServices[$id] = new Reference($id, ContainerBuilder::IGNORE_ON_UNINITIALIZED_REFERENCE);
3636
}
3737
}
3838

@@ -44,13 +44,15 @@ public function process(ContainerBuilder $container)
4444
$alias = $aliases[$target];
4545
}
4646
if (isset($definitions[$target]) && !$definitions[$target]->getErrors() && !$definitions[$target]->isAbstract()) {
47-
$privateServices[$id] = new ServiceClosureArgument(new Reference($target, ContainerBuilder::IGNORE_ON_UNINITIALIZED_REFERENCE));
47+
$privateServices[$id] = new Reference($target, ContainerBuilder::IGNORE_ON_UNINITIALIZED_REFERENCE);
4848
}
4949
}
5050
}
5151

5252
if ($privateServices) {
53-
$definitions['test.private_services_locator']->replaceArgument(0, $privateServices);
53+
$id = (string) ServiceLocatorTagPass::register($container, $privateServices);
54+
$container->setDefinition('test.private_services_locator', $container->getDefinition($id))->setPublic(true);
55+
$container->removeDefinition($id);
5456
}
5557
}
5658
}

src/Symfony/Bundle/FrameworkBundle/Resources/config/session.xml

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -58,14 +58,9 @@
5858

5959
<service id="session_listener" class="Symfony\Component\HttpKernel\EventListener\SessionListener">
6060
<tag name="kernel.event_subscriber" />
61-
<argument type="service">
62-
<service class="Symfony\Component\DependencyInjection\ServiceLocator">
63-
<tag name="container.service_locator" />
64-
<argument type="collection">
65-
<argument key="session" type="service" id="session" on-invalid="ignore" />
66-
<argument key="initialized_session" type="service" id="session" on-invalid="ignore_uninitialized" />
67-
</argument>
68-
</service>
61+
<argument type="service_locator">
62+
<argument key="session" type="service" id="session" on-invalid="ignore" />
63+
<argument key="initialized_session" type="service" id="session" on-invalid="ignore_uninitialized" />
6964
</argument>
7065
</service>
7166

src/Symfony/Bundle/FrameworkBundle/Resources/config/test.xml

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,8 @@
2424

2525
<service id="test.session.listener" class="Symfony\Component\HttpKernel\EventListener\TestSessionListener">
2626
<tag name="kernel.event_subscriber" />
27-
<argument type="service">
28-
<service class="Symfony\Component\DependencyInjection\ServiceLocator">
29-
<tag name="container.service_locator" />
30-
<argument type="collection">
31-
<argument key="session" type="service" id="session" on-invalid="ignore" />
32-
</argument>
33-
</service>
27+
<argument type="service_locator">
28+
<argument key="session" type="service" id="session" on-invalid="ignore" />
3429
</argument>
3530
</service>
3631

src/Symfony/Bundle/FrameworkBundle/composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
"php": "^7.1.3",
2020
"ext-xml": "*",
2121
"symfony/cache": "~3.4|~4.0",
22-
"symfony/dependency-injection": "^4.1.1",
22+
"symfony/dependency-injection": "^4.2",
2323
"symfony/config": "~4.2",
2424
"symfony/event-dispatcher": "^4.1",
2525
"symfony/http-foundation": "^4.1",

src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,9 @@
2727
<service id="Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface" alias="security.token_storage" />
2828

2929
<service id="security.helper" class="Symfony\Component\Security\Core\Security">
30-
<argument type="service">
31-
<service class="Symfony\Component\DependencyInjection\ServiceLocator">
32-
<tag name="container.service_locator" />
33-
<argument type="collection">
34-
<argument key="security.token_storage" type="service" id="security.token_storage" />
35-
<argument key="security.authorization_checker" type="service" id="security.authorization_checker" />
36-
</argument>
37-
</service>
30+
<argument type="service_locator">
31+
<argument key="security.token_storage" type="service" id="security.token_storage" />
32+
<argument key="security.authorization_checker" type="service" id="security.authorization_checker" />
3833
</argument>
3934
</service>
4035
<service id="Symfony\Component\Security\Core\Security" alias="security.helper" />

src/Symfony/Bundle/SecurityBundle/composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
"ext-xml": "*",
2121
"symfony/config": "^4.2",
2222
"symfony/security": "~4.2",
23-
"symfony/dependency-injection": "^3.4.3|^4.0.3",
23+
"symfony/dependency-injection": "^4.2",
2424
"symfony/http-kernel": "^4.1"
2525
},
2626
"require-dev": {

src/Symfony/Component/DependencyInjection/Argument/IteratorArgument.php

Lines changed: 1 addition & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -11,45 +11,12 @@
1111

1212
namespace Symfony\Component\DependencyInjection\Argument;
1313

14-
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
15-
use Symfony\Component\DependencyInjection\Reference;
16-
1714
/**
1815
* Represents a collection of values to lazily iterate over.
1916
*
2017
* @author Titouan Galopin <galopintitouan@gmail.com>
2118
*/
2219
class IteratorArgument implements ArgumentInterface
2320
{
24-
private $values;
25-
26-
/**
27-
* @param Reference[] $values
28-
*/
29-
public function __construct(array $values)
30-
{
31-
$this->setValues($values);
32-
}
33-
34-
/**
35-
* @return array The values to lazily iterate over
36-
*/
37-
public function getValues()
38-
{
39-
return $this->values;
40-
}
41-
42-
/**
43-
* @param Reference[] $values The service references to lazily iterate over
44-
*/
45-
public function setValues(array $values)
46-
{
47-
foreach ($values as $k => $v) {
48-
if (null !== $v && !$v instanceof Reference) {
49-
throw new InvalidArgumentException(sprintf('An IteratorArgument must hold only Reference instances, "%s" given.', is_object($v) ? get_class($v) : gettype($v)));
50-
}
51-
}
52-
53-
$this->values = $values;
54-
}
21+
use ReferenceSetArgumentTrait;
5522
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
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\Argument;
13+
14+
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
15+
use Symfony\Component\DependencyInjection\Reference;
16+
17+
/**
18+
* @author Titouan Galopin <galopintitouan@gmail.com>
19+
* @author Nicolas Grekas <p@tchwork.com>
20+
*/
21+
trait ReferenceSetArgumentTrait
22+
{
23+
private $values;
24+
25+
/**
26+
* @param Reference[] $values
27+
*/
28+
public function __construct(array $values)
29+
{
30+
$this->setValues($values);
31+
}
32+
33+
/**
34+
* @return array The values to lazily iterate over
35+
*/
36+
public function getValues()
37+
{
38+
return $this->values;
39+
}
40+
41+
/**
42+
* @param Reference[] $values The service references to lazily iterate over
43+
*/
44+
public function setValues(array $values)
45+
{
46+
foreach ($values as $k => $v) {
47+
if (null !== $v && !$v instanceof Reference) {
48+
throw new InvalidArgumentException(sprintf('A %s must hold only Reference instances, "%s" given.', __CLASS__, is_object($v) ? get_class($v) : gettype($v)));
49+
}
50+
}
51+
52+
$this->values = $values;
53+
}
54+
}

0 commit comments

Comments
 (0)