Dependency Injection and Inversion of Control are not rocket surgery
Posted by Scott
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.
public class MyClass
{
private DataTableReader _reader;
public MyClass()
{
_reader = new DataTableReader(new DataTable());
}
private void DoStuffWithTheReader()
{
while (_reader.Read())
{
//do fun stuff with the reader.
}
}
}
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?
public class MyClass
{
private DataTableReader _reader;
public MyClass(DataTableReader dataTableReader)
{
_reader = dataTableReader;
}
private void DoStuffWithTheReader()
{
while (_reader.Read())
{
//do fun stuff with the reader.
}
}
}
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?

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.
public class MyClass
{
private IDataReader _reader;
public MyClass(IDataReader dataTableReader)
{
_reader = dataTableReader;
}
private void DoStuffWithTheReader()
{
while (_reader.Read())
{
//do fun stuff with the reader.
}
}
}
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.
class MyClass():
def __init__(self, dataTableReader):
self._reader = dataTableReader
def DoStuffWithTheReader(self):
while(self._reader.Read()):
#Do Fun Stuff with the reader.
print(self._reader.item)
Ad
.NET HTTP Abstractions group
|
|
| Subscribe to .NET HTTP Abstractions |
| Visit this group |
Tags
O’Reilly Blogger Review Program
Books I’ve worked on
Contributors
Links
Herding Code Podcast
- Herding Code 166: Tomasz Janczuk on Edge.js 5/16/2013
- Herding Code 165: Mark Seemann on AutoFixture and Unit Testing 4/30/2013
- Herding Code 164: OWIN and Katana with Louis DeJardin 4/22/2013
- Herding Code 163: Sticker Tales and Building Windows Store apps with Damien Guard and Robert Sweeney 4/10/2013
- Herding Code 162: Whacha doin, Goodbye Google Reader, scriptcs and Lightning Round! 3/25/2013


