Skip to content

Commit b6337ee

Browse files
committed
Split from Phimple. Renamed to Container. Altered files accordingly.
1 parent bbdbce3 commit b6337ee

File tree

15 files changed

+1333
-3
lines changed

15 files changed

+1333
-3
lines changed

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
.idea/
2+
build/
3+
vendor/
4+
.DS_Store
5+
composer.lock
6+
phpunit.xml

LICENSE

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
The MIT License (MIT)
22

3-
Copyright (c) 2015 Strident
3+
Copyright (c) 2014 Strident
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal
@@ -18,5 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1818
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1919
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2020
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21-
SOFTWARE.
22-
21+
SOFTWARE.

README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#Container
2+
[![Build Status](https://img.shields.io/travis/Strident/Container.svg)](https://travis-ci.org/Strident/Container)
3+
[![Coverage](https://img.shields.io/codeclimate/coverage/github/Strident/Container.svg)](https://codeclimate.com/github/Strident/Container)
4+
[![Code Climate](https://img.shields.io/codeclimate/github/Strident/Container.svg)](https://codeclimate.com/github/Strident/Container)
5+
6+
Dependency injection container component designed for ease of use and speed. Built for Trident. Heavily inspired by [Pimple][1].
7+
8+
##Installation
9+
10+
Installation is available via Composer. Add the package to your composer.json:
11+
12+
```
13+
$ composer require strident/container ~1.0
14+
```
15+
16+
##Usage
17+
18+
The container is incredibly simple to instantiate. Simply do the following:
19+
20+
```php
21+
use Container\Container;
22+
23+
$container = new Container();
24+
```
25+
26+
[1]: https://github.com/silexphp/Pimple
27+

composer.json

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"name": "strident/container",
3+
"type": "library",
4+
"description": "Simple dependency injection container, inspired by Pimple.",
5+
"keywords": [ "dic" ],
6+
"license": "MIT",
7+
"homepage": "https://github.com/Strident/Container",
8+
"authors": [
9+
{
10+
"name": "Elliot Wright",
11+
"email": "elliot@elliotwright.co"
12+
}
13+
],
14+
"require": {
15+
"php": ">=5.4"
16+
},
17+
"require-dev": {
18+
"phpunit/phpunit": "~4.5",
19+
"codeclimate/php-test-reporter": "~0.1"
20+
},
21+
"autoload": {
22+
"psr-0": { "Container\\": "src/" }
23+
},
24+
"autoload-dev": {
25+
"psr-4": { "Container\\Tests\\": "tests/" }
26+
},
27+
"minimum-stability": "dev"
28+
}

phpunit.xml.dist

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<phpunit
3+
bootstrap="vendor/autoload.php"
4+
colors="true"
5+
convertErrorsToExceptions="true"
6+
convertNoticesToExceptions="true"
7+
convertWarningsToExceptions="true"
8+
stopOnFailure="false"
9+
>
10+
<php>
11+
<ini name="intl.default_locale" value="en"/>
12+
<ini name="intl.error_level" value="0"/>
13+
<ini name="memory_limit" value="-1"/>
14+
</php>
15+
16+
<testsuites>
17+
<testsuite name="Container Test Suite">
18+
<directory suffix="Test.php">tests/</directory>
19+
</testsuite>
20+
</testsuites>
21+
22+
<logging>
23+
<log type="coverage-clover" target="build/logs/clover.xml"/>
24+
</logging>
25+
26+
<filter>
27+
<whitelist>
28+
<directory suffix=".php">src/</directory>
29+
<exclude>
30+
<directory>tests/</directory>
31+
</exclude>
32+
</whitelist>
33+
</filter>
34+
</phpunit>

src/Container/Container.php

Lines changed: 274 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,274 @@
1+
<?php
2+
3+
/**
4+
* This file is part of the Container package.
5+
*
6+
* (c) Elliot Wright <elliot@elliotwright.co>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Container;
13+
14+
use ArrayAccess;
15+
use Closure;
16+
use InvalidArgumentException;
17+
use SplObjectStorage;
18+
19+
/**
20+
* Container
21+
*
22+
* @author Elliot Wright <elliot@elliotwright.co>
23+
*/
24+
class Container implements ArrayAccess, ContainerInterface
25+
{
26+
/**
27+
* @var SplObjectStorage
28+
*/
29+
protected $factories;
30+
31+
/**
32+
* @var LockBox
33+
*/
34+
protected $parameters;
35+
36+
/**
37+
* @var LockBox
38+
*/
39+
protected $services;
40+
41+
42+
/**
43+
* Constructor
44+
*/
45+
public function __construct()
46+
{
47+
$this->factories = new SplObjectStorage();
48+
$this->parameters = new LockBox();
49+
$this->services = new LockBox();
50+
}
51+
52+
/**
53+
* Array access for setting parameters
54+
*
55+
* @param string $name
56+
* @param mixed $value
57+
*/
58+
public function offsetSet($name, $value)
59+
{
60+
$this->setParameter($name, $value);
61+
}
62+
63+
/**
64+
* Array access for getting parameters
65+
*
66+
* @param string $name
67+
*
68+
* @return mixed
69+
*/
70+
public function offsetGet($name)
71+
{
72+
return $this->getParameter($name);
73+
}
74+
75+
/**
76+
* Array item exists
77+
*
78+
* @param string $name
79+
*
80+
* @return boolean
81+
*/
82+
public function offsetExists($name)
83+
{
84+
return $this->hasParameter($name);
85+
}
86+
87+
/**
88+
* Array item unset
89+
*
90+
* @param string $name
91+
*
92+
* @return boolean
93+
*/
94+
public function offsetUnset($name)
95+
{
96+
return $this->removeParameter($name);
97+
}
98+
99+
/**
100+
* {@inheritDoc}
101+
*/
102+
public function set($name, $value)
103+
{
104+
$this->services->set($name, $value);
105+
106+
return $this;
107+
}
108+
109+
/**
110+
* {@inheritDoc}
111+
*/
112+
public function get($name)
113+
{
114+
if (!$this->services->has($name)) {
115+
throw new InvalidArgumentException(sprintf('Service "%s" is not defined.', $name));
116+
}
117+
118+
/** @var Closure $service */
119+
$service = $this->services->get($name);
120+
121+
if ($this->services->isLocked($name)
122+
|| !method_exists($this->services->get($name), '__invoke')) {
123+
return $service;
124+
}
125+
126+
if ($this->factories->contains($service)) {
127+
return $service($this);
128+
}
129+
130+
$this->services->set($name, $service($this));
131+
$this->services->lock($name);
132+
133+
return $this->services->get($name);
134+
}
135+
136+
/**
137+
* {@inheritDoc}
138+
*/
139+
public function has($name)
140+
{
141+
return $this->services->has($name);
142+
}
143+
144+
/**
145+
* {@inheritDoc}
146+
*/
147+
public function remove($name)
148+
{
149+
if ($this->services->has($name)) {
150+
if (is_object($this->services->get($name))) {
151+
unset($this->factories[$this->services->get($name)]);
152+
}
153+
154+
$this->services->remove($name);
155+
}
156+
157+
return $this;
158+
}
159+
160+
/**
161+
* {@inheritDoc}
162+
*/
163+
public function setParameter($name, $value)
164+
{
165+
$this->parameters->set($name, $value);
166+
167+
return $this;
168+
}
169+
170+
/**
171+
* {@inheritDoc}
172+
*/
173+
public function getParameter($name)
174+
{
175+
if (!$this->parameters->has($name)) {
176+
throw new InvalidArgumentException(sprintf('Parameter "%s" is not defined.', $name));
177+
}
178+
179+
return $this->parameters->get($name);
180+
}
181+
182+
/**
183+
* {@inheritDoc}
184+
*/
185+
public function hasParameter($name)
186+
{
187+
return $this->parameters->has($name);
188+
}
189+
190+
/**
191+
* {@inheritDoc}
192+
*/
193+
public function removeParameter($name)
194+
{
195+
return $this->parameters->remove($name);
196+
}
197+
198+
/**
199+
* All array access keys
200+
*
201+
* @return array
202+
*/
203+
public function keys()
204+
{
205+
return $this->services->contents();
206+
}
207+
208+
/**
209+
* Marks a callable as being a factory service.
210+
*
211+
* @param callable $callable
212+
*
213+
* @return callable
214+
*
215+
* @throws InvalidArgumentException
216+
*/
217+
public function factory($callable)
218+
{
219+
if (!is_object($callable) || !method_exists($callable, '__invoke')) {
220+
throw new InvalidArgumentException('Service definition is not a Closure or invokable object.');
221+
}
222+
223+
$this->factories->attach($callable);
224+
225+
return $callable;
226+
}
227+
228+
/**
229+
* Extends a service definition.
230+
*
231+
* @param string $name
232+
* @param callable $callable
233+
* @param boolean $strict
234+
*
235+
* @return callable
236+
*
237+
* @throws InvalidArgumentException
238+
*/
239+
public function extend($name, $callable, $strict = true)
240+
{
241+
if (!$this->services->has($name)) {
242+
if ($strict) {
243+
throw new InvalidArgumentException(sprintf('Service "%s" is not defined.', $name));
244+
} else {
245+
return false;
246+
}
247+
}
248+
249+
$factory = $this->services->get($name);
250+
251+
if (!is_object($factory) || !method_exists($factory, '__invoke')) {
252+
throw new InvalidArgumentException(sprintf('Service "%s" does not contain an object definition.', $name));
253+
}
254+
255+
if (!is_object($callable) || !method_exists($callable, '__invoke')) {
256+
throw new InvalidArgumentException('Extension service definition is not a Closure or invokable object.');
257+
}
258+
259+
$extended = function($c) use($callable, $factory) {
260+
/** @var Closure $factory */
261+
return $callable($factory($c), $c);
262+
};
263+
264+
if ($this->factories->contains($factory)) {
265+
$this->factories->detach($factory);
266+
$this->factories->attach($extended);
267+
}
268+
269+
$this->services->unlock($name);
270+
$this->services->set($name, $extended);
271+
272+
return $this->services->get($name);
273+
}
274+
}

0 commit comments

Comments
 (0)