Test Failed
Push — main ( 3d89fd...8d1023 )
by Chema
03:11
created

resolveCallableDependencies()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 5
c 1
b 0
f 0
dl 0
loc 9
rs 10
cc 2
nc 2
nop 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Gacela\Container;
6
7
use Closure;
8
9
use function class_exists;
10
11
/**
12
 * Manages dependency resolution caching for performance optimization.
13
 */
14
final class DependencyCacheManager
15
{
16
    /** @var array<class-string|string, list<mixed>> */
17
    private array $cachedDependencies = [];
18
19
    private ?DependencyResolver $dependencyResolver = null;
20
21
    /**
22
     * @param array<class-string, class-string|callable|object> $bindings
23
     */
24
    public function __construct(
25
        private array $bindings = [],
26
    ) {
27
    }
28
29
    /**
30
     * Resolve dependencies for a class, using cache if available.
31
     *
32
     * @param class-string $className
33
     *
34
     * @return list<mixed>
35
     */
36
    public function resolveDependencies(string $className): array
37
    {
38
        if (!isset($this->cachedDependencies[$className])) {
39
            $this->cachedDependencies[$className] = $this
40
                ->getDependencyResolver()
41
                ->resolveDependencies($className);
42
        }
43
44
        return $this->cachedDependencies[$className];
45
    }
46
47
    /**
48
     * Resolve dependencies for a callable with a specific cache key.
49
     *
50
     * @return list<mixed>
51
     */
52
    public function resolveCallableDependencies(string $callableKey, Closure $callable): array
53
    {
54
        if (!isset($this->cachedDependencies[$callableKey])) {
55
            $this->cachedDependencies[$callableKey] = $this
56
                ->getDependencyResolver()
57
                ->resolveDependencies($callable);
58
        }
59
60
        return $this->cachedDependencies[$callableKey];
61
    }
62
63
    /**
64
     * Pre-warm the dependency cache for multiple classes.
65
     *
66
     * @param list<class-string> $classNames
67
     */
68
    public function warmUp(array $classNames): void
69
    {
70
        foreach ($classNames as $className) {
71
            if (!class_exists($className)) {
72
                continue;
73
            }
74
75
            // Pre-resolve dependencies to populate cache
76
            if (!isset($this->cachedDependencies[$className])) {
77
                $this->cachedDependencies[$className] = $this
78
                    ->getDependencyResolver()
79
                    ->resolveDependencies($className);
80
            }
81
        }
82
    }
83
84
    /**
85
     * Instantiate a class using cached dependencies.
86
     *
87
     * @param class-string $class
88
     */
89
    public function instantiate(string $class): ?object
90
    {
91
        if (class_exists($class)) {
92
            if (!isset($this->cachedDependencies[$class])) {
93
                $this->cachedDependencies[$class] = $this
94
                    ->getDependencyResolver()
95
                    ->resolveDependencies($class);
96
            }
97
98
            /** @psalm-suppress MixedMethodCall */
99
            return new $class(...$this->cachedDependencies[$class]);
100
        }
101
102
        return null;
103
    }
104
105
    private function getDependencyResolver(): DependencyResolver
106
    {
107
        if ($this->dependencyResolver === null) {
108
            $this->dependencyResolver = new DependencyResolver(
109
                $this->bindings,
110
            );
111
        }
112
113
        return $this->dependencyResolver;
114
    }
115
}
116