bug #11639 [DependencyInjection] Fixed factory service not within the ServiceReferenceGraph. (boekkooi)

This PR was submitted for the master branch but it was merged into the 2.3 branch instead (closes #11639).

Discussion
----------

[DependencyInjection] Fixed factory service not within the ServiceReferenceGraph.

| Q             | A
| ------------- | ---
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets |
| License       | MIT
| Doc PR        |

Fixed a problem where Factory services are not added to the ServiceReferenceGraph.

Commits
-------

e992f8e Fixed Factory services not within the ServiceReferenceGraph.
This commit is contained in:
Fabien Potencier 2014-08-27 10:32:18 +02:00
commit c59f1dde6b
4 changed files with 90 additions and 0 deletions

View File

@ -69,7 +69,11 @@ class AnalyzeServiceReferencesPass implements RepeatablePassInterface
$this->currentId = $id;
$this->currentDefinition = $definition;
$this->processArguments($definition->getArguments());
if ($definition->getFactoryService()) {
$this->processArguments(array(new Reference($definition->getFactoryService())));
}
if (!$this->onlyConstructorArguments) {
$this->processArguments($definition->getMethodCalls());

View File

@ -97,6 +97,26 @@ class AnalyzeServiceReferencesPassTest extends \PHPUnit_Framework_TestCase
$this->assertCount(2, $graph->getNode('a')->getInEdges());
}
public function testProcessDetectsFactoryReferences()
{
$container = new ContainerBuilder();
$container
->register('foo', 'stdClass')
->setFactoryClass('stdClass')
->setFactoryMethod('getInstance');
$container
->register('bar', 'stdClass')
->setFactoryService('foo')
->setFactoryMethod('getInstance');
$graph = $this->process($container);
$this->assertTrue($graph->hasNode('foo'));
$this->assertCount(1, $graph->getNode('foo')->getInEdges());
}
protected function process(ContainerBuilder $container)
{
$pass = new RepeatedPass(array(new AnalyzeServiceReferencesPass()));

View File

@ -48,6 +48,26 @@ class CheckCircularReferencesPassTest extends \PHPUnit_Framework_TestCase
$this->process($container);
}
/**
* @expectedException \Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException
*/
public function testProcessWithFactory()
{
$container = new ContainerBuilder();
$container
->register('a', 'stdClass')
->setFactoryService('b')
->setFactoryMethod('getInstance');
$container
->register('b', 'stdClass')
->setFactoryService('a')
->setFactoryMethod('getInstance');
$this->process($container);
}
/**
* @expectedException \Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException
*/
@ -61,6 +81,25 @@ class CheckCircularReferencesPassTest extends \PHPUnit_Framework_TestCase
$this->process($container);
}
/**
* @expectedException \Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException
*/
public function testProcessDetectsIndirectCircularReferenceWithFactory()
{
$container = new ContainerBuilder();
$container->register('a')->addArgument(new Reference('b'));
$container
->register('b', 'stdClass')
->setFactoryService('c')
->setFactoryMethod('getInstance');
$container->register('c')->addArgument(new Reference('a'));
$this->process($container);
}
/**
* @expectedException \Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException
*/

View File

@ -81,6 +81,33 @@ class RemoveUnusedDefinitionsPassTest extends \PHPUnit_Framework_TestCase
$this->assertTrue($container->hasDefinition('bar'));
}
public function testProcessWontRemovePrivateFactory()
{
$container = new ContainerBuilder();
$container
->register('foo', 'stdClass')
->setFactoryClass('stdClass')
->setFactoryMethod('getInstance')
->setPublic(false);
$container
->register('bar', 'stdClass')
->setFactoryService('foo')
->setFactoryMethod('getInstance')
->setPublic(false);
$container
->register('foobar')
->addArgument(new Reference('bar'));
$this->process($container);
$this->assertTrue($container->hasDefinition('foo'));
$this->assertTrue($container->hasDefinition('bar'));
$this->assertTrue($container->hasDefinition('foobar'));
}
protected function process(ContainerBuilder $container)
{
$repeatedPass = new RepeatedPass(array(new AnalyzeServiceReferencesPass(), new RemoveUnusedDefinitionsPass()));