[DependencyInjection] PhpDumper.php: hasReference() should not search references in lazy service arguments.
This commit is contained in:
parent
777cdfc0f6
commit
595a9781e2
|
@ -60,15 +60,20 @@ class CheckCircularReferencesPass implements CompilerPassInterface
|
|||
$id = $node->getId();
|
||||
|
||||
if (empty($this->checkedNodes[$id])) {
|
||||
$searchKey = array_search($id, $this->currentPath);
|
||||
$this->currentPath[] = $id;
|
||||
|
||||
if (false !== $searchKey) {
|
||||
throw new ServiceCircularReferenceException($id, array_slice($this->currentPath, $searchKey));
|
||||
// * don't check circular dependencies in lazy services.
|
||||
$isLazy = $node->getValue() && $node->getValue()->isLazy();
|
||||
if (!$isLazy) {
|
||||
$searchKey = array_search($id, $this->currentPath);
|
||||
$this->currentPath[] = $id;
|
||||
|
||||
if (false !== $searchKey) {
|
||||
throw new ServiceCircularReferenceException($id, array_slice($this->currentPath, $searchKey));
|
||||
}
|
||||
|
||||
$this->checkOutEdges($node->getOutEdges());
|
||||
}
|
||||
|
||||
$this->checkOutEdges($node->getOutEdges());
|
||||
|
||||
$this->checkedNodes[$id] = true;
|
||||
array_pop($this->currentPath);
|
||||
}
|
||||
|
|
|
@ -1293,6 +1293,13 @@ EOF;
|
|||
$visited[$argumentId] = true;
|
||||
|
||||
$service = $this->container->getDefinition($argumentId);
|
||||
|
||||
// if exists proxy dumper (proxy-manager) don't search references in lazy services.
|
||||
// As these services will be instantiated lazily and don't have direct related references.
|
||||
if ($service->isLazy() && !($this->getProxyDumper() instanceof NullDumper)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$arguments = array_merge($service->getMethodCalls(), $service->getArguments(), $service->getProperties());
|
||||
|
||||
if ($this->hasReference($id, $arguments, $deep, $visited)) {
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
namespace Symfony\Component\DependencyInjection\Tests\Dumper;
|
||||
|
||||
use DummyProxyDumper;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Dumper\PhpDumper;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
|
||||
|
@ -19,6 +20,8 @@ use Symfony\Component\DependencyInjection\Definition;
|
|||
use Symfony\Component\DependencyInjection\Variable;
|
||||
use Symfony\Component\ExpressionLanguage\Expression;
|
||||
|
||||
require_once __DIR__.'/../Fixtures/includes/classes.php';
|
||||
|
||||
class PhpDumperTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected static $fixturesPath;
|
||||
|
@ -286,4 +289,52 @@ class PhpDumperTest extends \PHPUnit_Framework_TestCase
|
|||
$container = new \Symfony_DI_PhpDumper_Test_Properties_Before_Method_Calls();
|
||||
$this->assertTrue($container->get('bar')->callPassed(), '->dump() initializes properties before method calls');
|
||||
}
|
||||
|
||||
public function testCircularReferenceAllowanceForLazyServices()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
$container->register('foo', 'stdClass')->addArgument(new Reference('bar'));
|
||||
$container->register('bar', 'stdClass')->setLazy(true)->addArgument(new Reference('foo'));
|
||||
$container->compile();
|
||||
|
||||
$dumper = new PhpDumper($container);
|
||||
$dumper->dump();
|
||||
}
|
||||
|
||||
public function testCircularReferenceAllowanceForInlinedDefinitionsForLazyServices()
|
||||
{
|
||||
/*
|
||||
* test graph:
|
||||
* [connection] -> [event_manager] --> [entity_manager](lazy)
|
||||
* |
|
||||
* --(call)- addEventListener ("@lazy_service")
|
||||
*
|
||||
* [lazy_service](lazy) -> [entity_manager](lazy)
|
||||
*
|
||||
*/
|
||||
|
||||
$container = new ContainerBuilder();
|
||||
|
||||
$eventManagerDefinition = new Definition('stdClass');
|
||||
|
||||
$connectionDefinition = $container->register('connection', 'stdClass');
|
||||
$connectionDefinition->addArgument($eventManagerDefinition);
|
||||
|
||||
$container->register('entity_manager', 'stdClass')
|
||||
->setLazy(true)
|
||||
->addArgument(new Reference('connection'));
|
||||
|
||||
$lazyServiceDefinition = $container->register('lazy_service', 'stdClass');
|
||||
$lazyServiceDefinition->setLazy(true);
|
||||
$lazyServiceDefinition->addArgument(new Reference('entity_manager'));
|
||||
|
||||
$eventManagerDefinition->addMethodCall('addEventListener', array(new Reference('lazy_service')));
|
||||
|
||||
$container->compile();
|
||||
|
||||
$dumper = new PhpDumper($container);
|
||||
|
||||
$dumper->setProxyDumper(new DummyProxyDumper());
|
||||
$dumper->dump();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
<?php
|
||||
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\DumperInterface as ProxyDumper;
|
||||
|
||||
function sc_configure($instance)
|
||||
{
|
||||
$instance->configure();
|
||||
|
@ -76,3 +79,30 @@ class MethodCallClass
|
|||
return $this->callPassed;
|
||||
}
|
||||
}
|
||||
|
||||
class DummyProxyDumper implements ProxyDumper
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isProxyCandidate(Definition $definition)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getProxyFactoryCode(Definition $definition, $id)
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getProxyCode(Definition $definition)
|
||||
{
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
|
Reference in New Issue