Skip to content

Commit

Permalink
Backport enhancements in buildObject from 2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
mbabker committed Feb 25, 2018
1 parent ac65b02 commit 33c66e4
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 4 deletions.
27 changes: 27 additions & 0 deletions Tests/ContainerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,33 @@ public function testBuildObjectNonClass()
);
}

/**
* Tests attempting to build a class with a circular dependency
*
* @return void
*
* @since 1.0
* @expectedException \Joomla\DI\Exception\DependencyResolutionException
*/
public function testBug4()
{
$fqcn = 'Extension\\vendor\\FooComponent\\FooComponent';
$data = array();

$this->fixture->set(
$fqcn,
function (Container $c) use ($fqcn, $data)
{
$instance = $c->buildObject($fqcn);
$instance->setData($data);

return $instance;
}
);

$this->fixture->get($fqcn);
}

/**
* Tests the buildSharedObject.
*
Expand Down
43 changes: 39 additions & 4 deletions src/Container.php
Original file line number Diff line number Diff line change
Expand Up @@ -181,22 +181,52 @@ public function getTagged($tag)
*/
public function buildObject($key, $shared = false)
{
static $buildStack = array();

$resolvedKey = $this->resolveAlias($key);

if (in_array($resolvedKey, $buildStack, true))
{
$buildStack = array();

throw new DependencyResolutionException("Can't resolve circular dependency");
}

$buildStack[] = $resolvedKey;

if ($this->has($resolvedKey))
{
$resource = $this->get($resolvedKey);
array_pop($buildStack);

return $resource;
}

try
{
$reflection = new \ReflectionClass($key);
$reflection = new \ReflectionClass($resolvedKey);
}
catch (\ReflectionException $e)
{
array_pop($buildStack);

return false;
}

if (!$reflection->isInstantiable())
{
$buildStack = array();

throw new DependencyResolutionException("$resolvedKey can not be instantiated.");
}

$constructor = $reflection->getConstructor();

// If there are no parameters, just return a new object.
if ($constructor === null)
{
$callback = function () use ($key) {
return new $key;
$callback = function () use ($resolvedKey) {
return new $resolvedKey;
};
}
else
Expand All @@ -209,7 +239,12 @@ public function buildObject($key, $shared = false)
};
}

return $this->set($key, $callback, $shared)->get($key);
$this->set($resolvedKey, $callback, $shared);

$resource = $this->get($resolvedKey);
array_pop($buildStack);

return $resource;
}

/**
Expand Down

0 comments on commit 33c66e4

Please sign in to comment.