8000 bug #29944 [DI] Overriding services autowired by name under _defaults… · symfony/symfony@3403a8e · GitHub
[go: up one dir, main page]

Skip to content

Commit 3403a8e

Browse files
bug #29944 [DI] Overriding services autowired by name under _defaults bind not working (przemyslaw-bogusz, renanbr)
This PR was merged into the 3.4 branch. Discussion ---------- [DI] Overriding services autowired by name under _defaults bind not working | Q | A | ------------- | --- | Branch? | 3.4 | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #28326 | License | MIT This is an implementation of ideas and suggestions of @nicolas-grekas and @GuilhemN. Commits ------- 7e805ea more tests 35a40ac [DI] Fixes: #28326 - Overriding services autowired by name under _defaults bind not working
2 parents d134dfc + 7e805ea commit 3403a8e

File tree

11 files changed

+117
-0
lines changed

11 files changed

+117
-0
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ class ResolveBindingsPass extends AbstractRecursivePass
3434
*/
3535
public function process(ContainerBuilder $container)
3636
{
37+
$this->usedBindings = $container->getRemovedBindingIds();
38+
3739
try {
3840
parent::process($container);
3941

src/Symfony/Component/DependencyInjection/ContainerBuilder.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,8 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
123123

124124
private $removedIds = [];
125125

126+
private $removedBindingIds = [];
127+
126128
private static $internalTypes = [
127129
'int' => true,
128130
'float' => true,
@@ -1504,6 +1506,35 @@ public function normalizeId($id)
15041506
return isset($this->definitions[$id]) || isset($this->aliasDefinitions[$id]) || isset($this->removedIds[$id< E864 /span>]) ? $id : parent::normalizeId($id);
15051507
}
15061508

1509+
/**
1510+
* Gets removed binding ids.
1511+
*
1512+
* @return array
1513+
*
1514+
* @internal
1515+
*/
1516+
public function getRemovedBindingIds()
1517+
{
1518+
return $this->removedBindingIds;
1519+
}
1520+
1521+
/**
1522+
* Adds a removed binding id.
1523+
*
1524+
* @param int $id
1525+
*
1526+
* @internal
1527+
*/
1528+
public function addRemovedBindingIds($id)
1529+
{
1530+
if ($this->hasDefinition($id)) {
1531+
foreach ($this->getDefinition($id)->getBindings() as $key => $binding) {
1532+
list(, $bindingId) = $binding->getValues();
1533+
$this->removedBindingIds[(int) $bindingId] = true;
1534+
}
1535+
}
1536+
}
1537+
15071538
/**
15081539
* Returns the Service Conditionals.
15091540
*

src/Symfony/Component/DependencyInjection/Loader/Configurator/ServiceConfigurator.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ public function __destruct()
5959
{
6060
parent::__destruct();
6161

62+
$this->container->addRemovedBindingIds($this->id);
63+
6264
if (!$this->definition instanceof ChildDefinition) {
6365
$this->container->setDefinition($this->id, $this->definition->setInstanceofConditionals($this->instanceof));
6466
} else {

src/Symfony/Component/DependencyInjection/Loader/FileLoader.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@ public function registerClasses(Definition $prototype, $namespace, $resource, $e
9191
*/
9292
protected function setDefinition($id, Definition $definition)
9393
{
94+
$this->container->addRemovedBindingIds($id);
95+
9496
if ($this->isLoadingInstanceof) {
9597
if (!$definition instanceof ChildDefinition) {
9698
throw new InvalidArgumentException(sprintf('Invalid type definition "%s": ChildDefinition expected, "%s" given.', $id, \get_class($definition)));

src/Symfony/Component/DependencyInjection/Tests/Fixtures/Bar.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,11 @@
1313

1414
class Bar implements BarInterface
1515
{
16+
public $quz;
17+
1618
public function __construct($quz = null, \NonExistent $nonExistent = null, BarInterface $decorated = null, array $foo = [])
1719
{
20+
$this->quz = $quz;
1821
}
1922

2023
public static function create(\NonExistent $nonExistent = null, $factory = null)
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
3+
<services>
4+
<defaults>
5+
<bind key="$quz">value</bind>
6+
<bind key="$foo" type="collection">
7+
<bind>value</bind>
8+
</bind>
9+
</defaults>
10+
11+
<service id="bar" class="Symfony\Component\DependencyInjection\Tests\Fixtures\Bar"/>
12+
13+
<service id="foo" class="stdClass"/>
14+
</services>
15+
</container>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
3+
<services>
4+
<defaults>
5+
<bind key="$quz">overridden</bind>
6+
</defaults>
7+
8+
<service id="bar" class="Symfony\Component\DependencyInjection\Tests\Fixtures\Bar"/>
9+
</services>
10+
</container>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
services:
2+
_defaults:
3+
bind:
4+
$quz: value
5+
$foo: [value]
6+
7+
bar:
8+
class: Symfony\Component\DependencyInjection\Tests\Fixtures\Bar
9+
10+
foo:
11+
class: stdClass
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
services:
2+
_defaults:
3+
bind:
4+
$quz: overridden
5+
6+
bar:
7+
class: Symfony\Component\DependencyInjection\Tests\Fixtures\Bar

src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Symfony\Component\Config\Resource\FileResource;
1818
use Symfony\Component\Config\Resource\GlobResource;
1919
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
20+
use Symfony\Component\DependencyInjection\Compiler\ResolveBindingsPass;
2021
use Symfony\Component\DependencyInjection\ContainerBuilder;
2122
use Symfony\Component\DependencyInjection\Dumper\PhpDumper;
2223
use Symfony\Component\DependencyInjection\Loader\IniFileLoader;
@@ -820,4 +821,20 @@ public function testTsantosContainer()
820821
$dump = $dumper->dump();
821822
$this->assertStringEqualsFile(self::$fixturesPath.'/php/services_tsantos.php', $dumper->dump());
822823
}
824+
825+
/**
826+
* The pass may throw an exception, which will cause the test to fail.
827+
*/
828+
public function testOverriddenDefaultsBindings()
829+
{
830+
$container = new ContainerBuilder();
831+
832+
$loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
833+
$loader->load('defaults_bindings.xml');
834+
$loader->load('defaults_bindings2.xml');
835+
836+
(new ResolveBindingsPass())->process($container);
837+
838+
$this->assertSame('overridden', $container->get('bar')->quz);
839+
}
823840
}

src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Symfony\Component\Config\Resource\FileResource;
1818
use Symfony\Component\Config\Resource\GlobResource;
1919
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
20+
use Symfony\Component\DependencyInjection\Compiler\ResolveBindingsPass;
2021
use Symfony\Component\DependencyInjection\ContainerBuilder;
2122
use Symfony\Component\DependencyInjection\Loader\IniFileLoader;
2223
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
@@ -732,4 +733,20 @@ public function testBindings()
732733
'$factory' => 'factory',
733734
], array_map(function ($v) { return $v->getValues()[0]; }, $definition->getBindings()));
734735
}
736+
737+
/**
738+
* The pass may throw an exception, which will cause the test to fail.
739+
*/
740+
public function testOverriddenDefaultsBindings()
741+
{
742+
$container = new ContainerBuilder();
743+
744+
$loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml'));
745+
$loader->load('defaults_bindings.yml');
746+
$loader->load('defaults_bindings2.yml');
747+
748+
(new ResolveBindingsPass())->process($container);
749+
750+
$this->assertSame('overridden', $container->get('bar')->quz);
751+
}
735752
}

0 commit comments

Comments
 (0)
0