# Dependency Injection Explicit definition of a class dependencies with the injection through the constructor or *getters*/*setters*. ```php 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](https://php-di.org/) 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](https://www.php.net/manual/en/intro.reflection.php) - 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 // 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 $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.