The religion of dependency injection


A quick way to explain a set of differing opinions is to label it as “a religious argument”.  In a post about using MEF on NerdDinner, Scott Hanselman showed an example on using poor man’s DI versus regular DI.  Now, the post wasn’t about that topic, but more on how to integrate MEF with ASP.NET MVC.  I do get rather annoyed at comments like this however (emphasis mine):

The second constructor takes an IDinnerRepository, allowing us to make different implementations, but the default constructor says, “well, here’s a concrete implementation if you don’t give one.” It’s a slippery slope and by adding the default implementation I get to sidestep using dependency injection while making the controller testable, but I’ve tied my controller down with a direct dependency to the DinnersController. This is sometimes called “Poor Man’s IoC” and many would say that this is a very poor man. That’s a religious argument, but Hammett takes a stand by removing the default constructor.

I see a religious argument is an argument whose opposite positions aren’t based in facts, but opinions.  It’s reasoning based on assumptions that are grounded in either faith, ignorance or a matter of opinion.

Something like poor man’s DI versus actual DI is different.  Let’s compare the code.  First, poor man’s DI:

public class DinnersController
{
    private readonly IDinnerRepository dinnerRepository;

    public DinnersController() : this(new DinnerRepository())
    {
    }

    public DinnersController(IDinnerRepository repository)
    {
        dinnerRepository = repository;
    }

Now, regular DI:

public class DinnersController
{
    private readonly IDinnerRepository dinnerRepository;

    public DinnersController(IDinnerRepository repository)
    {
        dinnerRepository = repository;
    }

In comparison, the poor man’s DI example:

  • Has more code
  • Is coupled to a specific implementation
  • Decides its component’s lifecycle

This isn’t just in the controller, every component used must use this technique.  Anything that DinnerRepository uses also would have to employ this technique, as we’re using the no-argument constructor for DinnerRepository.

I don’t know about you, but if I can write less code and gain the benefits of looser coupling and externalizing component lifecycle, that’s a win.

Let’s review.

Poor man’s DI: more code, more coupled, no flexibility

Regular DI: less code, less coupled, high flexibility

It was a failure in teaching dependency injection that the argument was made based on testability.  It only helps those already doing TDD to shape design, rather than just writing tests.

Instead, DI is about creating highly flexible components, both in lifecycle and component selection.  DI removes component resolution responsibilities from classes, therefore removing code.  And less code is ALWAYS a good thing.

Dependency Injection in ASP.NET MVC: Views