Piszemy kontener, za pomocą którego będziemy wstrzykiwać zależności. Kontynuacja lekcji o refleksji i grafie zależności. Do dzieła.
Na początek klasa z konstruktorem, którego parametrami są typy proste (nie podlega rekurencji dla obiektów):
class Person {
public function __construct(public string $name, public int $age)
{
}
}
Teraz inna, nieznana klasa, z konstruktorem bez parametrów:
class UnknownClass {
public string $name;
public int $age;
public function __construct()
{
$this->name = 'Prototype';
$this->age = 30;
}
}
Teraz kontener z rejesterm i możliwością zapisywania doń:
class Container {
private array $registry = [];
public function set(string $name, Closure $value): void
{
$this->registry[$name] = $value;
}
}
Tak to zapisywanie będzie wyglądać w praktyce:
$container = new Container;
$container->set(Person::class, function(){
return new Person("Prototype Name", 30);
});
Czyli klasa, która potrzebuje jakichś argumentów prostych będzie musiała być w rejestrze razem z tymi argumentami w postaci closure.
Teraz metoda get:
class Container {
private array $registry = [];
public function set(string $name, Closure $value): void
{
$this->registry[$name] = $value;
}
public function get(string $className) : object {
if (array_key_exists($className, $this->registry)) {
return $this->registry[$className]();
}
return new $className;
}
}
A teraz przykład działania:
$container = new Container;
$container->set(Person::class, function(){
return new Person("Prototype Name", 30);
});
$person = $container->get(Person::class);
print_r($person);
//Person Object ( [name] => Prototype Name [age] => 30 )
$unknown = $container->get(UnknownClass::class);
print_r($unknown);
//UnknownClass Object ( [name] => Prototype [age] => 30 )
Wszystko można połączyć z grafem zależności znanym z lekcji poprzedniej, ale tym zajmiemy się w następnej lekcji.