Builder::addProvider()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 5
ccs 3
cts 3
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 2
crap 1
1
<?php
2
declare(strict_types=1);
3
/**
4
 * Caridea
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
7
 * use this file except in compliance with the License. You may obtain a copy of
8
 * the License at
9
 *
10
 * http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15
 * License for the specific language governing permissions and limitations under
16
 * the License.
17
 *
18
 * @copyright 2015-2018 LibreWorks contributors
19
 * @license   Apache-2.0
20
 */
21
namespace Caridea\Container;
22
23
/**
24
 * Builder for dependency injection container.
25
 *
26
 * @copyright 2015-2018 LibreWorks contributors
27
 * @license   Apache-2.0
28
 */
29
class Builder
30
{
31
    /**
32
     * @var Provider[] Associative array of string names to `Provider` instances
33
     */
34
    protected $providers = [];
35
    /**
36
     * @var string[] Array of eager `Provider` names
37
     */
38
    protected $eager = [];
39
    
40
    /**
41
     * Adds a new Provider.
42
     *
43
     * This method exists only for completeness. You'd probably spend less
44
     * effort if you call `->eager`, `->lazy`, or `->proto`.
45
     *
46
     * @param string $name The component name
47
     * @param \Caridea\Container\Provider $provider The provider
48
     * @return $this provides a fluent interface
49
     */
50 1
    public function addProvider(string $name, Provider $provider): self
51
    {
52 1
        $this->providers[$name] = $provider;
53 1
        return $this;
54
    }
55
    
56
    /**
57
     * Adds a singleton component to be instantiated after the container is.
58
     *
59
     * ```php
60
     * $builder->eager('foobar', 'Acme\Mail\Service', function($c) {
61
     *     return new \Acme\Mail\Service($c['dependency']);
62
     * });
63
     * ```
64
     *
65
     * @param string $name The component name
66
     * @param string $type The class name of the component
67
     * @param object $factory A `Closure` or class with an `__invoke` method to return the component
68
     * @return $this provides a fluent interface
69
     */
70 1
    public function eager(string $name, string $type, $factory): self
71
    {
72 1
        $provider = new Provider($type, $factory);
73 1
        $this->eager[] = $name;
74 1
        return $this->addProvider($name, $provider);
75
    }
76
    
77
    /**
78
     * Adds a singleton component to be instantiated on demand.
79
     *
80
     * ```php
81
     * $builder->lazy('foobar', 'Acme\Mail\Service', function($c) {
82
     *     return new \Acme\Mail\Service($c['dependency']);
83
     * });
84
     * ```
85
     *
86
     * @param string $name The component name
87
     * @param string $type The class name of the component
88
     * @param object $factory A `Closure` or class with an `__invoke` method to return the component
89
     * @return $this provides a fluent interface
90
     */
91 1
    public function lazy(string $name, string $type, $factory): self
92
    {
93 1
        return $this->addProvider($name, new Provider($type, $factory));
94
    }
95
    
96
    /**
97
     * Adds a component that provides a new instance each time it's instantiated.
98
     *
99
     * ```php
100
     * $builder->lazy('objectStorage', 'SplObjectStorage', function($c) {
101
     *     return new \SplObjectStorage();
102
     * });
103
     * ```
104
     *
105
     * @param string $name The component name
106
     * @param string $type The class name of the component
107
     * @param object $factory A `Closure` or class with an `__invoke` method to return the component
108
     * @return $this provides a fluent interface
109
     */
110 1
    public function proto(string $name, string $type, $factory): self
111
    {
112 1
        return $this->addProvider($name, new Provider($type, $factory, false));
113
    }
114
    
115
    /**
116
     * Builds a container using the settings called.
117
     *
118
     * Any *eager* components will be instantiated at this time.
119
     *
120
     * When this method is called, this builder is reset to its default state.
121
     *
122
     * @param Container $parent An optional parent container
123
     * @return Objects The constructed `Objects` container
124
     */
125 4
    public function build(Container $parent = null): Objects
126
    {
127 4
        $container = new Objects($this->providers, $parent);
128 4
        if (!empty($this->eager)) {
129 1
            foreach ($this->eager as $v) {
130 1
                $container->get($v);
131
            }
132
        }
133 4
        $this->providers = [];
134 4
        $this->eager = [];
135 4
        return $container;
136
    }
137
}
138