[DI] Initialize properties before method calls

This commit is contained in:
Roland Franssen 2016-11-19 11:21:18 +00:00 committed by Nicolas Grekas
parent 30d161c0ae
commit 0af433b01f
7 changed files with 63 additions and 13 deletions

View File

@ -902,15 +902,15 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
$this->shareService($definition, $service, $id);
}
foreach ($definition->getMethodCalls() as $call) {
$this->callMethod($service, $call);
}
$properties = $this->resolveServices($parameterBag->unescapeValue($parameterBag->resolveValue($definition->getProperties())));
foreach ($properties as $name => $value) {
$service->$name = $value;
}
foreach ($definition->getMethodCalls() as $call) {
$this->callMethod($service, $call);
}
if ($callable = $definition->getConfigurator()) {
if (is_array($callable)) {
$callable[0] = $parameterBag->resolveValue($callable[0]);

View File

@ -335,8 +335,8 @@ class PhpDumper extends Dumper
$code .= $this->addNewInstance($id, $sDefinition, '$'.$name, ' = ');
if (!$this->hasReference($id, $sDefinition->getMethodCalls(), true) && !$this->hasReference($id, $sDefinition->getProperties(), true)) {
$code .= $this->addServiceMethodCalls(null, $sDefinition, $name);
$code .= $this->addServiceProperties(null, $sDefinition, $name);
$code .= $this->addServiceMethodCalls(null, $sDefinition, $name);
$code .= $this->addServiceConfigurator(null, $sDefinition, $name);
}
@ -507,8 +507,8 @@ class PhpDumper extends Dumper
}
$name = (string) $this->definitionVariables->offsetGet($iDefinition);
$code .= $this->addServiceMethodCalls(null, $iDefinition, $name);
$code .= $this->addServiceProperties(null, $iDefinition, $name);
$code .= $this->addServiceMethodCalls(null, $iDefinition, $name);
$code .= $this->addServiceConfigurator(null, $iDefinition, $name);
}
@ -663,8 +663,8 @@ EOF;
$this->addServiceInlinedDefinitions($id, $definition).
$this->addServiceInstance($id, $definition).
$this->addServiceInlinedDefinitionsSetup($id, $definition).
$this->addServiceMethodCalls($id, $definition).
$this->addServiceProperties($id, $definition).
$this->addServiceMethodCalls($id, $definition).
$this->addServiceConfigurator($id, $definition).
$this->addServiceReturn($id, $definition)
;

View File

@ -798,6 +798,20 @@ class ContainerBuilderTest extends \PHPUnit_Framework_TestCase
$this->assertTrue($classInList);
}
public function testInitializePropertiesBeforeMethodCalls()
{
$container = new ContainerBuilder();
$container->register('foo', 'stdClass');
$container->register('bar', 'MethodCallClass')
->setProperty('simple', 'bar')
->setProperty('complex', new Reference('foo'))
->addMethodCall('callMe');
$container->compile();
$this->assertTrue($container->get('bar')->callPassed(), '->compile() initializes properties before method calls');
}
}
class FooClass

View File

@ -267,4 +267,23 @@ class PhpDumperTest extends \PHPUnit_Framework_TestCase
$dumper = new PhpDumper($container);
$this->assertStringEqualsFile(self::$fixturesPath.'/php/services13.php', $dumper->dump(), '->dump() dumps inline definitions which reference service_container');
}
public function testInitializePropertiesBeforeMethodCalls()
{
require_once self::$fixturesPath.'/includes/classes.php';
$container = new ContainerBuilder();
$container->register('foo', 'stdClass');
$container->register('bar', 'MethodCallClass')
->setProperty('simple', 'bar')
->setProperty('complex', new Reference('foo'))
->addMethodCall('callMe');
$container->compile();
$dumper = new PhpDumper($container);
eval('?>'.$dumper->dump(array('class' => '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');
}
}

View File

@ -59,3 +59,20 @@ class BarUserClass
$this->bar = $bar;
}
}
class MethodCallClass
{
public $simple;
public $complex;
private $callPassed = false;
public function callMe()
{
$this->callPassed = is_scalar($this->simple) && is_object($this->complex);
}
public function callPassed()
{
return $this->callPassed;
}
}

View File

@ -170,11 +170,11 @@ class ProjectServiceContainer extends Container
$this->services['foo'] = $instance = \Bar\FooClass::getInstance('foo', $a, array($this->getParameter('foo') => 'foo is '.$this->getParameter('foo').'', 'foobar' => $this->getParameter('foo')), true, $this);
$instance->setBar($this->get('bar'));
$instance->initialize();
$instance->foo = 'bar';
$instance->moo = $a;
$instance->qux = array($this->getParameter('foo') => 'foo is '.$this->getParameter('foo').'', 'foobar' => $this->getParameter('foo'));
$instance->setBar($this->get('bar'));
$instance->initialize();
sc_configure($instance);
return $instance;
@ -333,8 +333,8 @@ class ProjectServiceContainer extends Container
{
$this->services['inlined'] = $instance = new \Bar();
$instance->setBaz($this->get('baz'));
$instance->pub = 'pub';
$instance->setBaz($this->get('baz'));
return $instance;
}

View File

@ -179,11 +179,11 @@ class ProjectServiceContainer extends Container
$this->services['foo'] = $instance = \Bar\FooClass::getInstance('foo', $a, array('bar' => 'foo is bar', 'foobar' => 'bar'), true, $this);
$instance->setBar($this->get('bar'));
$instance->initialize();
$instance->foo = 'bar';
$instance->moo = $a;
$instance->qux = array('bar' => 'foo is bar', 'foobar' => 'bar');
$instance->setBar($this->get('bar'));
$instance->initialize();
sc_configure($instance);
return $instance;
@ -230,8 +230,8 @@ class ProjectServiceContainer extends Container
$this->services['foo_with_inline'] = $instance = new \Foo();
$a->setBaz($this->get('baz'));
$a->pub = 'pub';
$a->setBaz($this->get('baz'));
$instance->setBar($a);