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

InstanceRegistry::isFrozen()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 1
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
    public function has(string $id): bool
27
    {
28
        return isset($this->instances[$id]);
29
    }
30
31
    /**
32
     * Store a service instance.
33
     *
34
     * @throws ContainerException if instance is frozen
35
     */
36
    public function set(string $id, mixed $instance): void
37
    {
38
        if (!empty($this->frozenInstances[$id])) {
39
            throw ContainerException::frozenInstanceOverride($id);
40
        }
41
42
        $this->instances[$id] = $instance;
43
    }
44
45
    /**
46
     * Get a service instance, handling frozen state and factory/protected closures.
47
     */
48
    public function get(string $id, FactoryManager $factoryManager, Container $container): mixed
49
    {
50
        $this->frozenInstances[$id] = true;
51
52
        if (!is_object($this->instances[$id])
53
            || $factoryManager->isProtected($this->instances[$id])
54
            || !method_exists($this->instances[$id], '__invoke')
55
        ) {
56
            return $this->instances[$id];
57
        }
58
59
        if ($factoryManager->isFactory($this->instances[$id])) {
60
            return $this->instances[$id]($container);
61
        }
62
63
        $rawService = $this->instances[$id];
64
65
        /** @var mixed $resolvedService */
66
        $resolvedService = $rawService($container);
67
68
        $this->instances[$id] = $resolvedService;
69
70
        return $resolvedService;
71
    }
72
73
    /**
74
     * Remove a service instance and its frozen state.
75
     */
76
    public function remove(string $id): void
77
    {
78
        unset(
79
            $this->instances[$id],
80
            $this->frozenInstances[$id],
81
        );
82
    }
83
84
    /**
85
     * Check if an instance is frozen.
86
     */
87
    public function isFrozen(string $id): bool
88
    {
89
        return isset($this->frozenInstances[$id]);
90
    }
91
92
    /**
93
     * Get all registered service IDs.
94
     *
95
     * @return list<string>
96
     */
97
    public function getAll(): array
98
    {
99
        return array_keys($this->instances);
100
    }
101
102
    /**
103
     * Get raw instance for internal use (e.g., factory status transfer, extension).
104
     */
105
    public function getRaw(string $id): mixed
106
    {
107
        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