Better your code with Dependency Injection

by Paweł Ogrodowczyk on 26th March 2013

Post image for Better your code with Dependency Injection

Dependency Injection – everybody’s doing it! It helps you write flexible, loosely coupled, reusable, testable and maintainable code. But fancy keywords aside, are you sure you know how to use it to reap all the benefits? Let’s have a look at a couple of tips on how you can use DI to help you write high quality code.

Always default to Constructor Injection

DI comes in many flavors, including:

  • Constructor Injection,
  • Property Injection (aka Setter Injection),
  • Interface Injection.

All of them are tasty, but Constructor Injection is by far the most delicious. Why? Because it makes your class’s required dependencies explicit and ensures that they’re always available to your service. It’s also really easy to implement and as a bonus it can make your code more testable.

Let’s have a look at a code sample:

public class Service : IService
{
    private readonly IDependency dependency;

    public Service(IDependency dependency)
    {
        if (dependency == null)
        {
            throw new ArgumentNullException("dependency");
        }

        this.dependency = dependency;
    }

    //Service implementation...
}

As you can see all of the dependencies of the Service class are explicitly stated in the class’s constructor and can be easily injected by our IoC container. Furthermore, having all of the dependencies in the constructor guarantees their availability to the service – there is no way to create an instance of Service without supplying something implementing IDependency. The null guards in the constructor’s code are an additional measure to ensure that the dependencies of the Service class are always satisfied.

Constructor Injection has another advantage – it improves testability. In our unit tests we can now simply create a mock object for IDependency, construct an instance of the Service class and test it without worrying about what the actual implementation of IDependency does.

Remember your three R’s

The three R’s are:

  • Register,
  • Resolve,
  • Release.

Also known as the Three Calls Pattern, the mnemonic describes the sequence of mandatory steps that accompany the usage of an IoC container. Here’s the kicker: each of those steps should be performed only once in the entire application. Impossible? Most frameworks actually enable you to do that! Let’s examine the three R’s rule based on the example of an ASP.NET MVC application which uses Castle Windsor as an IoC container.

Register is the first step in the sequence. This is the phase in which you create an instance of the IoC container and register your components with it. Registration should be performed in the application’s entry point. In the case of our MVC application the ideal place for this is the Application_Start method in the Global.asax file.

protected void Application_Start()
{
    var container = new WindsorContainer();
    //Castle Windsor uses Installers for component registrations
    container.Install(new MyComponentsInstaller());
}

The next step, Resolve, is the place where you construct your object graph. This should be done in your application’s Composition Root. A good candidate for a Composition Root in an MVC application is the place where our controllers are created – a controller factory. Our controller factory class should inherit from DefaultControllerFactory and override the GetControllerInstance method.

protected override IController GetControllerInstance(
    RequestContext requestContext, Type controllerType)
{
    return (IController)this.container.Resolve(controllerType);
}

How did the container get there? It was passed as a parameter the controller factory’s constructor.

Release is the third and final step and coincidentally the one which is most frequently forgotten. In this phase, components that are no longer needed should be decommissioned by the container. In an MVC application this can be done in the ReleaseController method of our, already implemented, custom controller factory.

public override void ReleaseController(IController controller)
{
    this.container.Release(controller);
}

Let’s sum up the whole example. Register? Check! Resolve? Check! Release? Check! Each invoked only once? Check! Having a single instance of an IoC container in the application and only three places where it’s used sure sounds like maintainability heaven, doesn’t it?

Don’t use the IoC container as a Service Locator

The infamous Service Locator is widely considered as an anti-pattern. That goes double for trying to use an IoC container as one. Why? Because it makes you lose most of the benefits of DI and more importantly it goes against the inversion of control paradigm.

An IoC container is used as a Service Locator when the code contains many calls like this:

public class Service
{
    //somewhere in a method, constructor or field initializer
    IDependency dependency = ServiceLocator.Resolve<IDependency>();
}

In the code sample above ServiceLocator denotes some kind of wrapper, static or not, on the IoC container. That’s bad due to several reasons. First of all, it introduces a hard dependency on ServiceLocator. Now, everywhere we use the Service class we have to drag the locator along with it.

Secondly, the dependency is implicit and even if we make it explicit (for example by making ServiceLocator, or even its abstraction, a constructor parameter), the dependencies the Service Locator provides will remain implicit.

Thirdly, how are we going to test our service? It looks like we have to use ServiceLocator in our tests. This hurts our testability.

My suggestion is: save yourself the trouble, switch to Constructor Injection, follow the three R’s rule and make your container transparent to the application you’re writing.

Use convention-based registration to your advantage

DI containers usually support three forms of component registration:

  • XML-based,
  • Code-based,
  • Convention-based.

The first two options enable you to explicitly register components one by one. One of them uses XML files and the the other uses code. But the real power lies within the third form, which allows you to establish rules used for locating your application’s components.

Let’s have a look at a sample showing how we can register components using Castle Windsor’s convention-based registration API:

public void Install(IWindsorContainer container, IConfigurationStore store)
{
    container.Register(
        Classes.FromAssemblyContaining<IService>()
            .Where(type => type.Name.EndsWith("Service"))
            .WithServiceDefaultInterfaces()
            .LifestyleTransient());
}

The code establishes a convention that can be summed up as “Register all types which names end with ‘Service’ and which are defined in the same assembly as IService. Use the default interface and a transient lifestyle for the types”. I won’t explain the Windsor-specific jargon but this simple example should give you an idea of how powerful this API is.

What are the advantages of such an approach? Well, the obvious one is that you don’t have to repeatedly write registration code for each new type you introduce, you only need to make sure to follow conventions. This makes the registration code more compact and DRY!

Furthermore, you get the benefits of Convention over Configuration, namely: code consistency, reduced complexity and increased developer productivity.

Additionally, some advanced convention code can even give you the ability to interchange components during runtime. How cool is that?

Dependency Injection is a really powerful mechanism which can greatly improve code quality in more than one way. Has DI helped you achieve that goal? Do you have any other tips on using IoC containers? Make sure to leave a comment.

  • Sławek Aleksiuk

    Great article, reads well! I’d like to point out some side remark also. You strongly advocate using Constructor Injection. I agree this is a good approach. But one must not forget about using it in unit tests too. Let’s suppose, that we have some class constructor with two parameters. We create a unit test to test something in this class, so in test method we explicitly create instance of this class. Of course, we have to pass two objects for parameters. We use some mock library to create mock objects and we pass them to the constructor. Let’s suppose we have 50 such methods. What will happen, when we add a new parameter to the constructor? Well, since we use DI, whole application will be still correct… apart from unit tests. You will have to modify your unit tests, even though you don’t actually change anything in them. That’s not good. Of course, you can refactor this creation code to some Setup method, store your instance and mocks in properties, but still, changes in the constructor will force you to update your test code. The solution is to use some mock library combined with… DI library. :) Take for example AutoMoq (on Nuget at http://nuget.org/packages/AutoMoq/). To use this approach, instead of explicitly constructing the instance, you resolve it, which automatically creates and passes mock objects to any parameter in the constructor. You then may setup these mocks, validate them, etc. And if you change the constructor, it doesn’t bother you – an implicit mock object will be automatically passed to the constructor, so this doesn’t require any change your existing tests. Perfect!

  • Paweł Ogrodowczyk

    Thanks for the comment!

    Auto-mocking containers are great! Still, I find it a good habit to make unit tests as maintainable as possible without them. That’s why I tend to restrict the call to the SUTs constructor to a single place in a test fixture.