What is dependency injection?

In a nutshell, dependency injection is a design pattern where external dependencies are “injected” into components rather than baked in.

If that made your eyes glaze over, think about it like this: imagine your friend asked you to drive him to the supermarket:

You would probably just hop in your car and take him:

But what if your friend asked you to drive him and his 5 friends to the supermarket, but your car only seats 4?

You would need a bigger car, right? Well, the good news is that since most cars implement the same interface (steering wheel, accelerator, brakes, etc.), you’re not only capable of driving your own car but many other cars as well. So if you had access to say, your mom’s minivan, you could complete the trip:

At the root of it, that’s what dependency injection is all about. Instead of you being stuck having to always use your car for your trips, you will be given the correct car to use based on the circumstances.

Bringing this back into software terminology, in the analogy above you (the driver) are a class and the car is your dependency. You depend on the car to drive your friend(s) to the supermarket. It doesn’t matter which car you use, so long as it’s familiar to you. Without dependency injection, the You class might look something like this:

Notice how you’ll always be using that particular instance of Car to complete the trip. With dependency injection however, the You class would look something like this:

Notice how now you don’t know (or care) what car you’ll be getting to complete your trip. The car is given to you by an outside entity via the constructor.

Ok great, so why should I care?

One reason is the one alluded to above. Dependency injection helps you create “loosely coupled” classes. What this means is that your classes will have less knowledge about their dependencies. This is a good thing. First, because it allows you to only expose functionality in your dependencies that your classes need (e.g. you don’t care what make or model or engine the car has, only that it drives and you’re capable of driving it). Second, because it lets you quickly and easily substitute out your dependencies (e.g. replacing the car with a minivan), which makes your code more flexible and also lets you swap out implementation without having to modify or recompile your dependent class.

Another reason is for unit testing. Dependency injection allows for something called “mocking”. What this means is that in your unit tests, you don’t actually have to inject concrete dependencies. Instead, you can inject “mock objects”, which are easy to create (via mocking frameworks) and define behavior for. This lets you test the behavior of your dependent class without having to worry about whether the dependencies are working as expected (you can test the dependencies in another unit test). This means your unit tests will be more in line with what unit tests are supposed to be: tests on individual units of an application (as opposed to tests on a unit and its dependencies and its dependencies dependencies, etc.).

Where can I learn more?

There’s been a lot written about dependency injection, but I think the wiki article covers it pretty well.

Once you’ve got that down, the next thing you’ll probably be interested in is Inversion of Control Containers. These containers make dependency injection a breeze by allowing you to configure default implementations to inject into your classes. Martin Fowler’s article on dependency injection covers this well.

Note: Yes, I did draw all the pictures using Paint and a laptop trackpad. No, I do not plan on selling my artwork anytime soon.

12 responses to Dependency Injection For Dummies

  1. brian said:

    I like your article. I know it’s more of an intro article, but I think it would be handy for newcomers to DI to show the Car class, as well as other classes implementing ICar! Maybe like… (some stuff cut out for brevity)

    public class Car
    {
    public void AddPassenger(Person p) { }
    public void Drive() { }
    }
    //add the interface (maybe rename to IVehicle?)
    public interface ICar
    {
    void AddPassenger(Person p);
    void Drive();
    }
    public class Car : ICar
    {
    public void AddPassenger(Person p) { }
    public void Drive() { }
    }
    //bigger auto, same interface
    public class Minivan : ICar
    {
    public void AddPassenger(Person p) { }
    public void Drive() { }
    }

    public class Foo
    {
    public void Bar()
    {
    //pass in any auto that implements ICar
    You y = new You(new Minivan());
    y.DriveToMarket(…);

    }
    }

  2. Rogerio said:

    But what exactly is an "external" dependency? How do I know if a dependency is internal or external?

    Assuming that "external" refers to implementation classes that do not belong to the application or library which uses them, then from my experience it would seem that nearly all dependencies are not "external".

    Another thing: it’s not correct to say that "dependency injection allows for mocking". Mocking can be done just as easily without the use of DI.

  3. Azizi Yazit said:

    with or without read your article, I will learn the dependency injection because we need to know it if we were Java developer. However, your article is really inspired me.

  4. Wow, what timing…I just finished an article this morning called "Dependency Injection 101" which I’m preparing to blog. I hope you don’t think I’m being a copy cat! ;)

  5. waggi said:

    Great post.

  6. Veera said:

    A Good way to explain the dependency injecttion concept.

  7. Perry said:

    EXCELLENT article. I’ve been looking for examples to explain to friends and co-workers that are having a hard time grasping the concept of DI.

    Very "Head First" approach! I think it’d be great if you turned this into a series on the SOLID principles.

  8. This is a good abstraction of the concept to something we can relate to in everyday life. This reminds me of a comparison I made of dependency injection to making a sandwich:

    http://earldouglas.com/node/14

  9. Chad Stewart said:

    Wow. Excellent pictures! I never realized I was doing this fancy Dependency Injection thing I’d heard so much about.

  10. Amgad said:

    Nice article, very detailed. I guess when you said for dummies you really meant it :)

  11. @Chad Stewart,

    It’s because the concept of DI is pretty obvious for any smart developer. I really don’t understand all that fuzz about it. It’s so simple and obvious,.

  12. Tejas Bhandari said:

    Really Nice Post…
    A very simple example to demonstrate Dependency Injection..
    Thank you!