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 ef91396

Browse filesBrowse files
beberleifabpot
authored andcommitted
[DependencyInjection] Add factory-class and factory-service concepts to DI Definition. A factory-class is a class-name for the static creation method of a service. A factory-service is the service object that has a factory method to construct a given service. Added tests. Changed Xml, Yaml Dumper and Loaders, PHP Dumper, aswell as the Runtime Builder Container. Graphviz changes missing!
1 parent 27458b6 commit ef91396
Copy full SHA for ef91396

File tree

Expand file treeCollapse file tree

14 files changed

+141
-5
lines changed
Filter options
Expand file treeCollapse file tree

14 files changed

+141
-5
lines changed

‎src/Symfony/Components/DependencyInjection/Builder.php

Copy file name to clipboardExpand all lines: src/Symfony/Components/DependencyInjection/Builder.php
+8-1Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,14 @@ protected function createService(Definition $definition, $id)
334334
$arguments = $this->resolveServices(self::resolveValue($definition->getArguments(), $this->getParameterBag()->all()));
335335

336336
if (null !== $definition->getFactoryMethod()) {
337-
$service = call_user_func_array(array(self::resolveValue($definition->getClass(), $this->getParameterBag()->all()), $definition->getFactoryMethod()), $arguments);
337+
if (null !== $definition->getFactoryService()) {
338+
$factoryService = $this->get(self::resolveValue($definition->getFactoryService(), $this->getParameterBag()->all()));
339+
$service = call_user_func_array(array($factoryService, $definition->getFactoryMethod()), $arguments);
340+
} else if(null !== $definition->getFactoryClass()) {
341+
$service = call_user_func_array(array(self::resolveValue($definition->getFactoryClass(), $this->getParameterBag()->all()), $definition->getFactoryMethod()), $arguments);
342+
} else {
343+
$service = call_user_func_array(array(self::resolveValue($definition->getClass(), $this->getParameterBag()->all()), $definition->getFactoryMethod()), $arguments);
344+
}
338345
} else {
339346
$service = null === $r->getConstructor() ? $r->newInstance() : $r->newInstanceArgs($arguments);
340347
}

‎src/Symfony/Components/DependencyInjection/Definition.php

Copy file name to clipboardExpand all lines: src/Symfony/Components/DependencyInjection/Definition.php
+44-1Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ class Definition
2323
protected $class;
2424
protected $file;
2525
protected $factoryMethod;
26+
protected $factoryService;
27+
protected $factoryClass;
2628
protected $shared;
2729
protected $arguments;
2830
protected $calls;
@@ -61,13 +63,54 @@ public function setFactoryMethod($method)
6163
/**
6264
* Gets the factory method.
6365
*
64-
* @return Definition The factory method name
66+
* @return string The factory method name
6567
*/
6668
public function getFactoryMethod()
6769
{
6870
return $this->factoryMethod;
6971
}
7072

73+
/**
74+
* Set the name of the service that acts as a factory using the specified `constructor` method.
75+
*
76+
* @param string
77+
*/
78+
public function setFactoryService($factoryService)
79+
{
80+
$this->factoryService = $factoryService;
81+
return $this;
82+
}
83+
84+
/**
85+
* @return string
86+
*/
87+
public function getFactoryService()
88+
{
89+
return $this->factoryService;
90+
}
91+
92+
/**
93+
* If service has a constructor method but no factory service, this class is the static callback.
94+
*
95+
* @param string $factoryClass
96+
* @return Definition
97+
*/
98+
public function setFactoryClass($factoryClass)
99+
{
100+
$this->factoryClass = $factoryClass;
101+
return $this;
102+
}
103+
104+
/**
105+
* Get the current static create class for this service.
106+
*
107+
* @return string
108+
*/
109+
public function getFactoryClass()
110+
{
111+
return $this->factoryClass;
112+
}
113+
71114
/**
72115
* Sets the service class.
73116
*

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

Copy file name to clipboardExpand all lines: src/Symfony/Components/DependencyInjection/Dumper/PhpDumper.php
+7-1Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,13 @@ protected function addServiceInstance($id, $definition)
9393
}
9494

9595
if (null !== $definition->getFactoryMethod()) {
96-
$code = sprintf(" \$instance = call_user_func(array(%s, '%s')%s);\n", $class, $definition->getFactoryMethod(), $arguments ? ', '.implode(', ', $arguments) : '');
96+
if (null !== $definition->getFactoryService()) {
97+
$code = sprintf(" \$instance = \$this->get%sService()->%s(%s);\n", $this->dumpValue($definition->getFactoryService()), $definition->getFactoryMethod(), implode(', ', $arguments));
98+
} elseif (null !== $definition->getFactoryClass()) {
99+
$code = sprintf(" \$instance = call_user_func(array(%s, '%s')%s);\n", $this->dumpValue($definition->getFactoryClass()), $definition->getFactoryMethod(), $arguments ? ', '.implode(', ', $arguments) : '');
100+
} else {
101+
$code = sprintf(" \$instance = call_user_func(array(%s, '%s')%s);\n", $class, $definition->getFactoryMethod(), $arguments ? ', '.implode(', ', $arguments) : '');
102+
}
97103
} elseif ($class != "'".str_replace('\\', '\\\\', $definition->getClass())."'") {
98104
$code = sprintf(" \$class = %s;\n \$instance = new \$class(%s);\n", $class, implode(', ', $arguments));
99105
} else {

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

Copy file name to clipboardExpand all lines: src/Symfony/Components/DependencyInjection/Dumper/XmlDumper.php
+3-1Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,12 @@ protected function addParameters()
4747

4848
protected function addService($id, $definition)
4949
{
50-
$code = sprintf(" <service id=\"%s\" class=\"%s\"%s%s>\n",
50+
$code = sprintf(" <service id=\"%s\" class=\"%s\"%s%s%s%s>\n",
5151
$id,
5252
$definition->getClass(),
5353
$definition->getFactoryMethod() ? sprintf(' factory-method="%s"', $definition->getFactoryMethod()) : '',
54+
$definition->getFactoryClass() ? sprintf(' factoryclass="%s"', $definition->getFactoryClass()) : '',
55+
$definition->getFactoryService() ? sprintf(' constructor="%s"', $definition->getFactoryService()) : '',
5456
!$definition->isShared() ? ' shared="false"' : ''
5557
);
5658

‎src/Symfony/Components/DependencyInjection/Dumper/YamlDumper.php

Copy file name to clipboardExpand all lines: src/Symfony/Components/DependencyInjection/Dumper/YamlDumper.php
+8Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,14 @@ protected function addService($id, $definition)
6666
$code .= sprintf(" factory_method: %s\n", $definition->getFactoryMethod());
6767
}
6868

69+
if ($definition->getFactoryClass()) {
70+
$code .= sprintf(" factoryClass: %s\n", $definition->getFactoryClass());
71+
}
72+
73+
if ($definition->getFactoryService()) {
74+
$code .= sprintf(" factoryService: %s\n", $definition->getFactoryService());
75+
}
76+
6977
if ($definition->getArguments()) {
7078
$code .= sprintf(" arguments: %s\n", Yaml::dump($this->dumpValue($definition->getArguments()), 0));
7179
}

‎src/Symfony/Components/DependencyInjection/Loader/XmlFileLoader.php

Copy file name to clipboardExpand all lines: src/Symfony/Components/DependencyInjection/Loader/XmlFileLoader.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ protected function parseDefinition(BuilderConfiguration $configuration, $id, $se
134134

135135
$definition = new Definition((string) $service['class']);
136136

137-
foreach (array('shared', 'factory-method') as $key) {
137+
foreach (array('shared', 'factory-method', 'factoryservice', 'factoryclass') as $key) {
138138
if (isset($service[$key])) {
139139
$method = 'set'.str_replace('-', '', $key);
140140
$definition->$method((string) $service->getAttributeAsPhp($key));

‎src/Symfony/Components/DependencyInjection/Loader/YamlFileLoader.php

Copy file name to clipboardExpand all lines: src/Symfony/Components/DependencyInjection/Loader/YamlFileLoader.php
+8Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,14 @@ protected function parseDefinition(BuilderConfiguration $configuration, $id, $se
141141
$definition->setFactoryMethod($service['factory_method']);
142142
}
143143

144+
if (isset($service['factoryClass'])) {
145+
$definition->setFactoryClass($service['factoryClass']);
146+
}
147+
148+
if (isset($service['factoryService'])) {
149+
$definition->setFactoryService($service['factoryService']);
150+
}
151+
144152
if (isset($service['file'])) {
145153
$definition->setFile($service['file']);
146154
}

‎tests/Symfony/Tests/Components/DependencyInjection/BuilderTest.php

Copy file name to clipboardExpand all lines: tests/Symfony/Tests/Components/DependencyInjection/BuilderTest.php
+23Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,4 +394,27 @@ public function testFindAnnotatedServiceIds()
394394
), '->findAnnotatedServiceIds() returns an array of service ids and its annotation attributes');
395395
$this->assertEquals(array(), $builder->findAnnotatedServiceIds('foobar'), '->findAnnotatedServiceIds() returns an empty array if there is annotated services');
396396
}
397+
398+
public function testFactories()
399+
{
400+
$def1 = new Definition('BazClass');
401+
$def1->setFactoryClass('BazFactory');
402+
$def1->setConstructor('createStatic');
403+
404+
$def2 = new Definition('BazClass');
405+
$def2->setFactoryService('BazFactoryService');
406+
$def2->setFactoryMethod('create');
407+
408+
$def3 = new Definition('BazFactory');
409+
410+
$builder = new Builder();
411+
$builder->addDefinitions(array(
412+
'baz_factory' => $def1,
413+
'baz_service' => $def2,
414+
'BazFactoryService' => $def3,
415+
));
416+
417+
$this->assertType('BazClass', $builder->get('baz_factory'));
418+
$this->assertType('Bazclass', $builder->get('baz_service'));
419+
}
397420
}

‎tests/Symfony/Tests/Components/DependencyInjection/DefinitionTest.php

Copy file name to clipboardExpand all lines: tests/Symfony/Tests/Components/DependencyInjection/DefinitionTest.php
+15Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,21 @@ public function testSetGetConstructor()
3737
$this->assertEquals('foo', $def->getFactoryMethod(), '->getFactoryMethod() returns the factory method name');
3838
}
3939

40+
public function testSetGetFactoryClass()
41+
{
42+
$def = new Definition('stdClass');
43+
$this->assertSame($def, $def->setFactoryClass('stdClass2'), "->setFactoryClass() implements a fluent interface.");
44+
$this->assertEquals('stdClass2', $def->getFactoryClass(), 'Overwrite default factory class method did not work.');
45+
}
46+
47+
public function testSetGetFactoryService()
48+
{
49+
$def = new Definition('stdClass');
50+
$this->assertNull($def->getFactoryService());
51+
$this->assertSame($def, $def->setFactoryService('stdClass2'), "->setFactoryService() implements a fluent interface.");
52+
$this->assertEquals('stdClass2', $def->getFactoryService(), "->getFactoryService() returns current service to construct this service.");
53+
}
54+
4055
/**
4156
* @covers Symfony\Components\DependencyInjection\Definition::setClass
4257
* @covers Symfony\Components\DependencyInjection\Definition::getClass

‎tests/Symfony/Tests/Components/DependencyInjection/Fixtures/includes/classes.php

Copy file name to clipboardExpand all lines: tests/Symfony/Tests/Components/DependencyInjection/Fixtures/includes/classes.php
+13Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,16 @@ static public function configureStatic1()
3030
{
3131
}
3232
}
33+
34+
class BazFactory
35+
{
36+
static public function createStatic()
37+
{
38+
return new BazClass();
39+
}
40+
41+
public function create()
42+
{
43+
return new BazClass();
44+
}
45+
}

‎tests/Symfony/Tests/Components/DependencyInjection/Fixtures/xml/services6.xml

Copy file name to clipboardExpand all lines: tests/Symfony/Tests/Components/DependencyInjection/Fixtures/xml/services6.xml
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,5 +43,8 @@
4343
</call>
4444
</service>
4545
<service id="alias_for_foo" alias="foo" />
46+
47+
<service id="factory_class" constructor="createStatic" factoryclass="BazFactory" />
48+
<service id="factory_service" constructor="create" factoryservice="BazFactoryService" />
4649
</services>
4750
</container>

‎tests/Symfony/Tests/Components/DependencyInjection/Fixtures/yaml/services6.yml

Copy file name to clipboardExpand all lines: tests/Symfony/Tests/Components/DependencyInjection/Fixtures/yaml/services6.yml
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,5 @@ services:
1818
calls:
1919
- [ setBar, [ foo, @foo, [true, false] ] ]
2020
alias_for_foo: @foo
21+
factory_class: { class: BazClass, factoryClass: BazFactory }
22+
factory_service: { class: BazClass, factoryService: BazFactoryService }

‎tests/Symfony/Tests/Components/DependencyInjection/Loader/XmlFileLoaderTest.php

Copy file name to clipboardExpand all lines: tests/Symfony/Tests/Components/DependencyInjection/Loader/XmlFileLoaderTest.php
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,9 @@ public function testLoadServices()
127127
$this->assertEquals(array('BazClass', 'configureStatic'), $services['configurator3']->getConfigurator(), '->load() parses the configurator tag');
128128
$this->assertEquals(array(array('setBar', array())), $services['method_call1']->getMethodCalls(), '->load() parses the method_call tag');
129129
$this->assertEquals(array(array('setBar', array('foo', new Reference('foo'), array(true, false)))), $services['method_call2']->getMethodCalls(), '->load() parses the method_call tag');
130+
$this->assertEquals('BazFactory', $services['factory_class']->getFactoryClass());
131+
$this->assertEquals('BazFactoryService', $services['factory_service']->getFactoryService());
132+
130133
$aliases = $config->getAliases();
131134
$this->assertTrue(isset($aliases['alias_for_foo']), '->load() parses <service> elements');
132135
$this->assertEquals('foo', $aliases['alias_for_foo'], '->load() parses aliases');

‎tests/Symfony/Tests/Components/DependencyInjection/Loader/YamlFileLoaderTest.php

Copy file name to clipboardExpand all lines: tests/Symfony/Tests/Components/DependencyInjection/Loader/YamlFileLoaderTest.php
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ public function testLoadServices()
9494
$this->assertEquals(array('BazClass', 'configureStatic'), $services['configurator3']->getConfigurator(), '->load() parses the configurator tag');
9595
$this->assertEquals(array(array('setBar', array())), $services['method_call1']->getMethodCalls(), '->load() parses the method_call tag');
9696
$this->assertEquals(array(array('setBar', array('foo', new Reference('foo'), array(true, false)))), $services['method_call2']->getMethodCalls(), '->load() parses the method_call tag');
97+
$this->assertEquals('BazFactory', $services['factory_class']->getFactoryClass());
98+
$this->assertEquals('BazFactoryService', $services['factory_service']->getFactoryService());
99+
97100
$aliases = $config->getAliases();
98101
$this->assertTrue(isset($aliases['alias_for_foo']), '->load() parses aliases');
99102
$this->assertEquals('foo', $aliases['alias_for_foo'], '->load() parses aliases');

0 commit comments

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