Introduction
There are many good tutorials about Dependency Injection (DI) out there (see links below) so i won’t bother you with yet another tutorial. Instead I will try to explain why DI is useful.
Dependency Injection is an evolution of the Factory pattern and can be done by hand or using a framework. It is basically an automated way to initialise a graph of objects. Say that you have a class with the following structure:
class Run
{
public GeneralSettings Settings;
public FitnessFunction Fitness;
public FunctionSet Functions;
}
Everytime you need to initialise an object of this type you need to write something like:
Run run = new Run();
run. Settings = new GeneralSettings();
run. Fitness = new FitnessFunction ();
run. Functions = new FunctionSet ();
If you use a Dependency Injection framework this code can be replaced by configuration either in an XML file or in code in a central location. So every time you need a Job object you write instead:
Run run = (Run)Context.Get(“MyRunImplementationV5.0″);
And the framework will give you a brand new object with all its children initialised and ready for use. You may say that you might as well use the Factory pattern instead where you might right code like this:
Run run = Run.Get();
This is absolutely valid, but you would have to write the factory yourself. That may not be a big deal, so, for the sake of the argument let’s change our class to:
class Run
{
public IRunInformation Settings;
public IRunInformation Fitness;
public IRunInformation FunctionSet;
}
This is exactly the same class but now we have an interface that exposes Run Information in a neutral fashion. We can say that our implementations are decoupled from the Run implementation, or can we? Assuming that GeneralSettings, FitnessFunction and FunctionSet implement IRunInformation, our code would have not changed much. If we used the Factory pattern our factory method could be:
public static Job Get()
{
Run run = new Run();
run. Settings = new GeneralSettings();
run. Fitness = new FitnessFunction ();
run. FunctionSet = new FunctionSet ();
return run;
}
So, if we change one of the implementers we have to recompile our Job class. There goes our decoupling… On the other hand, if we were using Spring.Net then we would still write:
Run run = (Run)Context.Get(“MyRunImplementationV5.0″);
To create new objects and we would describe the Run’s bindings in a configuration file:
</objects>
When the day comes to replace V5 with V6, you change the configuration file and that’s it (might be a good idea to run all those unit tests before releasing it to production…).
Another scenario where DI is useful is when you are using mocks for testing. It is as close as it gets to plug and play testing.
Videos, Tutorials and Documentation
This is an interesting video by a guy that created a DI framework for Java (Guice). It is worth watching the first 15-20 minutes where he explains why DI is useful and compares several approaches to the problem using code examples. The explanation is language neutral:
http://crazybob.org/2007/06/introduction-to-guice-video-redux.html
Inversion of Control is a more generic term for DI. This article explains it all in very good detail and from an authoritative source:
http://martinfowler.com/articles/injection.html
It is always interesting to look at both sides of the fence. This is a good article questioning the use of DI:
http://scruffylookingcatherder.com/archive/2007/08/07/dependency-injection.aspx
And this is a response to the article above which eventually reaches some common ground. Read the comments for the whole story:
http://kohari.org/2007/08/15/defending-dependency-injection/#comment-950
Frameworks
Spring.NET
Probably the largest and more out reaching of the DI frameworks. Spring goes beyond DI and covers several other interesting grounds like AOP. It started life in the Java world and may be the better tested and supported of all. It is open source and there is a company behind it (Interface 21) which survives on training and consultancy:
http://www.springframework.net/
http://www.springframework.net/examples.html
http://www.springframework.net/docs/1.1-RC1/reference/html/quickstarts.html
Ninject
Ninject seems to be a very good candidate if the only thing you need for your project is DI. I haven’t tested it but the author seems quite knowledgeable. You can decide for yourself in his blog:
http://kohari.org/
The main difference between Ninject and Spring is that Ninject uses code instead of XML files for the injection. It is also similar to Guice in that it uses a “fluent interface” which is a fancy name for code like this: Bind<IWeapon>().To<Sword>(); Another difference is that Ninject can be configured to use reflection or not and so can be much faster that Spring in some cases (the documentation gives more details).
This is the site where you will find a very good tutorial showing the same code with and without Ninject.
Yet another introductory article about NInject.
Unity
Unity is Microsoft’s Patterns and Practices response to the problem. It is tail chasing all the other older frameworks but with one very important advantage: it ships with PRISM. This may be the catalist to its adoption. There is a very good Unity tutorial which itself is an introduction to Dependency Injection:
Rough Notes on Unity
Final Notes
There are several discussions raging out there over which is the better way. You will have to make up your own mind and choose based on the breadth of your project. The links above cover the pros and cons of DI. As everything else, DI is not a silver bullet but a tool. I know I missed several very important frameworks (Castle comes to mind). They will be added in a future installment.
Nice article, and thanks for your praise for Ninject. :)
“Run run = new Run();
run. Settings = new GeneralSettings();
run. Fitness = new FitnessFunction ();
run. FunctionSet = new FunctionSet ();
If you use a Dependency Injection framework this code can be replaced by configuration either in an XML file or in code in a central location. ”
This makes no sense. I suppose by “central location” you mean someplace other than the server or the client? What about in the runtime classpath?
Oh and, is the motivation to change the XML later? Won’t this break the code that expects the fields to be properly defined? What is really gained by doing this?
A Factory would be better, typesafe, and browsable by the IDE.
Hi,
In the example you extracted, whenever you create a run you need to create three child objects which themselves might have other children. You usually do that in a Factory class to avoid repetition. A Dependency Injection (DI) framework takes you to the next level which is a Factory that is configurable and that works with any type you throw at it (within reason). Using DI will save you from coding the Factory.
By central location I mean a single location. Granted that a Factory is also a central location. This comment is directed at those developers that don’t use the Factory pattern.
I agree that changes to the DI configuration files in live systems may not very common. Having said that I use it all the time during development to swap the “real” data access layer with a mocked out one which is faster because it reads local text files instead of connecting to a database or calling webservices. This is very useful when you are working offsite through a VPN or completely disconnected. It is also predictable since the data is hard coded. With a DI framework this change is a one liner and no code paths (outside the data layer) are changed.
Finally, if you have the requirement for a typesafe configuration most DI frameworks can be configured using code instead of XML which, I agree, is not typesafe. This burden has been reduced with the introduction of automatic configuration in the latest versions of the DI frameworks.
Thanks for your thoughts,
cfn
“Using DI will save you from coding the Factory.”
Won’t you have to code the xml configuration file instead?
which is not type-safe, is a language of it’s own, not IDE friendly, i.e. no definition tracing, no hints etc, will break at runtime if its wrong, you lose all the benefits of an IDE.
I prefer to test with a test database anyway, just change the connection string, very often its the data from production that causes errors, not data from a mock object.
To each their own (looking at you username…) but you can indeed have intellisense with XML using XML Schemas or DTDs and it works with Visual Studio. Not sure about other IDEs though. I guess the best thing about using a DI framework is that all the configuration is in a single place and can be smart in some ways. These days you can create the configuration in XML or code using fluent interfaces and such.
Hi, wee fixup in the example:-
run.Functions = new FunctionSet(); // instead of run.FunctionSet = …
thanks
Andy
Good catch, fixed, thanks!