Skip to content

Dependency Injection and Inversion of Control are not rocket surgery

I see a lot of people talking about how “advanced” techniques like dependency injection and inversion of control are and how their team won’t understand either technique.

 

Folks, this isn’t hard. In fact, both of these things are so simple I simply call it “using the programming language”.

 

Let’s look at dependency injection.

C#:
  1. public class MyClass
  2.     {
  3.         private DataTableReader _reader;
  4.         public MyClass()
  5.         {
  6.             _reader = new DataTableReader(new DataTable());
  7.         }
  8.         private void DoStuffWithTheReader()
  9.         {
  10.             while (_reader.Read())
  11.             {
  12.                 //do fun stuff with the reader.
  13.             }
  14.         }
  15.     }

See the reader variable? That's a dependency. You have to have it in there to do fun things later on. But we have to create it ourselves, which is one more thing that we have to do in our class constructor. In reality we also have to populate the DataTable. So what if we make the reader variable constructor parameter so that another class can do the work of creating the DataTable and the reader?

C#:
  1. public class MyClass
  2.     {
  3.         private DataTableReader _reader;
  4.         public MyClass(DataTableReader dataTableReader)
  5.         {
  6.             _reader = dataTableReader;
  7.         }
  8.         private void DoStuffWithTheReader()
  9.         {
  10.             while (_reader.Read())
  11.             {
  12.                 //do fun stuff with the reader.
  13.             }
  14.         }
  15.     }

There, that's better. Now our class doesn't have to worry about creating the reader and the DataTable. This, in a nutshell, is dependency injection. It's not very complicated is it? We've made our class construction a little simpler and if we want to unit test this, we don't have to do any complicated mocking, we can just new up our own DataTableReader instance and populate it with whatever test data we want. If you run into any funny looking data in the DoStuffWithTheReader method, you know that you don't have to look in this class at all to see where the funny data is coming from, only in whatever method is creating this class and passing in the DataTableReader.

Now is there anyone who thinks that developers on their team would have trouble understanding passing in a parameter? Should they really be a developer if they do?
Honestly, it's not that hard.

Ok, so let's look at inversion of control. The original definition of inversion of control I read was by Martin Fowler:

There's a big difference now in the flow of control between these programs - in particular the control of when the process_name and process_quest methods are called. In the command line form I control when these methods are called, but in the window example I don't. Instead I hand control over to the windowing system (with the Tk.mainloop command). It then decides when to call my methods, based on the bindings I made when creating the form. The control is inverted - it calls me rather me calling the framework. This phenomenon is Inversion of Control (also known as the Hollywood Principle - "Don't call us, we'll call you").

If you look at the previous example, you'll see that we have already inverted the control a bit just by using dependency injection. But the class still has a degree of control over WHAT concrete object is created, in this case a DataTableReader. What if we need to switch over to a SqlDataReader or an OleDbDataReader? Well, we could create three other classes that all take the specific type of data reader we might want to use. But that's a bad idea, you end up with the same logic spread all over the place. Instead we can use the IDataReader interface that all three classes implement.

C#:
  1. public class MyClass
  2.     {
  3.         private IDataReader _reader;
  4.  
  5.         public MyClass(IDataReader dataTableReader)
  6.         {
  7.             _reader = dataTableReader;
  8.         }
  9.         private void DoStuffWithTheReader()
  10.         {
  11.             while (_reader.Read())
  12.             {
  13.                 //do fun stuff with the reader.
  14.             }
  15.         }
  16.     }

Now our class not only doesn't have to worry about creating the DataTableReader, it doesn't even really care if it gets a DataTableReader at all. All it cares about is that the reader is referencing something that implements the IDataReader interface. This is a type of inversion of control. Most of the time people get confused between inversion of control and a container that enables inversion of control and dependency injection (like Ninject, StructureMap or Unity). You don't have to use a container to utilize these two techniques, it just makes it a little easier.

update:Also check out this great post "It’s all about the delivery"

update: I mistakingly thought it was hard to do D.I. in Python due to the inheritance mechanism in Python. Turns out, it's just as easy.

PYTHON:
  1. class MyClass():
  2.  
  3.     def __init__(self, dataTableReader):
  4.         self._reader = dataTableReader
  5.        
  6.     def DoStuffWithTheReader(self):
  7.         while(self._reader.Read()):
  8.             #Do Fun Stuff with the reader.
  9.             print(self._reader.item)

Share and Enjoy:
  • del.icio.us
  • DotNetKicks
  • DZone
  • Reddit
  • Digg
  • StumbleUpon
  • LinkedIn
  • Facebook
  • FriendFeed
  • HackerNews
  • Netvibes
  • Posterous
  • Tumblr
  • Twitter

6 Comments

  1. “Rocket surgery” LOL

    Posted on 03-Nov-09 at 2:02 pm | Permalink
  2. Wim Hollebrandse

    Dependency injection really is something that enables inversion of control. It doesn’t have to be the case. In your reader example IoC isn’t very clear at all.
    In my opinion IoC is more about having a container that really controls a fairly granular set of methods defined on the dependency interface definition but the container wraps its own logic, logging, and process of executing the interface methods.

    Good and sensible post though – you can easily roll your own specific IoC container, it’s just that some of the abstract factory and configuration aspects are mostly taken care of when using an existing IoC framework.

    Posted on 03-Nov-09 at 2:15 pm | Permalink
  3. Wim: Yeah, I struggled a bit to come up with a good example of IoC. I finally just went with the interface injection. I supposed that delegate event handlers would have been another good example, one that might have turned on the light bulb for a lot of people. “Oh, I’m already using IoC and I didn’t even know it”.

    Posted on 03-Nov-09 at 2:28 pm | Permalink
  4. In a word – “Quality!”

    It’s posts like these that are driving home everyday something that we already know: these concepts are not tough to understand and use, it is the incessant resistance to change causing problems.

    The more of these great 1-pagers we have in evidence, the more I get to point out to those whining about “if it ain’t broke…blah” – that simple changes like this to future code at the very least will pay back dividends that they cannot yet fathom.

    That’s the real problem – the not being able to “fathom the benefits” part.

    Great post, keep ‘em coming
    Rob G

    Posted on 03-Nov-09 at 2:38 pm | Permalink
  5. That’s probably the best description of these concepts I’ve seen.

    I have to be honest, I was fairly confused by DI and IoC the first time I saw them. I wish I’d seen an article like this right at the start – it would have made things a lot easier.

    Thanks, I’ll be passing this link on.

    Posted on 03-Nov-09 at 4:51 pm | Permalink
  6. Great example. I have bookmarked this and will use it to show my colleagues just how simple DI and IOC are.

    Posted on 05-Nov-09 at 2:54 am | Permalink

4 Trackbacks/Pingbacks

  1. uberVU - social comments on 03-Nov-09 at 2:26 pm

    Social comments and analytics for this post…

    This post was mentioned on Twitter by lazycoder: [posted]Dependency Injection and Inversion of Control are not rocket surgery http://bit.ly/1AjGZN...

  2. [...] Dependency Injection and Inversion of Control are not rocket surgery – Scott Koon shows how the techniques of Dependency Injection and Inversion of control are not as complicated as may developers believe, looking at definitions of the techniques and showing simple examples of both. [...]

  3. [...] Dependency Injection and Inversion of Control are not rocket surgery (Scott Koon) [...]

  4. [...] This post was mentioned on Twitter by Scott Koon, Ryan Farley, Jungchan Hsieh, Patrick Veverka, Doug Philips and others. Doug Philips said: RT @lazycoder: [posted]Dependency Injection and Inversion of Control are not rocket surgery http://bit.ly/1AjGZN [...]

Post a Comment

Your email is never published nor shared. Required fields are marked *
*
*

Get Adobe Flash playerPlugin by wpburn.com wordpress themes