Passed
Push — main ( 8d1023...74092d )
by Chema
53s
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
use function count;
11
12
/**
13
 * Manages dependency resolution caching for performance optimization.
14
 */
15
final class DependencyCacheManager
16
{
17
    /** @var array<class-string|string, list<mixed>> */
18
    private array $cachedDependencies = [];
19
20
    private ?DependencyResolver $dependencyResolver = null;
21
22
    /**
23
     * @param array<class-string, class-string|callable|object> $bindings
24
     */
25 69
    public function __construct(
26
        private array $bindings = [],
27
    ) {
28 69
    }
29
30
    /**
31
     * Resolve dependencies for a class, using cache if available.
32
     *
33
     * @param class-string $className
34
     *
35
     * @return list<mixed>
36
     */
37
    public function resolveDependencies(string $className): array
38
    {
39
        if (!isset($this->cachedDependencies[$className])) {
40
            $this->cachedDependencies[$className] = $this
41
                ->getDependencyResolver()
42
                ->resolveDependencies($className);
43
        }
44
45
        return $this->cachedDependencies[$className];
46
    }
47
48
    /**
49
     * Resolve dependencies for a callable with a specific cache key.
50
     *
51
     * @return list<mixed>
52
     */
53 5
    public function resolveCallableDependencies(string $callableKey, Closure $callable): array
54
    {
55 5
        if (!isset($this->cachedDependencies[$callableKey])) {
56 5
            $this->cachedDependencies[$callableKey] = $this
57 5
                ->getDependencyResolver()
58 5
                ->resolveDependencies($callable);
59
        }
60
61 5
        return $this->cachedDependencies[$callableKey];
62
    }
63
64
    /**
65
     * Pre-warm the dependency cache for multiple classes.
66
     *
67
     * @param list<class-string> $classNames
68
     */
69 3
    public function warmUp(array $classNames): void
70
    {
71 3
        foreach ($classNames as $className) {
72 3
            if (!class_exists($className)) {
73 1
                continue;
74
            }
75
76
            // Pre-resolve dependencies to populate cache
77 3
            if (!isset($this->cachedDependencies[$className])) {
78 3
                $this->cachedDependencies[$className] = $this
79 3
                    ->getDependencyResolver()
80 3
                    ->resolveDependencies($className);
81
            }
82
        }
83
    }
84
85
    /**
86
     * Instantiate a class using cached dependencies.
87
     *
88
     * @param class-string $class
89
     */
90 18
    public function instantiate(string $class): ?object
91
    {
92 18
        if (class_exists($class)) {
93 18
            if (!isset($this->cachedDependencies[$class])) {
94 16
                $this->cachedDependencies[$class] = $this
95 16
                    ->getDependencyResolver()
96 16
                    ->resolveDependencies($class);
97
            }
98
99
            /** @psalm-suppress MixedMethodCall */
100 15
            return new $class(...$this->cachedDependencies[$class]);
101
        }
102
103
        return null;
104
    }
105
106
    /**
107
     * Get the number of cached dependency resolutions.
108
     */
109 8
    public function getCacheSize(): int
110
    {
111 8
        return count($this->cachedDependencies);
112
    }
113
114
    /**
115
     * Get all cached class names.
116
     *
117
     * @return list<string>
118
     */
119
    public function getCachedClasses(): array
120
    {
121
        return array_keys($this->cachedDependencies);
122
    }
123
124 24
    private function getDependencyResolver(): DependencyResolver
125
    {
126 24
        if ($this->dependencyResolver === null) {
127 24
            $this->dependencyResolver = new DependencyResolver(
128 24
                $this->bindings,
129 24
            );
130
        }
131
132 24
        return $this->dependencyResolver;
133
    }
134
}
135