Passed
Branch main (8d1023)
by Chema
01:53
created

BindingResolver   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 77
Duplicated Lines 0 %

Test Coverage

Coverage 91.67%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 13
eloc 18
c 1
b 0
f 0
dl 0
loc 77
ccs 22
cts 24
cp 0.9167
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A resolveType() 0 12 4
A getBindings() 0 3 1
A hasBinding() 0 3 1
A resolve() 0 25 6
A __construct() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Gacela\Container;
6
7
use function class_exists;
8
use function is_callable;
9
use function is_object;
10
use function is_string;
11
12
/**
13
 * Resolves abstract types to concrete implementations using bindings.
14
 */
15
final class BindingResolver
16
{
17
    /**
18
     * @param array<class-string, class-string|callable|object> $bindings
19
     */
20 61
    public function __construct(
21
        private array $bindings = [],
22
    ) {
23 61
    }
24
25
    /**
26
     * Resolve a class to a concrete instance using bindings.
27
     */
28 24
    public function resolve(string $class, DependencyCacheManager $cacheManager): ?object
29
    {
30 24
        if (isset($this->bindings[$class])) {
31 4
            $binding = $this->bindings[$class];
32
33 4
            if (is_callable($binding)) {
34
                /** @var mixed $binding */
35 2
                $binding = $binding();
36
            }
37
38 4
            if (is_object($binding)) {
39 2
                return $binding;
40
            }
41
42
            /** @var class-string $binding */
43 2
            if (class_exists($binding)) {
44 2
                return $cacheManager->instantiate($binding);
45
            }
46
        }
47
48 20
        if (class_exists($class)) {
49 16
            return $cacheManager->instantiate($class);
50
        }
51
52 4
        return null;
53
    }
54
55
    /**
56
     * Check if a binding exists for a class.
57
     */
58
    public function hasBinding(string $class): bool
59
    {
60
        return isset($this->bindings[$class]);
61
    }
62
63
    /**
64
     * Get all bindings.
65
     *
66
     * @return array<class-string, class-string|callable|object>
67
     */
68 1
    public function getBindings(): array
69
    {
70 1
        return $this->bindings;
71
    }
72
73
    /**
74
     * Resolve a type name to its concrete implementation (for dependency analysis).
75
     *
76
     * @param class-string $typeName
77
     *
78
     * @return class-string
79
     */
80 3
    public function resolveType(string $typeName): string
81
    {
82 3
        if (isset($this->bindings[$typeName])) {
83 1
            $binding = $this->bindings[$typeName];
84
85 1
            if (is_string($binding) && class_exists($binding)) {
86
                /** @var class-string */
87 1
                return $binding;
88
            }
89
        }
90
91 3
        return $typeName;
92
    }
93
}
94