joomla-framework
joomla-framework copied to clipboard
[DI] Use alias will create shared object twice
If we use buildSharedObject() to build an object named \Foo\Bar , the instance will be:
instance => Array
(
[\Foo\Bar] => Object()
)
But if we add alias foo.bar to this key, when we get by alias $container->get('foo.bar');, container will create two object and store it in instance:
instance => Array
(
[\Foo\Bar] => Object()
[foo.bar] => Object()
)
It because the buildObject use this closure, it will create new instance everytime called:
$callback = function () use ($reflection, $newInstanceArgs) {
return $reflection->newInstanceArgs($newInstanceArgs);
};
I'm not sure what is the good way to fix it, so I just report this issue.
See Container::get(): https://github.com/joomla/joomla-framework/blob/staging/src/Joomla/DI/Container.php#L337
public function get($key, $forceNew = false)
{
// Here we use alias to find raw data
$raw = $this->getRaw($key);
// ignore...
if ($raw['shared'])
{
// This key is 'foo.bar', but instance key is \Foo\Bar
if (!isset($this->instances[$key]) || $forceNew)
{
$this->instances[$key] = $raw['callback']($this);
}
return $this->instances[$key];
}
return call_user_func($raw['callback'], $this);
}
Same problem when child get instance from parent.
Just a sample to fix this:
public function get($key, $forceNew = false)
{
$raw = $this->getRaw($key);
$key = $this->resolveAlias($key);
if (is_null($raw))
{
throw new \InvalidArgumentException(sprintf('Key %s has not been registered with the container.', $key));
}
if ($raw['shared'])
{
if (!isset($this->instances[$key]) || $forceNew)
{
$this->instances[$key] = $raw['callback']($this);
}
return $this->instances[$key];
}
return call_user_func($raw['callback'], $this);
}