[DependencyInjection] store references to shared services as soon as possible to avoid circular references on legal code

This commit is contained in:
Fabien Potencier 2010-03-01 18:37:22 +01:00
parent 6ba662b0a4
commit 17d4e1538f
3 changed files with 30 additions and 35 deletions

View File

@ -97,14 +97,7 @@ class Builder extends Container implements AnnotatedContainerInterface
$this->loading[$id] = true;
if ($definition->isShared())
{
$service = $this->services[$id] = $this->createService($definition);
}
else
{
$service = $this->createService($definition);
}
$service = $this->createService($definition, $id);
unset($this->loading[$id]);
@ -339,10 +332,11 @@ class Builder extends Container implements AnnotatedContainerInterface
* Creates a service for a service definition.
*
* @param Definition $definition A service definition instance
* @param string $id The service identifier
*
* @return object The service described by the service definition
*/
protected function createService(Definition $definition)
protected function createService(Definition $definition, $id)
{
if (null !== $definition->getFile())
{
@ -362,6 +356,11 @@ class Builder extends Container implements AnnotatedContainerInterface
$service = null === $r->getConstructor() ? $r->newInstance() : $r->newInstanceArgs($arguments);
}
if ($definition->isShared())
{
$this->services[$id] = $service;
}
foreach ($definition->getMethodCalls() as $call)
{
$services = self::getServiceConditionals($call[1]);

View File

@ -76,24 +76,12 @@ EOF;
protected function addServiceReturn($id, $definition)
{
if ($definition->isShared())
{
return <<<EOF
return \$this->shared['$id'] = \$instance;
}
EOF;
}
else
{
return <<<EOF
return <<<EOF
return \$instance;
}
EOF;
}
}
protected function addServiceInstance($id, $definition)
@ -108,19 +96,23 @@ EOF;
if (null !== $definition->getConstructor())
{
return sprintf(" \$instance = call_user_func(array(%s, '%s')%s);\n", $class, $definition->getConstructor(), $arguments ? ', '.implode(', ', $arguments) : '');
$code = sprintf(" \$instance = call_user_func(array(%s, '%s')%s);\n", $class, $definition->getConstructor(), $arguments ? ', '.implode(', ', $arguments) : '');
}
elseif ($class != "'".str_replace('\\', '\\\\', $definition->getClass())."'")
{
$code = sprintf(" \$class = %s;\n \$instance = new \$class(%s);\n", $class, implode(', ', $arguments));
}
else
{
if ($class != "'".str_replace('\\', '\\\\', $definition->getClass())."'")
{
return sprintf(" \$class = %s;\n \$instance = new \$class(%s);\n", $class, implode(', ', $arguments));
}
else
{
return sprintf(" \$instance = new %s(%s);\n", $definition->getClass(), implode(', ', $arguments));
}
$code = sprintf(" \$instance = new %s(%s);\n", $definition->getClass(), implode(', ', $arguments));
}
if ($definition->isShared())
{
$code .= sprintf(" \$this->shared['$id'] = \$instance;\n");
}
return $code;
}
protected function addServiceMethodCalls($id, $definition)

View File

@ -61,9 +61,10 @@ class ProjectServiceContainer extends Container
if (isset($this->shared['bar'])) return $this->shared['bar'];
$instance = new FooClass('foo', $this->getFoo_BazService(), $this->getParameter('foo_bar'));
$this->shared['bar'] = $instance;
$this->getFoo_BazService()->configure($instance);
return $this->shared['bar'] = $instance;
return $instance;
}
/**
@ -79,9 +80,10 @@ class ProjectServiceContainer extends Container
if (isset($this->shared['foo.baz'])) return $this->shared['foo.baz'];
$instance = call_user_func(array($this->getParameter('baz_class'), 'getInstance'));
$this->shared['foo.baz'] = $instance;
call_user_func(array($this->getParameter('baz_class'), 'configureStatic1'), $instance);
return $this->shared['foo.baz'] = $instance;
return $instance;
}
/**
@ -98,8 +100,9 @@ class ProjectServiceContainer extends Container
$class = $this->getParameter('foo_class');
$instance = new $class();
$this->shared['foo_bar'] = $instance;
return $this->shared['foo_bar'] = $instance;
return $instance;
}
/**
@ -115,6 +118,7 @@ class ProjectServiceContainer extends Container
if (isset($this->shared['method_call1'])) return $this->shared['method_call1'];
$instance = new FooClass();
$this->shared['method_call1'] = $instance;
$instance->setBar($this->getFooService());
$instance->setBar($this->getService('foo', Container::NULL_ON_INVALID_REFERENCE));
if ($this->hasService('foo'))
@ -126,7 +130,7 @@ class ProjectServiceContainer extends Container
$instance->setBar($this->getService('foobaz', Container::NULL_ON_INVALID_REFERENCE));
}
return $this->shared['method_call1'] = $instance;
return $instance;
}
/**