8000 [DependencyInjection] fixed service resolution for factories · symfony/symfony@5778721 · GitHub
[go: up one dir, main page]

Skip to content

Commit 5778721

Browse files
committed
[DependencyInjection] fixed service resolution for factories
1 parent 8892cf0 commit 5778721

File tree

9 files changed

+67
-7
lines changed

9 files changed

+67
-7
lines changed

src/Symfony/Component/DependencyInjection/Compiler/ResolveParameterPlaceHoldersPass.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ public function process(ContainerBuilder $container)
3737
$definition->setClass($parameterBag->resolveValue($definition->getClass()));
3838
$definition->setFile($parameterBag->resolveValue($definition->getFile()));
3939
$definition->setArguments($parameterBag->resolveValue($definition->getArguments()));
40+
$definition->setFactoryClass($parameterBag->resolveValue($definition->getFactoryClass()));
41+
$definition->setFactoryService($parameterBag->resolveValue($definition->getFactoryService()));
4042

4143
$calls = array();
4244
foreach ($definition->getMethodCalls() as $name => $arguments) {

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -724,7 +724,9 @@ private function addNewInstance($id, Definition $definition, $return, $instantia
724724
}
725725

726726
if (null !== $definition->getFactoryService()) {
727-
return sprintf(" $return{$instantiation}%s->%s(%s);\n", $this->getServiceCall($definition->getFactoryService()), $definition->getFactoryMethod(), implode(', ', $arguments));
727+
$service = $this->dumpValue($definition->getFactoryService());
728+
729+
return sprintf(" $return{$instantiation}%s->%s(%s);\n", 0 === strpos($service, '$') ? sprintf('$this->get(%s)', $service) : $this->getServiceCall($definition->getFactoryService()), $definition->getFactoryMethod(), implode(', ', $arguments));
728730
}
729731

730732
throw new RuntimeException(sprintf('Factory method requires a factory service or factory class in service definition for %s', $id));
@@ -1223,7 +1225,9 @@ private function dumpValue($value, $interpolate = true)
12231225
if (null !== $value->getFactoryClass()) {
12241226
return sprintf("call_user_func(array(%s, '%s')%s)", $this->dumpValue($value->getFactoryClass()), $value->getFactoryMethod(), count($arguments) > 0 ? ', '.implode(', ', $arguments) : '');
12251227
} elseif (null !== $value->getFactoryService()) {
1226-
return sprintf("%s->%s(%s)", $this->getServiceCall($value->getFactoryService()), $value->getFactoryMethod(), implode(', ', $arguments));
1228+
$service = $this->dumpValue($definition->getFactoryService());
1229+
1230+
return sprintf("%s->%s(%s)", 0 === strpos($service, '$') ? sprintf('$this->get(%s)', $service) : $this->getServiceCall($value->getFactoryService()), $value->getFactoryMethod(), implode(', ', $arguments));
12271231
} else {
12281232
throw new RuntimeException('Cannot dump definitions which have factory method without factory service or factory class.');
12291233
}

src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -321,8 +321,14 @@ public function testCreateServiceFactoryMethod()
321321
{
322322
$builder = new ContainerBuilder();
323323
$builder->register('bar', 'stdClass');
324-
$builder->register('foo1', 'FooClass')->setFactoryClass('FooClass')->setFactoryMethod('getInstance')->addArgument(array('foo' => '%value%', '%value%' => 'foo', new Reference('bar')));
324+
$builder
325+
->register('foo1', 'FooClass')
326+
->setFactoryClass('%foo_class%')
327+
->setFactoryMethod('getInstance')
328+
->addArgument(array('foo' => '%value%', '%value%' => 'foo', new Reference('bar')))
329+
;
325330
$builder->setParameter('value', 'bar');
331+
$builder->setParameter('foo_class', 'FooClass');
326332
$this->assertTrue($builder->get('foo1')->called, '->createService() calls the factory method to create the service instance');
327333
$this->assertEquals(array('foo' => 'bar', 'bar' => 'foo', $builder->get('bar')), $builder->get('foo1')->arguments, '->createService() passes the arguments to the factory method');
328334
}
@@ -333,10 +339,14 @@ public function testCreateServiceFactoryMethod()
333339
public function testCreateServiceFactoryService()
334340
{
335341
$builder = new ContainerBuilder();
336-
$builder->register('baz_service')->setFactoryService('baz_factory')->setFactoryMethod('getInstance');
337-
$builder->register('baz_factory', 'BazClass');
338-
339-
$this->assertInstanceOf('BazClass', $builder->get('baz_service'));
342+
$builder->register('foo_service', 'FooClass');
343+
$builder
344+
->register('foo', 'FooClass')
345+
->setFactoryService('%foo_service%')
346+
->setFactoryMethod('getInstance')
347+
;
348+
$builder->setParameter('foo_service', 'foo_service');
349+
$this->assertTrue($builder->get('foo')->called, '->createService() calls the factory method to create the service instance');
340350
}
341351

342352
/**

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
'baz_class' => 'BazClass',
4242
'foo_class' => 'FooClass',
4343
'foo' => 'bar',
44+
'foo_baz_service' => 'foo.baz',
4445
));
4546
$container->setAlias('alias_for_foo', 'foo');
4647
$container->setAlias('alias_for_alias', 'alias_for_foo');
@@ -52,6 +53,11 @@
5253
addMethodCall('setBar', array(new Reference('foo3', ContainerInterface::IGNORE_ON_INVALID_REFERENCE)))->
5354
addMethodCall('setBar', array(new Reference('foobaz', ContainerInterface::IGNORE_ON_INVALID_REFERENCE)))
5455
;
56+
$container->
57+
register('factory_service_parameter', 'Bar')->
58+
setFactoryService('%foo_baz_service%')->
59+
setFactoryMethod('getInstance')
60+
;
5561
$container->
5662
register('factory_service', 'Bar')->
5763
setFactoryService('foo.baz')->

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ digraph sc {
88
node_foo_baz [label="foo.baz\nBazClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
99
node_foo_bar [label="foo_bar\nFooClass\n", shape=record, fillcolor="#eeeeee", style="dotted"];
1010
node_method_call1 [label="method_call1\nFooClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
11+
node_factory_service_parameter [label="factory_service_parameter\nBar\n", shape=record, fillcolor="#eeeeee", style="filled"];
1112
node_factory_service [label="factory_service\nBar\n", shape=record, fillcolor="#eeeeee", style="filled"];
1213
node_foo_with_inline [label="foo_with_inline\nFoo\n", shape=record, fillcolor="#eeeeee", style="filled"];
1314
node_inlined [label="inlined\nBar\n", shape=record, fillcolor="#eeeeee", style="filled"];

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ public function __construct()
3030
'baz' => 'getBazService',
3131
'depends_on_request' => 'getDependsOnRequestService',
3232
'factory_service' => 'getFactoryServiceService',
33+
'factory_service_parameter' => 'getFactoryServiceParameterService',
3334
'foo' => 'getFooService',
3435
'foo.baz' => 'getFoo_BazService',
3536
'foo_bar' => 'getFooBarService',
@@ -108,6 +109,19 @@ protected function getFactoryServiceService()
108109
return $this->services['factory_service'] = $this->get('foo.baz')->getInstance();
109110
}
110111

112+
/**
113+
* Gets the 'factory_service_parameter' service.
114+
*
115+
* This service is shared.
116+
* This method always returns the same instance of the service.
117+
*
118+
* @return \Bar A Bar instance.
119+
*/
120+
protected function getFactoryServiceParameterService()
121+
{
122+
return $this->services['factory_service_parameter'] = $this->get($this->getParameter('foo_baz_service'))->getInstance();
123+
}
124+
111125
/**
112126
* Gets the 'foo' service.
113127
*
@@ -260,6 +274,7 @@ protected function getDefaultParameters()
260274
'baz_class' => 'BazClass',
261275
'foo_class' => 'FooClass',
262276
'foo' => 'bar',
277+
'foo_baz_service' => 'foo.baz',
263278
);
264279
}
265280
}

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ public function __construct()
3939
'baz' => 'getBazService',
4040
'depends_on_request' => 'getDependsOnRequestService',
4141
'factory_service' => 'getFactoryServiceService',
42+
'factory_service_parameter' => 'getFactoryServiceParameterService',
4243
'foo' => 'getFooService',
4344
'foo.baz' => 'getFoo_BazService',
4445
'foo_bar' => 'getFooBarService',
@@ -116,6 +117,19 @@ protected function getFactoryServiceService()
116117
return $this->services['factory_service'] = $this->get('foo.baz')->getInstance();
117118
}
118119

120+
/**
121+
* Gets the 'factory_service_parameter' service.
122+
*
123+
* This service is shared.
124+
* This method always returns the same instance of the service.
125+
*
126+
* @return \Bar A Bar instance.
127+
*/
128+
protected function getFactoryServiceParameterService()
129+
{
130+
return $this->services['factory_service_parameter'] = $this->get('foo.baz')->getInstance();
131+
}
132+
119133
/**
120134
* Gets the 'foo' service.
121135
*
@@ -286,6 +300,7 @@ protected function getDefaultParameters()
286300
'baz_class' => 'BazClass',
287301
'foo_class' => 'FooClass',
288302
'foo' => 'bar',
303+
'foo_baz_service' => 'foo.baz',
289304
);
290305
}
291306
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
<parameter key="baz_class">BazClass</parameter>
55
<parameter key="foo_class">FooClass</parameter>
66
<parameter key="foo">bar</parameter>
7+
<parameter key="foo_baz_service">foo.baz</parameter>
78
</parameters>
89
<services>
910
<service id="foo" class="FooClass" factory-method="getInstance" factory-class="FooClass">
@@ -54,6 +55,7 @@
5455
<argument type="service" id="foobaz" on-invalid="ignore"/>
5556
</call>
5657
</service>
58+
<service id="factory_service_parameter" class="Bar" factory-method="getInstance" factory-service="%foo_baz_service%"/>
5759
<service id="factory_service" CC64 class="Bar" factory-method="getInstance" factory-service="foo.baz"/>
5860
<service id="foo_with_inline" class="Foo">
5961
<call method="setBar">

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ parameters:
22
baz_class: BazClass
33
foo_class: FooClass
44
foo: bar
5+
foo_baz_service: foo.baz
56

67
services:
78
foo:
@@ -39,6 +40,10 @@ services:
3940
- [setBar, ['@?foo3']]
4041
- [setBar, ['@?foobaz']]
4142

43+
factory_service_parameter:
44+
class: Bar
45+
factory_method: getInstance
46+
factory_service: %foo_baz_service%
4247
factory_service:
4348
class: Bar
4449
factory_method: getInstance

0 commit comments

Comments
 (0)
0