<?php
class Container {
private array $factories = [];
public function addFactory(string $className, Factory $factory): void
{
$this->factories[$className] = $factory;
}
public function getInstance(string $className): object
{
return $this->factories[$className]->create();
}
}
abstract class Factory {
private Container $container;
private array $config = [];
public function __construct(Container $container, array $config = [])
{
$this->container = $container;
$instanceConfig = array_key_exists(static::getClass(), $config) ? $config[static::getClass()] : [];
$this->config = $instanceConfig;
}
abstract public static function getClass(): string;
public function create(): object
{
$class = static::getClass();
$parameters = [];
foreach($this->config['parameters'] as $name => $value) {
if (null === $value) {
$value = $this->container->getInstance($name);
}
$parameters[] = $value;
}
return new $class(...$parameters);
}
}
class FooFactory extends Factory {
public static function getClass(): string
{
return Foo::class;
}
}
class BarFactory extends Factory {
public static function getClass(): string
{
return Bar::class;
}
}
class Foo {
private Bar $bar;
private string $test;
public function __construct(Bar $bar, string $test)
{
$this->bar = $bar;
$this->test = $test;
}
}
class Bar {}
$config = [
Foo::class => [
'parameters' => [
Bar::class => null,
'test',
]
],
Bar::class => [
'parameters' => [],
],
];
$container = new Container;
$container->addFactory(FooFactory::getClass(), new FooFactory($container, $config));
$container->addFactory(BarFactory::getClass(), new BarFactory($container, $config));
$foo = $container->getInstance(Foo::class);
var_dump($container);
var_dump($foo);
preferences:
23.21 ms | 404 KiB | 5 Q