Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ad4c2da

Browse files
committed
[DependencyInjection] Implement lazy collection type using generators
1 parent 69dcf41 commit ad4c2da

File tree

15 files changed

+202
-1
lines changed

15 files changed

+202
-1
lines changed

src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Component\DependencyInjection\Dumper;
1313

14+
use Symfony\Component\DependencyInjection\LazyArgument;
1415
use Symfony\Component\DependencyInjection\Variable;
1516
use Symfony\Component\DependencyInjection\Definition;
1617
use Symfony\Component\DependencyInjection\ContainerBuilder;
@@ -632,7 +633,7 @@ private function addService($id, Definition $definition)
632633
}
633634

634635
if ($definition->isAutowired()) {
635-
$doc = <<<EOF
636+
$doc = <<<'EOF'
636637
637638
*
638639
* This service is autowired.
@@ -1348,6 +1349,17 @@ private function dumpValue($value, $interpolate = true)
13481349
}
13491350

13501351
return sprintf('array(%s)', implode(', ', $code));
1352+
} elseif ($value instanceof LazyArgument) {
1353+
$code = array();
1354+
$code[] = 'call_user_func(function() {';
1355+
1356+
foreach ($value->getValues() as $key => $reference) {
1357+
$code[] = sprintf(' yield %s => %s;', $this->dumpValue($key, $interpolate), $this->dumpValue($reference, $interpolate));
1358+
}
1359+
1360+
$code[] = ' })';
1361+
1362+
return implode("\n", $code);
13511363
} elseif ($value instanceof Definition) {
13521364
if (null !== $this->definitionVariables && $this->definitionVariables->contains($value)) {
13531365
return $this->dumpValue($this->definitionVariables->offsetGet($value), $interpolate);

src/Symfony/Component/DependencyInjection/Dumper/XmlDumper.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\DependencyInjection\Dumper;
1313

1414
use Symfony\Component\DependencyInjection\ContainerInterface;
15+
use Symfony\Component\DependencyInjection\LazyArgument;
1516
use Symfony\Component\DependencyInjection\Parameter;
1617
use Symfony\Component\DependencyInjection\Reference;
1718
use Symfony\Component\DependencyInjection\Definition;
@@ -283,6 +284,9 @@ private function convertParameters(array $parameters, $type, \DOMElement $parent
283284
if (is_array($value)) {
284285
$element->setAttribute('type', 'collection');
285286
$this->convertParameters($value, $type, $element, 'key');
287+
} elseif ($value instanceof LazyArgument) {
288+
$element->setAttribute('type', 'lazy');
289+
$this->convertParameters($value->getValues(), $type, $element, 'key');
286290
} elseif ($value instanceof Reference) {
287291
$element->setAttribute('type', 'service');
288292
$element->setAttribute('id', (string) $value);

src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Component\DependencyInjection\Dumper;
1313

14+
use Symfony\Component\DependencyInjection\LazyArgument;
1415
use Symfony\Component\Yaml\Dumper as YmlDumper;
1516
use Symfony\Component\DependencyInjection\Alias;
1617
use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -245,6 +246,10 @@ private function dumpCallable($callable)
245246
*/
246247
private function dumpValue($value)
247248
{
249+
if ($value instanceof LazyArgument) {
250+
$value = $value->getValues();
251+
}
252+
248253
if (is_array($value)) {
249254
$code = array();
250255
foreach ($value as $k => $v) {
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
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;
13+
14+
/**
15+
* Represents a collection of values to lazily iterate over.
16+
*
17+
* @author Titouan Galopin <[email protected]>
18+
*/
19+
class LazyArgument
20+
{
21+
private $values;
22+
23+
public function __construct(array $values)
24+
{
25+
$this->values = $values;
26+
}
27+
28+
/**
29+
* @return array The services to create a lazy collection for
30+
*/
31+
public function getValues()
32+
{
33+
return $this->values;
34+
}
35+
}

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

Lines changed: 4 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\Definition;
1919
use Symfony\Component\DependencyInjection\ChildDefinition;
20+
use Symfony\Component\DependencyInjection\LazyArgument;
2021
use Symfony\Component\DependencyInjection\Reference;
2122
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
2223
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
@@ -401,6 +402,9 @@ private function getArgumentsAsPhp(\DOMElement $node, $name, $lowercase = true)
401402
case 'collection':
402403
$arguments[$key] = $this->getArgumentsAsPhp($arg, $name, false);
403404
break;
405+
case 'lazy':
406+
$arguments[$key] = new LazyArgument($this->getArgumentsAsPhp($arg, $name, false));
407+
break;
404408
case 'string':
405409
$arguments[$key] = $arg->nodeValue;
406410
break;

src/Symfony/Component/DependencyInjection/Loader/schema/dic/services/services-1.0.xsd

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@
189189
<xsd:enumeration value="expression" />
190190
<xsd:enumeration value="string" />
191191
<xsd:enumeration value="constant" />
192+
<xsd:enumeration value="lazy" />
192193
</xsd:restriction>
193194
</xsd:simpleType>
194195

src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Symfony\Component\Config\FileLocator;
1616
use Symfony\Component\DependencyInjection\ContainerBuilder;
1717
use Symfony\Component\DependencyInjection\Dumper\PhpDumper;
18+
use Symfony\Component\DependencyInjection\LazyArgument;
1819
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
1920
use Symfony\Component\DependencyInjection\Reference;
2021
use Symfony\Component\DependencyInjection\Definition;
@@ -391,4 +392,60 @@ public function testCircularReferenceAllowanceForInlinedDefinitionsForLazyServic
391392
$dumper->setProxyDumper(new DummyProxyDumper());
392393
$dumper->dump();
393394
}
395+
396+
public function testLazyArgumentProvideGenerator()
397+
{
398+
require_once self::$fixturesPath.'/includes/classes.php';
399+
400+
$container = new ContainerBuilder();
401+
$container->register('lazy_referenced', 'stdClass');
402+
$container
403+
->register('lazy_context', 'LazyContext')
404+
->setArguments(array(new LazyArgument(array('foo', new Reference('lazy_referenced'), 'k1' => array('foo' => 'bar'), true, 'k2' => new Reference('service_container')))))
405+
;
406+
$container->compile();
407+
408+
$dumper = new PhpDumper($container);
409+
eval('?>'.$dumper->dump(array('class' => 'Symfony_DI_PhpDumper_Test_Lazy_Argument_Provide_Generator')));
410+
411+
$container = new \Symfony_DI_PhpDumper_Test_Lazy_Argument_Provide_Generator();
412+
$lazyContext = $container->get('lazy_context');
413+
414+
$this->assertInstanceOf('\Generator', $lazyContext->lazyValues);
415+
416+
$i = -1;
417+
foreach ($lazyContext->lazyValues as $k => $v) {
418+
++$i;
419+
420+
if ($i === 0) {
421+
$this->assertEquals(0, $k);
422+
$this->assertEquals('foo', $v);
423+
continue;
424+
}
425+
426+
if ($i === 1) {
427+
$this->assertEquals(1, $k);
428+
$this->assertInstanceOf('\stdClass', $v);
429+
continue;
430+
}
431+
432+
if ($i === 2) {
433+
$this->assertEquals('k1', $k);
434+
$this->assertEquals(array('foo' => 'bar'), $v);
435+
continue;
436+
}
437+
438+
if ($i === 3) {
439+
$this->assertEquals(2, $k);
440+
$this->assertTrue($v);
441+
continue;
442+
}
443+
444+
if ($i === 4) {
445+
$this->assertEquals('k2', $k);
446+
$this->assertInstanceOf('\Symfony_DI_PhpDumper_Test_Lazy_Argument_Provide_Generator', $v);
447+
continue;
448+
}
449+
}
450+
}
394451
}

src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container9.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use Symfony\Component\DependencyInjection\ContainerBuilder;
77
use Symfony\Component\DependencyInjection\Reference;
88
use Symfony\Component\DependencyInjection\Parameter;
9+
use Symfony\Component\DependencyInjection\LazyArgument;
910
use Symfony\Component\ExpressionLanguage\Expression;
1011

1112
$container = new ContainerBuilder();
@@ -129,5 +130,9 @@
129130
->register('factory_service_simple', 'Bar')
130131
->setFactory(array(new Reference('factory_simple'), 'getInstance'))
131132
;
133+
$container
134+
->register('lazy_context', 'LazyContext')
135+
->setArguments(array(new LazyArgument(array('foo', new Reference('foo.baz'), array('%foo%' => 'foo is %foo%', 'foobar' => '%foo%'), true, new Reference('service_container')))))
136+
;
132137

133138
return $container;

src/Symfony/Component/DependencyInjection/Tests/Fixtures/graphviz/services9.dot

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ digraph sc {
2626
node_service_from_static_method [label="service_from_static_method\nBar\\FooClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
2727
node_factory_simple [label="factory_simple\nSimpleFactoryClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
2828
node_factory_service_simple [label="factory_service_simple\nBar\n", shape=record, fillcolor="#eeeeee", style="filled"];
29+
node_lazy_context [label="lazy_context\nLazyContext\n", shape=record, fillcolor="#eeeeee", style="filled"];
2930
node_service_container [label="service_container\nSymfony\\Component\\DependencyInjection\\ContainerBuilder\n", shape=record, fillcolor="#9999ff", style="filled"];
3031
node_foo2 [label="foo2\n\n", shape=record, fillcolor="#ff9999", style="filled"];
3132
node_foo3 [label="foo3\n\n", shape=record, fillcolor="#ff9999", style="filled"];

src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/classes.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,13 @@ public function getProxyCode(Definition $definition)
9797
return '';
9898
}
9999
}
100+
101+
class LazyContext
102+
{
103+
public $lazyValues;
104+
105+
public function __construct($lazyValues)
106+
{
107+
$this->lazyValues = $lazyValues;
108+
}
109+
}

0 commit comments

Comments
 (0)