public function __invoke($spec)
{
if (is_callable($spec)) {
if (is_array($spec)) {
list($class, $method) = $spec;
$class = new ReflectionClass($class);
$object = $class->newInstance();
$mirror = $class->getMethod($method);
} else {
$object = false;
$mirror = new ReflectionFunction($spec);
}
$container = $this;
$arguments = array_map(function ($param) use($container) {
if ($paramClass = $param->getClass()) {
$paramClassName = $paramClass->getName();
return $container->getItem($paramClassName);
}
}, $mirror->getParameters());
if ($object) {
return $mirror->invokeArgs($object, $arguments);
}
return $mirror->invokeArgs($arguments);
}
if ((bool) array_filter(func_get_args(), 'is_object')) {
foreach (func_get_args() as $dependency) {
$this[get_class($dependency)] = $dependency;
}
}
foreach ($spec as $name => $item) {
parent::offsetSet($name, $item);
}
if ($this->configurator) {
$this->configure();
}
return $this;
}