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

DependencyCacheManager::resolveDependencies()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 5
c 1
b 0
f 0
dl 0
loc 9
ccs 0
cts 6
cp 0
rs 10
cc 2
nc 2
nop 1
crap 6
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 61
    public function __construct(
25
        private array $bindings = [],
26
    ) {
27 61
    }
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 5
    public function resolveCallableDependencies(string $callableKey, Closure $callable): array
53
    {
54 5
        if (!isset($this->cachedDependencies[$callableKey])) {
55 5
            $this->cachedDependencies[$callableKey] = $this
56 5
                ->getDependencyResolver()
57 5
                ->resolveDependencies($callable);
58
        }
59
60 5
        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 2
    public function warmUp(array $classNames): void
69
    {
70 2
        foreach ($classNames as $className) {
71 2
            if (!class_exists($className)) {
72 1
                continue;
73
            }
74
75
            // Pre-resolve dependencies to populate cache
76 2
            if (!isset($this->cachedDependencies[$className])) {
77 2
                $this->cachedDependencies[$className] = $this
78 2
                    ->getDependencyResolver()
79 2
                    ->resolveDependencies($className);
80
            }
81
        }
82
    }
83
84
    /**
85
     * Instantiate a class using cached dependencies.
86
     *
87
     * @param class-string $class
88
     */
89 18
    public function instantiate(string $class): ?object
90
    {
91 18
        if (class_exists($class)) {
92 18
            if (!isset($this->cachedDependencies[$class])) {
93 16
                $this->cachedDependencies[$class] = $this
94 16
                    ->getDependencyResolver()
95 16
                    ->resolveDependencies($class);
96
            }
97
98
            /** @psalm-suppress MixedMethodCall */
99 15
            return new $class(...$this->cachedDependencies[$class]);
100
        }
101
102
        return null;
103
    }
104
105 23
    private function getDependencyResolver(): DependencyResolver
106
    {
107 23
        if ($this->dependencyResolver === null) {
108 23
            $this->dependencyResolver = new DependencyResolver(
109 23
                $this->bindings,
110 23
            );
111
        }
112
113 23
        return $this->dependencyResolver;
114
    }
115
}
116