bug #13519 [DependencyInjection] fixed service resolution for factories (fabpot)
This PR was merged into the 2.3 branch.
Discussion
----------
[DependencyInjection] fixed service resolution for factories
| Q | A
| ------------- | ---
| Bug fix? | yes
| New feature? | no
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | #13455
| License | MIT
| Doc PR | n/a
In the service container, factories can be defined with a class/method pair or a service/method pair.
The class or service value can be a container parameter, but it was not supported everywhere, this PR fixes that.
Note that the method can never be a container parameter as this is supported nowhere in the current code, so this has not been changed.
Another PR will fix the 2.6 way of configuring a factory.
Commits
-------
f86ad95
[DependencyInjection] fixed service resolution for factories
This commit is contained in:
commit
e34387d7b5
@ -37,6 +37,7 @@ class ResolveParameterPlaceHoldersPass implements CompilerPassInterface
|
||||
$definition->setClass($parameterBag->resolveValue($definition->getClass()));
|
||||
$definition->setFile($parameterBag->resolveValue($definition->getFile()));
|
||||
$definition->setArguments($parameterBag->resolveValue($definition->getArguments()));
|
||||
$definition->setFactoryClass($parameterBag->resolveValue($definition->getFactoryClass()));
|
||||
|
||||
$calls = array();
|
||||
foreach ($definition->getMethodCalls() as $name => $arguments) {
|
||||
|
@ -1223,7 +1223,9 @@ EOF;
|
||||
if (null !== $value->getFactoryClass()) {
|
||||
return sprintf("call_user_func(array(%s, '%s')%s)", $this->dumpValue($value->getFactoryClass()), $value->getFactoryMethod(), count($arguments) > 0 ? ', '.implode(', ', $arguments) : '');
|
||||
} elseif (null !== $value->getFactoryService()) {
|
||||
return sprintf("%s->%s(%s)", $this->getServiceCall($value->getFactoryService()), $value->getFactoryMethod(), implode(', ', $arguments));
|
||||
$service = $this->dumpValue($definition->getFactoryService());
|
||||
|
||||
return sprintf("%s->%s(%s)", 0 === strpos($service, '$') ? sprintf('$this->get(%s)', $service) : $this->getServiceCall($value->getFactoryService()), $value->getFactoryMethod(), implode(', ', $arguments));
|
||||
} else {
|
||||
throw new RuntimeException('Cannot dump definitions which have factory method without factory service or factory class.');
|
||||
}
|
||||
|
@ -322,8 +322,14 @@ class ContainerBuilderTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
$builder = new ContainerBuilder();
|
||||
$builder->register('bar', 'stdClass');
|
||||
$builder->register('foo1', 'FooClass')->setFactoryClass('FooClass')->setFactoryMethod('getInstance')->addArgument(array('foo' => '%value%', '%value%' => 'foo', new Reference('bar')));
|
||||
$builder
|
||||
->register('foo1', 'FooClass')
|
||||
->setFactoryClass('%foo_class%')
|
||||
->setFactoryMethod('getInstance')
|
||||
->addArgument(array('foo' => '%value%', '%value%' => 'foo', new Reference('bar')))
|
||||
;
|
||||
$builder->setParameter('value', 'bar');
|
||||
$builder->setParameter('foo_class', 'FooClass');
|
||||
$this->assertTrue($builder->get('foo1')->called, '->createService() calls the factory method to create the service instance');
|
||||
$this->assertEquals(array('foo' => 'bar', 'bar' => 'foo', $builder->get('bar')), $builder->get('foo1')->arguments, '->createService() passes the arguments to the factory method');
|
||||
}
|
||||
@ -334,10 +340,14 @@ class ContainerBuilderTest extends \PHPUnit_Framework_TestCase
|
||||
public function testCreateServiceFactoryService()
|
||||
{
|
||||
$builder = new ContainerBuilder();
|
||||
$builder->register('baz_service')->setFactoryService('baz_factory')->setFactoryMethod('getInstance');
|
||||
$builder->register('baz_factory', 'BazClass');
|
||||
|
||||
$this->assertInstanceOf('BazClass', $builder->get('baz_service'));
|
||||
$builder->register('foo_service', 'FooClass');
|
||||
$builder
|
||||
->register('foo', 'FooClass')
|
||||
->setFactoryService('%foo_service%')
|
||||
->setFactoryMethod('getInstance')
|
||||
;
|
||||
$builder->setParameter('foo_service', 'foo_service');
|
||||
$this->assertTrue($builder->get('foo')->called, '->createService() calls the factory method to create the service instance');
|
||||
}
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user