Completed
Branch 2.x (dc1b30)
by Akihito
02:25
created

Container::__sleep()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
3
/**
4
 * This file is part of the Ray.Di package.
5
 *
6
 * @license http://opensource.org/licenses/MIT MIT
7
 */
8
namespace Ray\Di;
9
10
use Ray\Aop\Compiler;
11
use Ray\Aop\Pointcut;
12
use Ray\Di\Exception\Unbound;
13
use Ray\Di\Exception\Untargetted;
14
15
final class Container
16
{
17
    /**
18
     * @var DependencyInterface[]
19
     */
20
    private $container = [];
21
22
    /**
23
     * @var Pointcut[]
24
     */
25
    private $pointcuts = [];
26
27
    /**
28
     * Add binding to container
29
     *
30
     * @param Bind $bind
31
     */
32 74
    public function add(Bind $bind)
33
    {
34 74
        $dependency = $bind->getBound();
35 74
        $dependency->register($this->container, $bind);
36 74
    }
37
38
    /**
39
     * Add Pointcut to container
40
     *
41
     * @param Pointcut $pointcut
42
     */
43 7
    public function addPointcut(Pointcut $pointcut)
44
    {
45 7
        $this->pointcuts[] = $pointcut;
46 7
    }
47
48
    /**
49
     * Return instance by interface + name(interface namespace)
50
     *
51
     * @param string $interface
52
     * @param string $name
53
     *
54
     * @return mixed
55
     */
56 45
    public function getInstance($interface, $name)
57
    {
58 45
        return $this->getDependency($interface . '-' . $name);
59
    }
60
61
    /**
62
     * Return dependency injected instance
63
     *
64
     * @param string $index
65
     *
66
     * @return mixed
67
     *
68
     * @throws Unbound
69
     */
70 65
    public function getDependency($index)
71
    {
72 65
        if (! isset($this->container[$index])) {
73 21
            throw $this->unbound($index);
74
        }
75 61
        $dependency = $this->container[$index];
76 61
        $instance = $dependency->inject($this);
77
78 60
        return $instance;
79
    }
80
81
    /**
82
     * Rename existing dependency interface + name
83
     *
84
     * @param string $sourceInterface
85
     * @param string $sourceName
86
     * @param string $targetInterface
87
     * @param string $targetName
88
     */
89 22
    public function move($sourceInterface, $sourceName, $targetInterface, $targetName)
90
    {
91 22
        $sourceIndex = $sourceInterface . '-' . $sourceName;
92 3
        if (! isset($this->container[$sourceIndex])) {
93 1
            throw $this->unbound($sourceIndex);
94
        }
95 2
        $targetIndex = $targetInterface . '-' . $targetName;
96 2
        $this->container[$targetIndex] = $this->container[$sourceIndex];
97 21
        unset($this->container[$sourceIndex]);
98 2
    }
99
100
    /**
101
     * @param string $index {interface}-{bind name}
102
     *
103
     * @return Untargetted | Unbound
104
     */
105 22
    public function unbound($index)
106
    {
107 22
        list($class, $name) = explode('-', $index);
108 22
        if (class_exists($class) && ! (new \ReflectionClass($class))->isAbstract()) {
109 10
            return new Untargetted($class);
110
        }
111
112 15
        return new Unbound("{$class}-{$name}");
113
    }
114
115
    /**
116
     * @return DependencyInterface[]
117
     */
118 37
    public function getContainer()
119
    {
120 37
        return $this->container;
121
    }
122
123
    /**
124
     * @return \Ray\Aop\Pointcut[]
125
     */
126 12
    public function getPointcuts()
127
    {
128 12
        return $this->pointcuts;
129
    }
130
131
    /**
132
     * @param Container $container
133
     */
134 12
    public function merge(Container $container)
135
    {
136 12
        $this->container = $this->container + $container->getContainer();
137 12
        $this->pointcuts = array_merge($this->pointcuts, $container->getPointcuts());
138 12
    }
139
140
    /**
141
     * Weave aspects to all dependency in container
142
     *
143
     * @param Compiler $compiler
144
     */
145 33
    public function weaveAspects(Compiler $compiler)
146
    {
147 33
        foreach ($this->container as $dependency) {
148 27
            if (! $dependency instanceof Dependency) {
149 17
                continue;
150
            }
151
            /* @var $dependency Dependency */
152 12
            $dependency->weaveAspects($compiler, $this->pointcuts);
153 33
        }
154 33
    }
155
156
    /**
157
     * Weave aspect to single dependency
158
     *
159
     * @param Compiler   $compiler
160
     * @param Dependency $dependency
161
     *
162
     * @return $this
163
     */
164 10
    public function weaveAspect(Compiler $compiler, Dependency $dependency)
165
    {
166 10
        $dependency->weaveAspects($compiler, $this->pointcuts);
167
168 10
        return $this;
169
    }
170
171 2
    public function __sleep()
172
    {
173 2
        return ['container', 'pointcuts'];
174
    }
175
}
176