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

View File

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

View File

@ -61,9 +61,10 @@ class ProjectServiceContainer extends Container
if (isset($this->shared['bar'])) return $this->shared['bar']; if (isset($this->shared['bar'])) return $this->shared['bar'];
$instance = new FooClass('foo', $this->getFoo_BazService(), $this->getParameter('foo_bar')); $instance = new FooClass('foo', $this->getFoo_BazService(), $this->getParameter('foo_bar'));
$this->shared['bar'] = $instance;
$this->getFoo_BazService()->configure($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']; if (isset($this->shared['foo.baz'])) return $this->shared['foo.baz'];
$instance = call_user_func(array($this->getParameter('baz_class'), 'getInstance')); $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); 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'); $class = $this->getParameter('foo_class');
$instance = new $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']; if (isset($this->shared['method_call1'])) return $this->shared['method_call1'];
$instance = new FooClass(); $instance = new FooClass();
$this->shared['method_call1'] = $instance;
$instance->setBar($this->getFooService()); $instance->setBar($this->getFooService());
$instance->setBar($this->getService('foo', Container::NULL_ON_INVALID_REFERENCE)); $instance->setBar($this->getService('foo', Container::NULL_ON_INVALID_REFERENCE));
if ($this->hasService('foo')) if ($this->hasService('foo'))
@ -126,7 +130,7 @@ class ProjectServiceContainer extends Container
$instance->setBar($this->getService('foobaz', Container::NULL_ON_INVALID_REFERENCE)); $instance->setBar($this->getService('foobaz', Container::NULL_ON_INVALID_REFERENCE));
} }
return $this->shared['method_call1'] = $instance; return $instance;
} }
/** /**