Dependency Injection Container


Dependency Injection Container

What is DI Container?

A dependency injection (DI) container can be defined as an object that knows how to instantiate and configure objects and all their dependent objects.

Lets take a look into an example to better understand how you can use DI Container to instantiate objects. We will use some pseudo Container class here, just so you can get the basic idea.

$container = new Container();

// Tell the container how he should instantiate the UserService class.
// This class depends upon UserRepository, so it has to be passed as 
// a parameter.
$container->bind('user_service', function () {
    return new UserService(new UserRepository);
});

// Getting user service out of the container
$userService = $container->get('user_service');

// We can now use $userService (which is intance of UserService class)
// and do anything we want with it without worrying about how it is 
//instantiated.

UserService class has only one dependency, so it is not a problem to instantiate it whenever we need it. However, imagine some class with 3-4 dependencies where each dependency has it's own dependencies. It will be a nightmare to instantiate such classes. That's where DI Container comes into play and make things a lot easier.

You can start learning more about Dependency Injection and DI Containers here: http://www.phptherightway.com/#containers

Pimple

Pimple is a small Dependency Injection Container for PHP, and since AS starves to simplicity and ease of use, it uses Pimple to make instantiating classes a breeze.

Here is an example how to use Pimple for our UserService from previous chapter:

$container = new Pimple\Container();

$container['user_service'] = function () {
    return new UserService(new UserRepository);
});

// Getting user service out of the container
$userService = $container['user_service'];

More about Pimple is available here.

Pimple in AS

All Advanced Security classes (starting from version 2.3) are being instantiated out of the container.

For example, if you want to instantiate ASLogin class, which has two dependencies (ASDatabase and ASPasswordHasher), can be instantianted like this:

$asLogin = $container['login'];

And it is bound to a container like this:

$container['login'] = $container->factory(function ($c) {
    return new ASLogin($c['db'], $c['hasher']);
});

AS provides one additional helper method app() that can be used to resolve some class out of the container anywhere inside the application. For example, if we want to resolve this ASLogin class, as in example above, we can do it by using app function like following:

$asLogin = app('login');

All container bindings are defined inside ASEngine/AS.php file, so you can check that file and learn more about how you can instantiate different AS classes out of the container.