Injector::getInstance()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 26
rs 9.504
c 0
b 0
f 0
cc 4
nc 4
nop 4
1
<?php
2
3
declare(strict_types=1);
4
5
namespace BEAR\Package;
6
7
use BEAR\AppMeta\Meta;
8
use BEAR\Package\Module\ScriptinjectorModule;
9
use BEAR\Sunday\Extension\Application\AppInterface;
10
use Doctrine\Common\Cache\CacheProvider;
11
use Doctrine\Common\Cache\PhpFileCache;
12
use Ray\Compiler\Annotation\Compile;
13
use Ray\Compiler\ScriptInjector;
14
use Ray\Di\Injector as RayInjector;
15
use Ray\Di\InjectorInterface;
16
17
use function assert;
18
use function is_bool;
19
use function is_dir;
20
use function mkdir;
21
22
final class Injector
23
{
24
    /**
25
     * Serialized injector instances
26
     *
27
     * @var array<InjectorInterface>
28
     */
29
    private static $instances;
30
31
    /**
32
     * @codeCoverageIgnore
33
     */
34
    private function __construct()
35
    {
36
    }
37
38
    public static function getInstance(string $appName, string $context, string $appDir, ?CacheProvider $cache = null): InjectorInterface
39
    {
40
        $injectorId = $appName . $context;
41
        if (isset(self::$instances[$injectorId])) {
42
            return self::$instances[$injectorId];
43
        }
44
45
        $meta = new Meta($appName, $context, $appDir);
46
        $cache = $cache ?? new PhpFileCache($meta->tmpDir . '/injector');
47
        $cache->setNamespace($injectorId);
48
        /** @var ?InjectorInterface $cachedInjector */
0 ignored issues
show
Documentation introduced by
The doc-type ?InjectorInterface could not be parsed: Unknown type name "?InjectorInterface" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
49
        $cachedInjector = $cache->fetch(InjectorInterface::class);
50
        if ($cachedInjector instanceof InjectorInterface) {
51
            return $cachedInjector;
52
        }
53
54
        $injector = self::factory($meta, $context);
55
        $injector->getInstance(AppInterface::class);
56
        if ($injector instanceof ScriptInjector) {
57
            $cache->save(InjectorInterface::class, $injector);
58
        }
59
60
        self::$instances[$injectorId] = $injector;
61
62
        return $injector;
63
    }
64
65
    private static function factory(Meta $meta, string $context): InjectorInterface
66
    {
67
        $scriptDir = $meta->tmpDir . '/di';
68
        ! is_dir($scriptDir) && ! @mkdir($scriptDir) && ! is_dir($scriptDir);
69
        $module = (new Module())($meta, $context, '');
70
        $rayInjector = new RayInjector($module, $scriptDir);
71
        $isProd = $rayInjector->getInstance('', Compile::class);
72
        assert(is_bool($isProd));
73
        if ($isProd) {
74
            return new ScriptInjector($scriptDir, static function () use ($scriptDir, $module) {
75
                return new ScriptinjectorModule($scriptDir, $module);
76
            });
77
        }
78
79
        return $rayInjector;
80
    }
81
}
82