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

Bind::toProvider()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 1

Importance

Changes 3
Bugs 0 Features 1
Metric Value
dl 0
loc 9
cc 1
eloc 6
c 3
b 0
f 1
nc 1
nop 1
ccs 6
cts 6
cp 1
crap 1
rs 9.6666
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\Di\Exception\NotFound;
11
12
final class Bind
13
{
14
    /**
15
     * @var Container
16
     */
17
    private $container;
18
19
    /**
20
     * @var string
21
     */
22
    private $interface;
23
24
    /**
25
     * @var string
26
     */
27
    private $name = Name::ANY;
28
29
    /**
30
     * @var DependencyInterface
31
     */
32
    private $bound;
33
34
    /**
35
     * @var BindValidator
36
     */
37
    private $validate;
38
39
    /**
40
     * @var Untarget
41
     */
42
    private $untarget;
43
44
    /**
45
     * @param Container $container dependency container
46
     * @param string    $interface interface or concrete class name
47
     */
48 81
    public function __construct(Container $container, $interface)
49
    {
50 81
        $this->container = $container;
51 81
        $this->interface = $interface;
52 81
        $this->validate = new BindValidator;
53 81
        $bindUntarget = class_exists($interface) && ! (new \ReflectionClass($interface))->isAbstract() && $this->hasNotRegistered($interface);
54 81
        if ($bindUntarget) {
55 27
            $this->untarget = new Untarget($interface);
56
57 27
            return;
58 1
        }
59 80
        $this->validate->constructor($interface);
60 79
    }
61
62 75
    public function __destruct()
63
    {
64 75
        if ($this->untarget) {
65 13
            $this->untarget->__invoke($this->container, $this);
66 13
            $this->untarget = null;
67 13
        }
68 75
    }
69
70
    /**
71
     * @param string $name
72
     *
73
     * @return $this
74
     */
75 23
    public function annotatedWith($name)
76
    {
77 23
        $this->name = $name;
78
79 23
        return $this;
80
    }
81
82
    /**
83
     * @param string $class
84
     *
85
     * @return $this
86
     */
87 31
    public function to($class)
88
    {
89 31
        $this->untarget = null;
90 31
        $this->validate->to($this->interface, $class);
91 29
        $this->bound = (new DependencyFactory)->newAnnotatedDependency(new \ReflectionClass($class));
92 29
        $this->container->add($this);
93
94 29
        return $this;
95
    }
96
97
    /**
98
     * @param string          $class           class name
99
     * @param string          $name            varName=bindName,...
100
     * @param InjectionPoints $injectionPoints injection points
101
     * @param null            $postConstruct   method name of initialization after all dependencies are injected
102
     *
103
     * @return $this
104
     */
105 2
    public function toConstructor($class, $name, InjectionPoints $injectionPoints = null, $postConstruct = null)
106
    {
107 2
        $this->untarget = null;
108 2
        $postConstruct = $postConstruct ? new \ReflectionMethod($class, $postConstruct) : null;
109 2
        $this->bound = (new DependencyFactory)->newToConstructor(new \ReflectionClass($class), $name, $injectionPoints, $postConstruct);
110 2
        $this->container->add($this);
111
112 2
        return $this;
113
    }
114
115
    /**
116
     * @param string $provider
117
     *
118
     * @return $this
119
     *
120
     * @throws NotFound
121
     */
122 14
    public function toProvider($provider)
123
    {
124 14
        $this->untarget = null;
125 14
        $this->validate->toProvider($provider);
126 12
        $this->bound = (new DependencyFactory)->newProvider(new \ReflectionClass($provider));
127 12
        $this->container->add($this);
128
129 12
        return $this;
130
    }
131
132
    /**
133
     * @param mixed $instance
134
     *
135
     * @return $this
136
     */
137 69
    public function toInstance($instance)
138
    {
139 69
        $this->untarget = null;
140 69
        $this->bound = new Instance($instance);
141 69
        $this->container->add($this);
142
143 69
        return $this;
144
    }
145
146
    /**
147
     * @param string $scope
148
     *
149
     * @return $this
150
     */
151 15
    public function in($scope)
152
    {
153 15
        if ($this->bound instanceof Dependency || $this->bound instanceof DependencyProvider) {
154 14
            $this->bound->setScope($scope);
155 14
        }
156 15
        if ($this->untarget) {
157 1
            $this->untarget->setScope($scope);
158 1
        }
159
160 15
        return $this;
161
    }
162
163
    /**
164
     * @return string
165
     */
166 75
    public function __toString()
167
    {
168 75
        return $this->interface . '-' . $this->name;
169
    }
170
171
    /**
172
     * @return DependencyInterface
173
     */
174 74
    public function getBound()
175
    {
176 74
        return $this->bound;
177
    }
178
179
    /**
180
     * @param DependencyInterface $bound
181
     */
182 13
    public function setBound(DependencyInterface $bound)
183
    {
184 13
        $this->bound = $bound;
185 13
    }
186
187
    /**
188
     * @param string $interface
189
     *
190
     * @return bool
191
     */
192 27
    private function hasNotRegistered($interface)
193
    {
194 27
        $hasNotRegistered = ! isset($this->container->getContainer()[$interface . '-' . Name::ANY]);
195
196 27
        return $hasNotRegistered;
197
    }
198
}
199