http://phing.info/

Source Code Coverage

Designed for use with PHPUnit2, Xdebug and Phing.

Methods: 14 LOC: 243 Statements: 52
Legend: executednot executeddead code
Source file Statements Methods Total coverage
Container.php 100.0% 100.0% 100.0%
 
1
<?php
2
/**
3
 * Xyster Framework
4
 *
5
 * This source file is subject to the new BSD license that is bundled
6
 * with this package in the file LICENSE.txt.
7
 * It is also available through the world-wide-web at this URL:
8
 * http://www.opensource.org/licenses/bsd-license.php
9
 *
10
 * @category  Xyster
11
 * @package   Xyster_Container
12
 * @copyright Copyright LibreWorks, LLC (http://libreworks.net)
13
 * @license   http://www.opensource.org/licenses/bsd-license.php New BSD License
14
 * @version   $Id$
15
 */
16
namespace Xyster\Container;
17
use Xyster\Type\Type;
18
/**
19
 * The standard implementation of the dependency injection container.
20
 *
21
 * @category  Xyster
22
 * @package   Xyster_Container
23
 * @copyright Copyright LibreWorks, LLC (http://libreworks.net)
24
 * @license   http://www.opensource.org/licenses/bsd-license.php New BSD License
25
 */
26
class Container implements IMutable
27
{
28
    /**
29
     * @var IContainer
30
     */
31
    protected $_parent;
32
    /**
33
     * @var \Xyster\Container\Provider\IProvider[]
34
     */
35
    protected $_providers = array();
36
    protected $_types = array();
37
38
    /**
39
     * Creates a new container.
40
     *
41
     * @param IContainer $parent The parent container
42
     */
43
    public function __construct(IContainer $parent = null)
44
    {
45 39
        $this->_parent = $parent;
46
    }
47
48
    /**
49
     * Adds a definition to the container and autowires its dependencies based on the constructor.
50
     *
51
     * @param mixed $type A Xyster_Type or the name of a class
52
     * @param string $name Optional. The component name.
53
     * @return IMutable provides a fluent interface
54
     */
55
    public function autowire($type, $name = null)
56
    {
57 3
        return $this->addProvider(new Injector\Autowiring(
58 3
                        new Definition($type, $name), Autowire::Constructor()));
59
    }
60
61
    /**
62
     * Adds a definition to the container and autowires its dependencies.
63
     *
64
     * @param mixed $type A Xyster_Type or the name of a class
65
     * @param string $name Optional. The component name.
66
     * @param array $except Optional.  An array of property names to ignore.
67
     * @return IMutable provides a fluent interface
68
     */
69
    public function autowireByName($type, $name = null, array $except = array())
70
    {
71 1
        return $this->addProvider(new Injector\Autowiring(
72 1
                        new Definition($type, $name), Autowire::ByName(), $except));
73
    }
74
75
    /**
76
     * Adds a definition to the container and autowires its dependencies.
77
     *
78
     * @param mixed $type A Xyster_Type or the name of a class
79
     * @param string $name Optional. The component name.
80
     * @param array $except Optional.  An array of property names to ignore.
81
     * @return IMutable provides a fluent interface
82
     */
83
    public function autowireByType($type, $name = null, array $except = array())
84
    {
85 1
        return $this->addProvider(new Injector\Autowiring(
86 1
                        new Definition($type, $name), Autowire::ByType(), $except));
87
    }
88
89
    /**
90
     * Adds a definition to the container.
91
     *
92
     * @param Definition $definition The component definition
93
     * @return IMutable provides a fluent interface
94
     */
95
    public function add(Definition $definition)
96
    {
97 19
        return $this->addProvider(new Injector\Standard($definition));
98
    }
99
100
    /**
101
     * Adds a provider to the container.
102
     *
103
     * @param Provider\IProvider $provider The provider
104
     * @return IMutable provides a fluent interface
105
     */
106
    public function addProvider(Provider\IProvider $provider)
107
    {
108 25
        if (in_array($provider, $this->_providers, true) ||
109 25
                array_key_exists($provider->getName(), $this->_providers)) {
110 1
            throw new ContainerException('A component with the name "' .
111 1
                    $provider->getName() . '" is already registered');
112
        }
113 25
        $this->_types[] = $provider->getType()->getName();
114 25
        $this->_providers[$provider->getName()] = $provider;
115 25
        return $this;
116
    }
117
118
    /**
119
     * Whether this container contains a component with the given name.
120
     *
121
     * @param string $name The component name
122
     * @return boolean
123
     */
124
    public function contains($name)
125
    {
126 21
        return array_key_exists($name, $this->_providers);
127
    }
128
129
    /**
130
     * Whether this container contains a component with the given type.
131
     *
132
     * @param mixed $type A \Xyster\Type\Type or the name of a class
133
     * @return boolean
134
     */
135
    public function containsType($type)
136
    {
137 7
        $realType = $type instanceof Type ? $type : new Type($type);
138
        /* @var $realType \Xyster\Type\Type */
139 7
        foreach ($this->_types as $ctype) {
140 6
            if ($realType->isAssignableFrom($ctype)) {
141 6
                return true;
142
            }
143 2
        }
144
    }
145
146
    /**
147
     * Creates a new definition.
148
     *
149
     * This method is just for convenience.  Prevents having to create a new
150
     * definition and then populating it, then passing it to the add method.
151
     *
152
     * @param mixed $type A Xyster_Type or the name of a class
153
     * @param string $name Optional. The component name.
154
     * @return Definition the definition created
155
     */
156
    static public function definition($type, $name = null)
157
    {
158 24
        return new Definition($type, $name);
159
    }
160
161
    /**
162
     * Gets the component by name.
163
     *
164
     * @param string $name The component name
165
     * @param Type $into Optional. The type into which the component is being injected
166
     * @return object The component
167
     */
168
    public function get($name, Type $into = null)
169
    {
170 10
        if (!$this->contains($name)) {
171 1
            return ( $this->_parent !== null ) ?
172 1
                    $this->_parent->get($name, $into) : null;
173
        } else {
174 10
            return $this->_providers[$name]->get($this);
175
        }
176
    }
177
178
    /**
179
     * Gets the components in the contanier for the given type.
180
     *
181
     * @param mixed $type A Xyster_Type or string class name
182
     * @return array Keys are component names, values are components themselves
183
     */
184
    public function getForType($type)
185
    {
186 6
        $type = $type instanceof Type ? $type : new Type($type);
187 6
        $components = array();
188 6
        foreach ($this->_providers as $name => $provider) {
189
            /* @var $provider \Xyster\Container\Provider\IProvider */
190 6
            if ($type->isAssignableFrom($provider->getType())) {
191 6
                $components[$name] = $provider->get($this);
192 6
            }
193 6
        }
194 6
        return $components;
195
    }
196
197
    /**
198
     * Gets the component names given a type.
199
     *
200
     * If the type argument is omitted, this will return all component names.
201
     *
202
     * @param mixed $type Optional. A Xyster_Type or string class name
203
     * @return array of strings
204
     */
205
    public function getNames($type = null)
206
    {
207 5
        if ($type === null) {
208 1
            return array_keys($this->_providers);
209
        } else {
210 5
            $type = $type instanceof Type ? $type : new Type($type);
211 5
            $names = array();
212 5
            foreach ($this->_providers as $name => $provider) {
213
                /* @var $provider \Xyster\Container\Provider\IProvider */
214 4
                if ($type->isAssignableFrom($provider->getType())) {
215 4
                    $names[] = $provider->getName();
216 4
                }
217 5
            }
218 5
            return $names;
219
        }
220
    }
221
222
    /**
223
     * Gets the parent container.
224
     *
225
     * @return IContainer
226
     */
227
    public function getParent()
228
    {
229 1
        return $this->_parent;
230
    }
231
232
    /**
233
     * Gets the type of component with the given name.
234
     *
235
     * @param string $name The component name
236
     * @return Type The component type
237
     */
238
    public function getType($name)
239
    {
240 1
        return $this->contains($name) ?
241 1
                $this->_providers[$name]->getType() : null;
242
    }
243 1
}


Report generated at 2010-10-18T17:19:49-04:00