Completed
Pull Request — 2.x (#144)
by Akihito
03:38
created

Bind::toInstance()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

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