diff --git a/src/Symfony/Component/DependencyInjection/Argument/BoundArgument.php b/src/Symfony/Component/DependencyInjection/Argument/BoundArgument.php index f72f211074..332f5354fa 100644 --- a/src/Symfony/Component/DependencyInjection/Argument/BoundArgument.php +++ b/src/Symfony/Component/DependencyInjection/Argument/BoundArgument.php @@ -22,10 +22,14 @@ final class BoundArgument implements ArgumentInterface private $identifier; private $used; - public function __construct($value) + public function __construct($value, bool $trackUsage = true) { $this->value = $value; - $this->identifier = ++self::$sequence; + if ($trackUsage) { + $this->identifier = ++self::$sequence; + } else { + $this->used = true; + } } /** diff --git a/src/Symfony/Component/DependencyInjection/Compiler/ResolveInstanceofConditionalsPass.php b/src/Symfony/Component/DependencyInjection/Compiler/ResolveInstanceofConditionalsPass.php index 3e1250cbdd..cc9b0dd01a 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/ResolveInstanceofConditionalsPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/ResolveInstanceofConditionalsPass.php @@ -62,6 +62,7 @@ class ResolveInstanceofConditionalsPass implements CompilerPassInterface $parent = $shared = null; $instanceofTags = array(); $instanceofCalls = array(); + $instanceofBindings = array(); foreach ($conditionals as $interface => $instanceofDefs) { if ($interface !== $class && (!$container->getReflectionClass($class, false))) { @@ -79,6 +80,7 @@ class ResolveInstanceofConditionalsPass implements CompilerPassInterface $parent = '.instanceof.'.$interface.'.'.$key.'.'.$id; $container->setDefinition($parent, $instanceofDef); $instanceofTags[] = $instanceofDef->getTags(); + $instanceofBindings = $instanceofDef->getBindings() + $instanceofBindings; foreach ($instanceofDef->getMethodCalls() as $methodCall) { $instanceofCalls[] = $methodCall; @@ -86,6 +88,7 @@ class ResolveInstanceofConditionalsPass implements CompilerPassInterface $instanceofDef->setTags(array()); $instanceofDef->setMethodCalls(array()); + $instanceofDef->setBindings(array()); if (isset($instanceofDef->getChanges()['shared'])) { $shared = $instanceofDef->isShared(); @@ -123,7 +126,7 @@ class ResolveInstanceofConditionalsPass implements CompilerPassInterface } $definition->setMethodCalls(array_merge($instanceofCalls, $definition->getMethodCalls())); - $definition->setBindings($bindings); + $definition->setBindings($bindings + $instanceofBindings); // reset fields with "merge" behavior $abstract diff --git a/src/Symfony/Component/DependencyInjection/Loader/Configurator/InstanceofConfigurator.php b/src/Symfony/Component/DependencyInjection/Loader/Configurator/InstanceofConfigurator.php index 78a8e3c327..ad9a6872b6 100644 --- a/src/Symfony/Component/DependencyInjection/Loader/Configurator/InstanceofConfigurator.php +++ b/src/Symfony/Component/DependencyInjection/Loader/Configurator/InstanceofConfigurator.php @@ -26,6 +26,7 @@ class InstanceofConfigurator extends AbstractServiceConfigurator use Traits\PublicTrait; use Traits\ShareTrait; use Traits\TagTrait; + use Traits\BindTrait; /** * Defines an instanceof-conditional to be applied to following service definitions. diff --git a/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php index b73c82a496..e28ac7dbcb 100644 --- a/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php +++ b/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php @@ -93,6 +93,7 @@ class YamlFileLoader extends FileLoader 'calls' => 'calls', 'tags' => 'tags', 'autowire' => 'autowire', + 'bind' => 'bind', ); private static $defaultsKeywords = array( diff --git a/src/Symfony/Component/DependencyInjection/Loader/schema/dic/services/services-1.0.xsd b/src/Symfony/Component/DependencyInjection/Loader/schema/dic/services/services-1.0.xsd index 2e17476cd1..25ef73a14e 100644 --- a/src/Symfony/Component/DependencyInjection/Loader/schema/dic/services/services-1.0.xsd +++ b/src/Symfony/Component/DependencyInjection/Loader/schema/dic/services/services-1.0.xsd @@ -141,6 +141,7 @@ + diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveInstanceofConditionalsPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveInstanceofConditionalsPassTest.php index b211ec355f..e794eab0dc 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveInstanceofConditionalsPassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveInstanceofConditionalsPassTest.php @@ -17,6 +17,7 @@ use Symfony\Component\DependencyInjection\ChildDefinition; use Symfony\Component\DependencyInjection\Compiler\ResolveChildDefinitionsPass; use Symfony\Component\DependencyInjection\Compiler\ResolveInstanceofConditionalsPass; use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; class ResolveInstanceofConditionalsPassTest extends TestCase { @@ -270,7 +271,30 @@ class ResolveInstanceofConditionalsPassTest extends TestCase $this->assertTrue($abstract->isAbstract()); } - public function testBindings() + public function testProcessForAutoconfiguredBindings() + { + $container = new ContainerBuilder(); + + $container->registerForAutoconfiguration(self::class) + ->setBindings(array( + '$foo' => new BoundArgument(234, false), + parent::class => new BoundArgument(new Reference('foo'), false), + )); + + $container->register('foo', self::class) + ->setAutoconfigured(true) + ->setBindings(array('$foo' => new BoundArgument(123, false))); + + (new ResolveInstanceofConditionalsPass())->process($container); + + $expected = array( + '$foo' => new BoundArgument(123, false), + parent::class => new BoundArgument(new Reference('foo'), false), + ); + $this->assertEquals($expected, $container->findDefinition('foo')->getBindings()); + } + + public function testBindingsOnInstanceofConditionals() { $container = new ContainerBuilder(); $def = $container->register('foo', self::class)->setBindings(array('$toto' => 123));