Skip to content

Commit

Permalink
Container: dynamic factories as stored in $factories
Browse files Browse the repository at this point in the history
  • Loading branch information
dg committed Apr 28, 2024
1 parent 1fa0bc4 commit ed53906
Showing 1 changed file with 14 additions and 9 deletions.
23 changes: 14 additions & 9 deletions src/DI/Container.php
Expand Up @@ -41,9 +41,12 @@ class Container
/** @var array<string, true> circular reference detector */
private array $creating;

/** @var array<string, int|\Closure> */
/** @var array<string, int> */
private array $methods;

/** @var array<string, \Closure> service name => \Closure */
private array $factories = [];


public function __construct(array $params = [])
{
Expand Down Expand Up @@ -110,7 +113,7 @@ public function addService(string $name, object $service): static
}

if ($service instanceof \Closure) {
$this->methods[self::getMethodName($name)] = $service;
$this->factories[$name] = $service;
$this->types[$name] = $type;
} else {
$this->instances[$name] = $service;
Expand Down Expand Up @@ -175,6 +178,9 @@ public function getServiceType(string $name): string
} elseif (isset($this->methods[$method])) {
return (string) (new \ReflectionMethod($this, $method))->getReturnType();

} elseif ($cb = $this->factories[$name] ?? null) {
return (string) (new \ReflectionFunction($cb))->getReturnType();

} else {
throw new MissingServiceException(sprintf("Service '%s' not found.", $name));
}
Expand All @@ -187,7 +193,7 @@ public function getServiceType(string $name): string
public function hasService(string $name): bool
{
$name = $this->aliases[$name] ?? $name;
return isset($this->methods[self::getMethodName($name)]) || isset($this->instances[$name]);
return isset($this->methods[self::getMethodName($name)]) || isset($this->instances[$name]) || isset($this->factories[$name]);
}


Expand All @@ -213,15 +219,14 @@ public function createService(string $name): object
{
$name = $this->aliases[$name] ?? $name;
$method = self::getMethodName($name);
$callback = $this->methods[$method] ?? null;
if ($callback === null) {
if ($callback = ($this->factories[$name] ?? null)) {
$service = $this->preventDeadLock($name, fn() => $callback());
} elseif (isset($this->methods[$method])) {
$service = $this->preventDeadLock($name, fn() => $this->$method());
} else {
throw new MissingServiceException(sprintf("Service '%s' not found.", $name));
}

$service = $this->preventDeadLock($name, fn() => $callback instanceof \Closure
? $callback()
: $this->$method());

if (!is_object($service)) {
throw new Nette\UnexpectedValueException(sprintf(
"Unable to create service '$name', value returned by %s is not object.",
Expand Down

0 comments on commit ed53906

Please sign in to comment.