diff --git a/src/Symfony/Component/DependencyInjection/Argument/BoundArgument.php b/src/Symfony/Component/DependencyInjection/Argument/BoundArgument.php
index f72f2110744c1..332f5354fa8f6 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 63309b3a17e77..41ef09c1146d3 100644
--- a/src/Symfony/Component/DependencyInjection/Compiler/ResolveInstanceofConditionalsPass.php
+++ b/src/Symfony/Component/DependencyInjection/Compiler/ResolveInstanceofConditionalsPass.php
@@ -62,6 +62,7 @@ private function processDefinition(ContainerBuilder $container, $id, Definition
$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 @@ private function processDefinition(ContainerBuilder $container, $id, Definition
$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 @@ private function processDefinition(ContainerBuilder $container, $id, Definition
$instanceofDef->setTags(array());
$instanceofDef->setMethodCalls(array());
+ $instanceofDef->setBindings(array());
if (isset($instanceofDef->getChanges()['shared'])) {
$shared = $instanceofDef->isShared();
@@ -123,7 +126,7 @@ private function processDefinition(ContainerBuilder $container, $id, Definition
}
$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 78a8e3c327f85..ad9a6872b6800 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 11eb8e45c7507..779bfb2e3e5db 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 21e3b593105d2..c7f344fd8340c 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 cc96c5a517849..84bfa6a655f19 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\Compiler\ResolveInstanceofConditionalsPass;
use Symfony\Component\DependencyInjection\Compiler\ResolveChildDefinitionsPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Reference;
class ResolveInstanceofConditionalsPassTest extends TestCase
{
@@ -270,7 +271,30 @@ public function testMergeReset()
$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));