Dependency Injection Containers

This article is a continuation of “Understanding Dependency Injection”. We will create a simple D.I.C. and illustrate how it works.

Miguel Loureiro
Coding skills
Published in
3 min readMar 29, 2014

--

Dependency Injection Containers

This article is a continuation of “Understanding Dependency Injection”. We will create a simple D.I.C and illustrate how it works.

Let’s remember the problem we face when we start using Dependency Injection.

While decoupling more and more your code, it gets hard to manage all the dependencies and you’ll have lots of code just for injecting the dependencies, in our example if we want to create an instance of OccurrenceManager we need to do this.

$db = new DatabaseConnection($someConfig);
$validator = new OccurrenceValidator();
$response = new XMLResponse();
$manager = new OccurrenceManager($db, $validator, $response);

Yep, the code is now more modular, but it is also much more complex to manage it, because you now need to remember all the dependencies the OccurrenceManager need.

Dependency Injection Containers

Think of a D.I.C. as a box available in all your application scope where you can store and request for dependencies. Simple as that !

Let’s create a basic one.

class DIContainer {    /**
* array where we store our dependencies
**/
protected static $registry = [];
/**
* register is used to store resolvers.
* @param string $id how you'll call the dependency
* @param object $resolve Closure that creates the instance
* @return void
*/
public static function register($id, Closure $resolve) {
static::$registry[$id] = $resolve;
}
/**
* Create the instance
* @param string $id the id to call
* @return someObject
*/
public static function resolve($id) {
if( isset(static::$registry[$id]) )
{
$id = static::$registry[$id];
return $id();
}
throw new Exception('Nothing registered with id ' . $id); }
}

Don’t let this code scare you. It’s actually pretty easy to understand it if we see how it works.

So, somewhere where you initialize your application, you should create an instance of your D.I.C. and then you can start storing your dependencies in your container like this.

Registering dependencies

DIContainer::register('OccurrenceManager', function(){    $db = new DatabaseConnection($someConfig);
$validator = new OccurrenceValidator();
$response = new XMLResponse();
$manager = new OccurrenceManager($db, $validator, $response);
return $manager;
});

Remember in the DIContainer class our register method ? We are telling that we want to access our dependency by calling ‘OccurrenceManager’ and passing a lamba that tells how we create our dependency.

Using dependencies

$OccurrenceManager = DIContainer::resolve('OccurrenceManager');

See ? We now don’t need to remember what dependencies we need to create a new OccurrenceManager instance.

There are a lot of benefits by using a D.I.C., just by this example you can notice that you’ll have no need to remember all the dependencies some instantiations need, but you’ll also notice that you will create no more unnecessary objects because you’ll always have a reference to whatever you need in your container!

If you want the code from this article you can check this GitHub repository, I will be making some improvements on it.

Also, note there are a bunch of excellent D.I.C. already implemented for the majority of the languages, so don’t do it yourself ☺ this article is just to illustrate how they work!

--

--

Miguel Loureiro
Coding skills

Product & Technology, entrepreneur, early-stage investor and advisor, occasional blogger