Skip to content

Dependency Injection

Explicit definition of a class dependencies with the injection through the constructor or getters/setters.

PHP
1
2
3
4
5
6
7
class Foo
{
    public function __construct(PDO $pdo)  // depends on PDO
    {
        $this->pdo = $pdo;
    }
}

Dependency Injection Container

The Dependency Injection Container (DIC) allow to archive all the dependencies in a single Container class. Some offer automatic resolution of the dependencies.

PHP-DI

The dependency injection container for humans. Installation: composer require php-di/php-di

  • Autowire functionality: the ability of the container to create and inject the dependency automatically.
  • Use of Reflection
  • Configuration of the container through annotations & PHP code.
PHP
class Foo
{
    private $bar;
    public function __construct(Bar $bar)  // depends on Bar
    {
        $this->bar = $bar;
    }
}

class Bar{}

$container = new DI\Container();  // DI Container
$foo = $container->get('Foo');  // get instance of Foo (automatic DI of Bar)

DIC Configuration

PHP
1
2
3
4
5
6
7
8
// Foo.php
class Foo
{
    public function __construct(PDO $pdo)  // depends on PDO
    {
        $this->pdo = $pdo;
    }
}
PHP
// config.php
use Psr\Container\ContainerInterface;

// config "primitive" dependencies (dependency => construct & return)
return [
    'dsn' => 'sqlite:db.sq3',
    PDO::class => function(ContainerInterface $c) {
        return new PDO($c->get('dsn'));
    },

    ...
];
PHP
1
2
3
4
$builder = new \DI\ContainerBuilder();
$builder->addDefinitions("config.php");  // load config
$container = $builder->build();  // construct container
$cart = $container->get(Foo::class);  // Instantiate & Inject

Note: get("className") requires the explicit definition of className in the config file. get(ClassName::class) does not.