Наипростейший DI-контейнер

1. Возможность добавить зависимости автосборщиком в конструктор. 2. Возможность ручного добавления зависимостей. 3. Автовайринг.


<?php

use Closure;
use Exception;
use ReflectionClass;

class Container
{
private $dependencies;
private $result = [];

public function __construct($dependencies = [])
{
$this->dependencies = $dependencies;
}

public function set($key, $value)
{
if (array_key_exists($key, $this->result)) {
unset($this->result[$key]);
}

$this->dependencies[$key] = $value;

return $this;
}

public function has($key)
{
return array_key_exists($key, $this->dependencies) || class_exists($key);
}

public function get($key)
{
if (array_key_exists($key, $this->result)) {
return $this->result[$key];
}

if (!array_key_exists($key, $this->dependencies)) {

if (class_exists($key)) {
$reflectionClass = new ReflectionClass($key);
$args = [];

if ($constructor = $reflectionClass->getConstructor()) {

foreach ($constructor->getParameters() as $parameter) {

if ($parameter->getType()->isBuiltin()) {

if (!$parameter->isDefaultValueAvailable()) {
throw new Exception("Не указано значение по умолчанию параметра: $parameter->name");
}

$args[] = $parameter->getDefaultValue();
} else {
$args[] = $this->get($parameter->getType()->getName());
}
}
}

return $this->result[$key] = $reflectionClass->newInstanceArgs($args);
}

throw new Exception("Не найдена зависимость: $key");
}

$dependency = $this->dependencies[$key];

if ($dependency instanceof Closure) {
$this->result[$key] = $dependency($this);
} else {
$this->result[$key] = $dependency;
}

return $this->result[$key];
}
}


  18.01.24 / 06:01 | PHP |   98 | 0   0