diff --git a/src/Symfony/Component/DependencyInjection/Dumper/XmlDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/XmlDumper.php index 38025ff3eac8c..463a3695c0f0b 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/XmlDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/XmlDumper.php @@ -22,6 +22,7 @@ * * @author Fabien Potencier * @author Martin HasoĊˆ + * @author Johannes M. Schmitt * * @api */ @@ -239,6 +240,14 @@ private function convertParameters($parameters, $type, \DOMElement $parent, $key } elseif ($behaviour == ContainerInterface::IGNORE_ON_INVALID_REFERENCE) { $element->setAttribute('on-invalid', 'ignore'); } + + if ( ! $value->isStrict()) { + $element->setAttribute('strict', 'false'); + } + + if ($value->isLazy()) { + $element->setAttribute('lazy', 'true'); + } } elseif ($value instanceof Definition) { $element->setAttribute('type', 'service'); $this->addService($value, null, $element); diff --git a/src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php index 82d68008e0eeb..b4ffa323ac6fb 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php @@ -24,6 +24,7 @@ * YamlDumper dumps a service container as a YAML string. * * @author Fabien Potencier + * @author Johannes M. Schmitt * * @api */ @@ -212,7 +213,15 @@ private function dumpValue($value) return $code; } elseif ($value instanceof Reference) { - return $this->getServiceCall((string) $value, $value); + $call = $this->getServiceCall((string) $value, $value); + if ($value->isLazy()) { + $call .= '~'; + } + if ( ! $value->isStrict()) { + $call .= '='; + } + + return $call; } elseif ($value instanceof Parameter) { return $this->getParameterCall((string) $value); } elseif (is_object($value) || is_resource($value)) { diff --git a/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php index 6f2c8eba1ada6..ebb0b28d5619c 100644 --- a/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php +++ b/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php @@ -25,6 +25,7 @@ * XmlFileLoader loads XML files service definitions. * * @author Fabien Potencier + * @author Johannes M. Schmitt */ class XmlFileLoader extends FileLoader { diff --git a/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php index 71de4ac6592f6..482bab827913b 100644 --- a/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php +++ b/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php @@ -26,6 +26,7 @@ * The YAML format does not support anonymous services (cf. the XML loader). * * @author Fabien Potencier + * @author Johannes M. Schmitt */ class YamlFileLoader extends FileLoader { @@ -298,14 +299,20 @@ private function resolveServices($value) $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE; } + $strict = true; if ('=' === substr($value, -1)) { $value = substr($value, 0, -1); $strict = false; - } else { - $strict = true; + } + + $lazy = false; + if ('~' === substr($value, -1)) { + $value = substr($value, 0, -1); + $lazy = true; } $value = new Reference($value, $invalidBehavior, $strict); + $value->setLazy($lazy); } return $value; 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 316f2d7596870..ab76a77a51227 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 @@ -126,6 +126,7 @@ + @@ -139,6 +140,7 @@ + diff --git a/src/Symfony/Component/DependencyInjection/Reference.php b/src/Symfony/Component/DependencyInjection/Reference.php index 1517da29885a7..8663d7155f6d1 100644 --- a/src/Symfony/Component/DependencyInjection/Reference.php +++ b/src/Symfony/Component/DependencyInjection/Reference.php @@ -15,6 +15,7 @@ * Reference represents a service reference. * * @author Fabien Potencier + * @author Johannes M. Schmitt * * @api */ @@ -23,6 +24,7 @@ class Reference private $id; private $invalidBehavior; private $strict; + private $lazy = false; /** * Constructor. @@ -69,4 +71,28 @@ public function isStrict() { return $this->strict; } + + /** + * Whether this reference should be lazily initialized if available. + * + * @return Boolean + */ + public function isLazy() + { + return $this->lazy; + } + + /** + * Sets the lazily initialization status for this reference. + * + * @param Boolean $bool + * + * @return Reference + */ + public function setLazy($bool) + { + $this->lazy = $bool; + + return $this; + } } diff --git a/src/Symfony/Component/DependencyInjection/SimpleXMLElement.php b/src/Symfony/Component/DependencyInjection/SimpleXMLElement.php index d154602fd330d..9d80041fe1961 100644 --- a/src/Symfony/Component/DependencyInjection/SimpleXMLElement.php +++ b/src/Symfony/Component/DependencyInjection/SimpleXMLElement.php @@ -74,6 +74,11 @@ public function getArgumentsAsPhp($name, $lowercase = true) } $arguments[$key] = new Reference((string) $arg['id'], $invalidBehavior, $strict); + + if (isset($arg['lazy'])) { + $arguments[$key]->setLazy(self::phpize($arg['lazy'])); + } + break; case 'collection': $arguments[$key] = $arg->getArgumentsAsPhp($name, false); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services6.xml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services6.xml index 45bc042f61906..b3fbccec989df 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services6.xml +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services6.xml @@ -46,5 +46,9 @@ + + + + diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services6.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services6.yml index eaa52bda62065..b94cffef3ae19 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services6.yml +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services6.yml @@ -24,3 +24,5 @@ services: alias: foo public: false factory_service: { class: BazClass, factory_method: getInstance, factory_service: baz_factory } + lazy_deps_service: + arguments: ["@foo~", "@bar"] \ No newline at end of file diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php index b589ed95ac036..810855884acc8 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php @@ -173,6 +173,10 @@ public function testLoadServices() $this->assertEquals('getInstance', $services['factory_service']->getFactoryMethod()); $this->assertEquals('baz_factory', $services['factory_service']->getFactoryService()); + $args = $services['lazy_deps_service']->getArguments(); + $this->assertTrue($args[0]->isLazy()); + $this->assertFalse($args[1]->isLazy()); + $aliases = $container->getAliases(); $this->assertTrue(isset($aliases['alias_for_foo']), '->load() parses elements'); $this->assertEquals('foo', (string) $aliases['alias_for_foo'], '->load() parses aliases'); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php index e655d3bd8981a..2ecd5b2935b65 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php @@ -128,6 +128,10 @@ public function testLoadServices() $this->assertEquals(array(array('setBar', array('foo', new Reference('foo'), array(true, false)))), $services['method_call2']->getMethodCalls(), '->load() parses the method_call tag'); $this->assertEquals('baz_factory', $services['factory_service']->getFactoryService()); + $args = $services['lazy_deps_service']->getArguments(); + $this->assertTrue($args[0]->isLazy()); + $this->assertFalse($args[1]->isLazy()); + $aliases = $container->getAliases(); $this->assertTrue(isset($aliases['alias_for_foo']), '->load() parses aliases'); $this->assertEquals('foo', (string) $aliases['alias_for_foo'], '->load() parses aliases');