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

InstanceRegistry::update()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
ccs 0
cts 2
cp 0
rs 10
cc 1
nc 1
nop 2
crap 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Gacela\Container;
6
7
use Gacela\Container\Exception\ContainerException;
8
9
use function is_object;
10
use function method_exists;
11
12
/**
13
 * Manages service instance storage and frozen state.
14
 */
15
final class InstanceRegistry
16
{
17
    /** @var array<string,mixed> */
18
    private array $instances = [];
19
20
    /** @var array<string,bool> */
21
    private array $frozenInstances = [];
22
23
    /**
24
     * Check if an instance is registered.
25
     */
26 50
    public function has(string $id): bool
27
    {
28 50
        return isset($this->instances[$id]);
29
    }
30
31
    /**
32
     * Store a service instance.
33
     *
34
     * @throws ContainerException if instance is frozen
35
     */
36 27
    public function set(string $id, mixed $instance): void
37
    {
38 27
        if (!empty($this->frozenInstances[$id])) {
39 1
            throw ContainerException::frozenInstanceOverride($id);
40
        }
41
42 27
        $this->instances[$id] = $instance;
43
    }
44
45
    /**
46
     * Get a service instance, handling frozen state and factory/protected closures.
47
     */
48 20
    public function get(string $id, FactoryManager $factoryManager, Container $container): mixed
49
    {
50 20
        $this->frozenInstances[$id] = true;
51
52 20
        if (!is_object($this->instances[$id])
53 17
            || $factoryManager->isProtected($this->instances[$id])
54 20
            || !method_exists($this->instances[$id], '__invoke')
55
        ) {
56 12
            return $this->instances[$id];
57
        }
58
59 14
        if ($factoryManager->isFactory($this->instances[$id])) {
60 3
            return $this->instances[$id]($container);
61
        }
62
63 11
        $rawService = $this->instances[$id];
64
65
        /** @var mixed $resolvedService */
66 11
        $resolvedService = $rawService($container);
67
68 11
        $this->instances[$id] = $resolvedService;
69
70 11
        return $resolvedService;
71
    }
72
73
    /**
74
     * Remove a service instance and its frozen state.
75
     */
76 2
    public function remove(string $id): void
77
    {
78 2
        unset(
79 2
            $this->instances[$id],
80 2
            $this->frozenInstances[$id],
81 2
        );
82
    }
83
84
    /**
85
     * Check if an instance is frozen.
86
     */
87 13
    public function isFrozen(string $id): bool
88
    {
89 13
        return isset($this->frozenInstances[$id]);
90
    }
91
92
    /**
93
     * Get all registered service IDs.
94
     *
95
     * @return list<string>
96
     */
97 1
    public function getAll(): array
98
    {
99 1
        return array_keys($this->instances);
100
    }
101
102
    /**
103
     * Get raw instance for internal use (e.g., factory status transfer, extension).
104
     */
105 11
    public function getRaw(string $id): mixed
106
    {
107 11
        return $this->instances[$id] ?? null;
108
    }
109
110
    /**
111
     * Update instance directly (for lazy-loaded services).
112
     */
113
    public function update(string $id, mixed $instance): void
114
    {
115
        $this->instances[$id] = $instance;
116
    }
117
}
118