DaContainer
, (*1)
A simpe IoC container for PHP., (*2)
DaContainer is a powerful inversion of control container for managing class dependencies., (*3)
Installation
Simply add dagardner/dacontainer to your composer dependencies and run composer install., (*4)
"require": {
"dagardner/dacontainer": "1.*"
}
The last step is to include composer' s autoload file (like this: require './vendor/autoload.php'., (*5)
And thats it. In the next chapter we we' ll cover basic usage., (*6)
Basic Usage
DaContainer can resolve both via Closure and direct resolution. Let' s start with Closures:, (*7)
Binding...
$container = new \DaGardner\DaContainer\Container;
$container->bind('foo', function() {
return new stdClass;
});
Resolving
$container->resolve('foo');
This will call the closure callback and therefor returns a new instance of a stdClass., (*8)
Singletons
Even if this pattern is often consired to be an anti-pattern, I implemented it, just in case somebody craves for it..., (*9)
$container->singelton('foo', function() {
return new stdClass;
});
This closure is only called once during execution. The returned instance is stored and a second resolve call will return the stored instance:, (*10)
($container->resolve('foo') === $container->resolve('foo));
This statement will be true., (*11)
You can also store existing objects into the container:, (*12)
$object = new stdClass;
$container->instance('foo', $object);
Automatic Injection
The IoC DaContainer can also auto-inject dependencies of a class into it' s constrcutor and injector methods., (*13)
class Foo
{
public function __construct(stdClass $class) {}
public function setLogger(LoggerInterface $logger) {}
}
With some other containers this wouldn' t be possible. The DaContainer will analyze the class with Reflections and auto-inject classes., (*14)
$container->resolve('Foo');
This will just return a new instance of Foo with a stdClass injected into the constructor.
But how do we enable the injector method detection?, (*15)
$container->enableInjecterDetection();
$container->resolve('Foo');
NOTE This feature (enableInjecterDetection()) requires PHP 5.4 or higher. In PHP 5.3 closure to object binding is not supported, which is crucial for this feature to work., (*16)
But this won' t work right now and throws a \DaGardner\DaContainer\Exceptions\ResolveException exception. Why?, (*17)
The container doesn' t know what to do with this LoggerInterface. Since the container doesn' t know which implementation to use you have to tell it the container!, (*18)
$container->bind('LoggerInterface', 'BasicLogger');
As you can see you can also bind an id to just a class name., (*19)
If a class requires an implementation of the LoggerInterface the container knows which implementation to use!, (*20)
The Container::enableInjecterDetection() takes as optional argument a blacklist (and the PHP_VERSION string, but you can ignore this!), (*21)
The exact display of the method is:, (*22)
\DaGardner\DaContainer\Container::enableInjecterDetection([array $blacklist = array() [, string $version = PHP_VERSION]])
The blacklist should (has to be) constructed like this:, (*23)
[
'setString',
'setArray',
'_CLASSES_' => [
'SomeClass' => [
'setLogger'
]
]
]
Strings in the main array are consired to be global and are ignored everytime., (*24)
The class specific blacklist is only checked if the object is an instance of this class. A blacklist for a class should go into the _CLASSES_ key., (*25)
The algorithm of the method detection is pretty simple and not that complex. But you can write your own very algorithm., (*26)
As of version 1.3 the detection algorithm lifes in it's own class. Your detector class just has to implement an interface:, (*27)
class MyDetector implements \DaGardner\DaContainer\InjectorDetection\DetectorInterface {
/**
* {@inheritdoc}
*/
public function detect(ReflectionMethod $method) { }
}
The detect(ReflectionMethod $method) gets the method of interest passed into and the task of this class is to
return true or false whether the given method is a injector method., (*28)
You can inject your detector this way: $container->setDetector(new MyDetector);. If you do not inject one the
SimpleDetector will get used., (*29)
Events
The IoC Container has it' s own simple event system, which can be used standalone or getting hooked into the main event dispatcher!, (*30)
$container->onResolving(function($object) {
// Do something
});