Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit d85d9a8

Browse filesBrowse files
committed
[DependencyInjection] Implement lazy collection type using generators
1 parent 69dcf41 commit d85d9a8
Copy full SHA for d85d9a8

File tree

15 files changed

+197
-0
lines changed
Filter options

15 files changed

+197
-0
lines changed

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php
+8Lines changed: 8 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\DependencyInjection\Variable;
1516
use Symfony\Component\DependencyInjection\Definition;
1617
use Symfony\Component\DependencyInjection\ContainerBuilder;
@@ -1348,6 +1349,13 @@ private function dumpValue($value, $interpolate = true)
13481349
}
13491350

13501351
return sprintf('array(%s)', implode(', ', $code));
1352+
} elseif ($value instanceof LazyArgument) {
1353+
$code = array();
1354+
foreach ($value->getValues() as $k => $v) {
1355+
$code[] = sprintf(' yield %s => %s;', $this->dumpValue($k, $interpolate), $this->dumpValue($v, $interpolate));
1356+
}
1357+
1358+
return sprintf("(function(){\n%s\n })()", implode("\n", $code));
13511359
} elseif ($value instanceof Definition) {
13521360
if (null !== $this->definitionVariables && $this->definitionVariables->contains($value)) {
13531361
return $this->dumpValue($this->definitionVariables->offsetGet($value), $interpolate);

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Dumper/XmlDumper.php
+4Lines 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

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php
+5Lines 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) {
+35Lines 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 <fabien@symfony.com>
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 <galopintitouan@gmail.com>
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

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php
+4Lines 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

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Loader/schema/dic/services/services-1.0.xsd
+1Lines 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

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php
+57Lines 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

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container9.php
+5Lines 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

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Fixtures/graphviz/services9.dot
+1Lines 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

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/classes.php
+10Lines 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+
}

‎src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php
+20Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ public function __construct()
4343
'foo_bar' => 'getFooBarService',
4444
'foo_with_inline' => 'getFooWithInlineService',
4545
'inlined' => 'getInlinedService',
46+
'lazy_context' => 'getLazyContextService',
4647
'method_call1' => 'getMethodCall1Service',
4748
'new_factory' => 'getNewFactoryService',
4849
'new_factory_service' => 'getNewFactoryServiceService',
@@ -284,6 +285,25 @@ protected function getFooWithInlineService()
284285
return $instance;
285286
}
286287

288+
/**
289+
* Gets the 'lazy_context' service.
290+
*
291+
* This service is shared.
292+
* This method always returns the same instance of the service.
293+
*
294+
* @return \LazyContext A LazyContext instance
295+
*/
296+
protected function getLazyContextService()
297+
{
298+
return $this->services['lazy_context'] = new \LazyContext((function(){
299+
yield 0 => 'foo';
300+
yield 1 => $this->get('foo.baz');
301+
yield 2 => array($this->getParameter('foo') => 'foo is '.$this->getParameter('foo').'', 'foobar' => $this->getParameter('foo'));
302+
yield 3 => true;
303+
yield 4 => $this;
304+
})());
305+
}
306+
287307
/**
288308
* Gets the 'method_call1' service.
289309
*

‎src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php
+20Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ public function __construct()
4040
'foo.baz' => 'getFoo_BazService',
4141
'foo_bar' => 'getFooBarService',
4242
'foo_with_inline' => 'getFooWithInlineService',
43+
'lazy_context' => 'getLazyContextService',
4344
'method_call1' => 'getMethodCall1Service',
4445
'new_factory_service' => 'getNewFactoryServiceService',
4546
'request' => 'getRequestService',
@@ -283,6 +284,25 @@ protected function getFooWithInlineService()
283284
return $instance;
284285
}
285286

287+
/**
288+
* Gets the 'lazy_context' service.
289+
*
290+
* This service is shared.
291+
* This method always returns the same instance of the service.
292+
*
293+
* @return \LazyContext A LazyContext instance
294+
*/
295+
protected function getLazyContextService()
296+
{
297+
return $this->services['lazy_context'] = new \LazyContext((function(){
298+
yield 0 => 'foo';
299+
yield 1 => $this->get('foo.baz');
300+
yield 2 => array('bar' => 'foo is '.'bar'.'', 'foobar' => 'bar');
301+
yield 3 => true;
302+
yield 4 => $this;
303+
})());
304+
}
305+
286306
/**
287307
* Gets the 'method_call1' service.
288308
*

‎src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services9.xml

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services9.xml
+12Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,18 @@
115115
<service id="factory_service_simple" class="Bar">
116116
<factory service="factory_simple" method="getInstance"/>
117117
</service>
118+
<service id="lazy_context" class="LazyContext">
119+
<argument type="lazy">
120+
<argument>foo</argument>
121+
<argument type="service" id="foo.baz"/>
122+
<argument type="collection">
123+
<argument key="%foo%">foo is %foo%</argument>
124+
<argument key="foobar">%foo%</argument>
125+
</argument>
126+
<argument>true</argument>
127+
<argument type="service" id="service_container"/>
128+
</argument>
129+
</service>
118130
<service id="alias_for_foo" alias="foo"/>
119131
<service id="alias_for_alias" alias="foo"/>
120132
</services>

‎src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services9.yml

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services9.yml
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,5 +107,8 @@ services:
107107
factory_service_simple:
108108
class: Bar
109109
factory: ['@factory_simple', getInstance]
110+
lazy_context:
111+
class: LazyContext
112+
arguments: [[foo, '@foo.baz', { '%foo%': 'foo is %foo%', foobar: '%foo%' }, true, '@service_container']]
110113
alias_for_foo: '@foo'
111114
alias_for_alias: '@foo'

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php
+12Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Symfony\Component\DependencyInjection\ContainerInterface;
1515
use Symfony\Component\DependencyInjection\ContainerBuilder;
16+
use Symfony\Component\DependencyInjection\LazyArgument;
1617
use Symfony\Component\DependencyInjection\Reference;
1718
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
1819
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
@@ -257,6 +258,17 @@ public function testLoadServices()
257258
$this->assertEquals(array('decorated', 'decorated.pif-pouf', 5), $services['decorator_service_with_name_and_priority']->getDecoratedService());
258259
}
259260

261+
public function testParsesLazyArgument()
262+
{
263+
$container = new ContainerBuilder();
264+
$loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
265+
$loader->load('services9.xml');
266+
267+
$lazyDefinition = $container->getDefinition('lazy_context');
268+
269+
$this->assertEquals(array(new LazyArgument(array('foo', new Reference('foo.baz'), array('%foo%' => 'foo is %foo%', 'foobar' => '%foo%'), true, new Reference('service_container')))), $lazyDefinition->getArguments(), '->load() parses lazy arguments');
270+
}
271+
260272
public function testParsesTags()
261273
{
262274
$container = new ContainerBuilder();

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.