Posted by Kevin Pang on 11/7/2009 | Comment Comments (17)

The goal of this series is to introduce programming patterns and practices to developers who have little to no familiarity with them. This series does not intend to dive into the intricacies of each pattern / practice, but to give a brief overview that will (hopefully) inspire developers to learn more about them.

What is it?

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:

Now, 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.

Enjoyed this post? Share it with others!

Comments

trackback
DotNetKicks.com on 11/7/2009 1:13 PM Trackback from DotNetKicks.com

Dependency Injection For Dummies
brian
brian on 11/7/2009 5:56 PM 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(...);

        }
    }
Rogerio
Rogerio on 11/7/2009 7:28 PM 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.
Azizi Yazit
Azizi Yazit on 11/8/2009 7:43 AM 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.
pingback
jasper22.wordpress.com on 11/9/2009 12:38 AM Pingback from jasper22.wordpress.com

Dependency Injection For Dummies « Jasper Blog
Billy McCafferty
Billy McCafferty on 11/9/2009 1:01 PM 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! ;)
trackback
Billy McCafferty on 11/9/2009 4:31 PM Trackback from Billy McCafferty

Dependency Injection 101
waggi
waggi on 11/9/2009 5:21 PM Great post.
Veera
Veera on 11/9/2009 9:28 PM A Good way to explain the dependency injecttion concept.
pingback
blog.cwa.me.uk on 11/10/2009 12:36 AM Pingback from blog.cwa.me.uk

Reflective Perspective - Chris Alcock  » The Morning Brew #474
pingback
pabloidz.wordpress.com on 11/10/2009 4:05 AM Pingback from pabloidz.wordpress.com

links for 2009-11-10 « pabloidz
Perry
Perry on 11/10/2009 5:06 AM 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.
James Douglas
James Douglas on 11/10/2009 7:44 AM 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
Chad Stewart
Chad Stewart on 11/10/2009 9:02 AM Wow. Excellent pictures! I never realized I was doing this fancy Dependency Injection thing I'd heard so much about.
pingback
gryphin.be on 11/22/2009 12:04 PM Pingback from gryphin.be

links for 2009-11-22 | The Gryphin Experience
Amgad
Amgad on 11/25/2009 2:53 AM Nice article, very detailed. I guess when you said for dummies you really meant it Smile
Mike Borozdin
Mike Borozdin on 11/26/2009 3:41 PM @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,.
Comments are closed