[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();
|
$id = $node->getId();
|
||||||
|
|
||||||
if (empty($this->checkedNodes[$id])) {
|
if (empty($this->checkedNodes[$id])) {
|
||||||
$searchKey = array_search($id, $this->currentPath);
|
|
||||||
$this->currentPath[] = $id;
|
|
||||||
|
|
||||||
if (false !== $searchKey) {
|
// * don't check circular dependencies in lazy services.
|
||||||
throw new ServiceCircularReferenceException($id, array_slice($this->currentPath, $searchKey));
|
$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;
|
$this->checkedNodes[$id] = true;
|
||||||
array_pop($this->currentPath);
|
array_pop($this->currentPath);
|
||||||
}
|
}
|
||||||
|
@ -1293,6 +1293,13 @@ EOF;
|
|||||||
$visited[$argumentId] = true;
|
$visited[$argumentId] = true;
|
||||||
|
|
||||||
$service = $this->container->getDefinition($argumentId);
|
$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());
|
$arguments = array_merge($service->getMethodCalls(), $service->getArguments(), $service->getProperties());
|
||||||
|
|
||||||
if ($this->hasReference($id, $arguments, $deep, $visited)) {
|
if ($this->hasReference($id, $arguments, $deep, $visited)) {
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\DependencyInjection\Tests\Dumper;
|
namespace Symfony\Component\DependencyInjection\Tests\Dumper;
|
||||||
|
|
||||||
|
use DummyProxyDumper;
|
||||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||||
use Symfony\Component\DependencyInjection\Dumper\PhpDumper;
|
use Symfony\Component\DependencyInjection\Dumper\PhpDumper;
|
||||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
|
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
|
||||||
@ -19,6 +20,8 @@ use Symfony\Component\DependencyInjection\Definition;
|
|||||||
use Symfony\Component\DependencyInjection\Variable;
|
use Symfony\Component\DependencyInjection\Variable;
|
||||||
use Symfony\Component\ExpressionLanguage\Expression;
|
use Symfony\Component\ExpressionLanguage\Expression;
|
||||||
|
|
||||||
|
require_once __DIR__.'/../Fixtures/includes/classes.php';
|
||||||
|
|
||||||
class PhpDumperTest extends \PHPUnit_Framework_TestCase
|
class PhpDumperTest extends \PHPUnit_Framework_TestCase
|
||||||
{
|
{
|
||||||
protected static $fixturesPath;
|
protected static $fixturesPath;
|
||||||
@ -286,4 +289,52 @@ class PhpDumperTest extends \PHPUnit_Framework_TestCase
|
|||||||
$container = new \Symfony_DI_PhpDumper_Test_Properties_Before_Method_Calls();
|
$container = new \Symfony_DI_PhpDumper_Test_Properties_Before_Method_Calls();
|
||||||
$this->assertTrue($container->get('bar')->callPassed(), '->dump() initializes 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
|
<?php
|
||||||
|
|
||||||
|
use Symfony\Component\DependencyInjection\Definition;
|
||||||
|
use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\DumperInterface as ProxyDumper;
|
||||||
|
|
||||||
function sc_configure($instance)
|
function sc_configure($instance)
|
||||||
{
|
{
|
||||||
$instance->configure();
|
$instance->configure();
|
||||||
@ -76,3 +79,30 @@ class MethodCallClass
|
|||||||
return $this->callPassed;
|
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
Block a user