Another dumb dependency injector

0.5.0 2014-03-22 02:54 UTC


Build Status

This library is a dependency injection container. It is largely an academic exercise to provide the following features:

  • Support both services (objects) and parameters (scalars, arrays).
  • Build services from configuration without using reflection.
    • Reflection is slow, but this slowness is widely considered to be acceptable for di containers as it is the only way to sanely dynamically instantiate objects.
    • PHP 5.6 will solve this issue with its support for argument unpacking (See RFC).
    • This library uses eval instead of reflection.
  • Require explicit definitions (No magic, no annotations, no reflection autoresolving).


A few notes:

  • Setting a service or parameter will overwrite any previous definition or retrieved service at the same id.
  • Resources are invalid and cannot be set on the container.
  • DI Configuration can be imported through the DefinitionImporter. In order to be considered a class definition and not just a static array, specific properties (such as class or parameters) must be prefixed with a +.
  • Class definitions imported through the DefinitionImporter will be wrapped in closures. Any closure set on the container will be called when the service is resolved. It is not currently possible to store and retrieve a closure from the container.
  • All services are singletons (factory functionality will be added later).

Adding services upon container instantiation

use Addi\Container;

$config = ['param1' => true, 'param2' => 'test-value'];
$container = new Container($config);

// This will print 'test-value'.
echo $container->get('param2');

Batch importing services after instantiation

use Addi\Container;

$config = ['param1' => true, 'param2' => 'test-value'];
$container = new Container;

// This will print 'test-value'.
echo $container->get('param2');

Setting services

use Addi\Container;
use stdClass;

$container = new Container;
$container->set('param1', true);
$container->set('param2', 'test-value');

$container->set('service1', function () {
    return 'test-value';
$container->set('service2', new stdClass);

// This will print 'test-value' because the closure will
// be resolved before being returned from the container.
echo $container->get('service1');

Setting a class definition with configuration

The DefinitionImporter allows you set all of your parameters and services in configuration files such as YAML, JSON, or even standard PHP arrays. Once parsed, simply pass the array to the importer.

You can also import multiple configurations with succesive calls to ->import() and services set previously will be overwritten if already set. It is recommended that all configuration importing is completed before resolving any services from the Container.

All configuration (class definitions only) set through the DefinitionImporter will be lazy loaded.

use Addi\Container;
use Addi\DefinitionFactory\EvalDefinitionFactory;
use Addi\DefinitionImporter;

$container = new Container;
$factory = new EvalDefinitionFactory($container);
$importer = new DefinitionImporter($container, $factory);

    'service1' => [
        '+class' => 'Foo\Bar',
        '+parameters' => [

// This will resolve to an instance of Foo\Bar.
$service = $container->get('service1');


  • Add setter injection
  • Support factory services
  • Add container freezing/validation/synthetic services
  • Support container dumping
  • Benchmark
  • Create Unpacker definition factory for PHP 5.6