DependencyContainer::forget()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 6
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php declare(strict_types=1);
2
3
namespace Stratadox\Di;
4
5
use Closure;
6
use Throwable;
7
use Psr\Container\NotFoundExceptionInterface as NotFound;
8
9
final class DependencyContainer implements Container
10
{
11
    private $remember = [];
12
    private $factoryFor = [];
13
    private $mustReload = [];
14
    private $isCurrentlyResolving = [];
15
16
    public function get($theService)
17
    {
18
        $this->mustKnowAbout($theService);
19
        if ($this->mustReload[$theService] || $this->hasNotYetLoaded($theService)) {
20
            $this->remember[$theService] = $this->load($theService);
21
        }
22
        return $this->remember[$theService];
23
    }
24
25
    public function has($theService): bool
26
    {
27
        return isset($this->factoryFor[$theService]);
28
    }
29
30
    public function set(
31
        string $theService,
32
        Closure $producingTheService,
33
        bool $cache = true
34
    ): void {
35
        $this->remember[$theService] = null;
36
        $this->factoryFor[$theService] = $producingTheService;
37
        $this->mustReload[$theService] = !$cache;
38
    }
39
40
    public function forget(string $theService): void
41
    {
42
        unset(
43
            $this->remember[$theService],
44
            $this->factoryFor[$theService],
45
            $this->mustReload[$theService]
46
        );
47
    }
48
49
    /** @throws InvalidServiceDefinition */
50
    private function load(string $theService)
51
    {
52
        if (isset($this->isCurrentlyResolving[$theService])) {
53
            throw DependenciesCannotBeCircular::loopDetectedIn($theService);
54
        }
55
        $this->isCurrentlyResolving[$theService] = true;
56
        $makeTheService = $this->factoryFor[$theService];
57
        try {
58
            return $makeTheService();
59
        } catch (Throwable $encounteredException) {
60
            throw InvalidFactory::threwException($theService, $encounteredException);
61
        } finally {
62
            unset($this->isCurrentlyResolving[$theService]);
63
        }
64
    }
65
66
    private function hasNotYetLoaded(string $theService): bool
67
    {
68
        return !isset($this->remember[$theService]);
69
    }
70
71
    /** @throws NotFound */
72
    private function mustKnowAbout(string $theService): void
73
    {
74
        if ($this->has($theService)) {
75
            return;
76
        }
77
        throw ServiceNotFound::noServiceNamed($theService);
78
    }
79
}
80