commit | author | age
|
2bddb6
|
1 |
<?php |
e3d936
|
2 |
declare(strict_types= 1); |
2bddb6
|
3 |
namespace Framework; |
F |
4 |
use ReflectionClass; |
75438d
|
5 |
use Closure; |
3880d4
|
6 |
use ReflectionNamedType; |
8cb4bd
|
7 |
use Exception; |
2bddb6
|
8 |
|
F |
9 |
class Container { |
95ec24
|
10 |
|
F |
11 |
private array $registry = []; |
|
12 |
|
75438d
|
13 |
public function set(string $name, Closure $value): void { |
95ec24
|
14 |
$this->registry[$name] = $value; |
F |
15 |
} |
75438d
|
16 |
public function get(string $class_name): object { |
95ec24
|
17 |
if(array_key_exists($class_name, $this->registry)) { |
75438d
|
18 |
return $this->registry[$class_name](); |
95ec24
|
19 |
} |
2bddb6
|
20 |
$reflector = new ReflectionClass($class_name); |
F |
21 |
$contructor = $reflector->getConstructor(); |
|
22 |
|
|
23 |
$dependencies = []; |
|
24 |
|
|
25 |
if($contructor === null) { |
|
26 |
return new $class_name(); |
|
27 |
} |
|
28 |
|
|
29 |
foreach($contructor->getParameters() as $param) { |
d0dae2
|
30 |
$type = $param->getType(); |
3880d4
|
31 |
|
F |
32 |
if($type === null) { |
8cb4bd
|
33 |
throw new Exception("Constructor parameter '{$param->getName()}' in the $class_name class has no type declaration"); |
3880d4
|
34 |
} |
F |
35 |
|
|
36 |
if( ! ($type instanceof ReflectionNamedType)) { |
8cb4bd
|
37 |
throw new Exception("Constructor parameter '{$param->getName()}' in the $class_name class is an invalid type: $type |
3880d4
|
38 |
- only single named type supported"); |
F |
39 |
} |
|
40 |
|
d0dae2
|
41 |
if($type->isBuiltin()) { |
8cb4bd
|
42 |
throw new Exception("Unable to resolve costructor parameter '{$param->getName()}' of type '$type' in the '$class_name' class"); |
d0dae2
|
43 |
} |
e3d936
|
44 |
$dependencies[] = $this->get((string) $type); |
2bddb6
|
45 |
} |
F |
46 |
|
|
47 |
return new $class_name(...$dependencies); |
|
48 |
} |
|
49 |
} |