[DependencyInjection] Fix aliased access of shared services, fixes #8096

This commit is contained in:
Jordi Boggiano 2013-06-04 14:28:00 +02:00
parent 8d2cda3395
commit 379f5e08b4
4 changed files with 72 additions and 14 deletions

View File

@ -69,6 +69,7 @@ class Container implements IntrospectableContainerInterface
protected $services;
protected $methodMap;
protected $aliases;
protected $scopes;
protected $scopeChildren;
protected $scopedServices;
@ -253,6 +254,12 @@ class Container implements IntrospectableContainerInterface
{
$id = strtolower($id);
// resolve aliases
if (isset($this->aliases[$id])) {
$id = $this->aliases[$id];
}
// re-use shared service instance if it exists
if (array_key_exists($id, $this->services)) {
return $this->services[$id];
}
@ -264,6 +271,7 @@ class Container implements IntrospectableContainerInterface
if (isset($this->methodMap[$id])) {
$method = $this->methodMap[$id];
} elseif (method_exists($this, $method = 'get'.strtr($id, array('_' => '', '.' => '_')).'Service')) {
// $method is set to the right value, proceed
} else {
if (self::EXCEPTION_ON_INVALID_REFERENCE === $invalidBehavior) {
if (!$id) {

View File

@ -799,6 +799,9 @@ EOF;
$code .= " \$this->scopeChildren = ".$this->dumpValue($this->container->getScopeChildren()).";\n";
}
$code .= $this->addMethodMap();
$code .= $this->addAliases();
$code .= <<<EOF
}
@ -846,19 +849,8 @@ EOF;
$code .= " \$this->scopeChildren = array();\n";
}
// build method map
$code .= " \$this->methodMap = array(\n";
$definitions = $this->container->getDefinitions();
ksort($definitions);
foreach ($definitions as $id => $definition) {
$code .= ' '.var_export($id, true).' => '.var_export('get'.Container::camelize($id).'Service', true).",\n";
}
$aliases = $this->container->getAliases();
ksort($aliases);
foreach ($aliases as $alias => $id) {
$code .= ' '.var_export($alias, true).' => '.var_export('get'.Container::camelize($id).'Service', true).",\n";
}
$code .= " );\n";
$code .= $this->addMethodMap();
$code .= $this->addAliases();
$code .= <<<EOF
}
@ -868,6 +860,46 @@ EOF;
return $code;
}
/**
* Adds the methodMap property definition
*
* @return string
*/
private function addMethodMap()
{
if (!$definitions = $this->container->getDefinitions()) {
return '';
}
$code = " \$this->methodMap = array(\n";
ksort($definitions);
foreach ($definitions as $id => $definition) {
$code .= ' '.var_export($id, true).' => '.var_export('get'.Container::camelize($id).'Service', true).",\n";
}
return $code . " );\n";
}
/**
* Adds the aliases property definition
*
* @return string
*/
private function addAliases()
{
if (!$aliases = $this->container->getAliases()) {
return '';
}
$code = " \$this->aliases = array(\n";
ksort($aliases);
foreach ($aliases as $alias => $id) {
$code .= ' '.var_export($alias, true).' => '.var_export((string) $id, true).",\n";
}
return $code . " );\n";
}
/**
* Adds default parameters method.
*

View File

@ -24,6 +24,22 @@ class ProjectServiceContainer extends Container
public function __construct()
{
parent::__construct(new ParameterBag($this->getDefaultParameters()));
$this->methodMap = array(
'bar' => 'getBarService',
'baz' => 'getBazService',
'depends_on_request' => 'getDependsOnRequestService',
'factory_service' => 'getFactoryServiceService',
'foo' => 'getFooService',
'foo.baz' => 'getFoo_BazService',
'foo_bar' => 'getFooBarService',
'foo_with_inline' => 'getFooWithInlineService',
'inlined' => 'getInlinedService',
'method_call1' => 'getMethodCall1Service',
'request' => 'getRequestService',
);
$this->aliases = array(
'alias_for_foo' => 'foo',
);
}
/**

View File

@ -44,7 +44,9 @@ class ProjectServiceContainer extends Container
'foo_with_inline' => 'getFooWithInlineService',
'method_call1' => 'getMethodCall1Service',
'request' => 'getRequestService',
'alias_for_foo' => 'getFooService',
);
$this->aliases = array(
'alias_for_foo' => 'foo',
);
}