Introduction

At the place where I work, we have started developing a new project using all sorts of Agile/SCRUM/Xp methodologies, and we were actually lucky enough to have Martin Fowler's company: ThoughtWorks, come in and teach us a few things. One of these things was Dependency Injection. Now, there are already a number of articles here at CodeProject about DI, but after reading a few of them, I felt there was still room for another one, as I wanted to talk a little bit about what it is trying to solve, which is something that some of the other articles didn't seem to cover.

What IOCs Solve

Typically, when we write software, we are writing software that calls on service classes, not necessarily Web Services; what I mean are classes that provide some function when called. Consider the following code, where I am expecting to be able to use some sort of logging service and some sort of exception reporting service:

More often that not, if an object needs to gain access to a certain service, the actual object takes on the role of creating an instance of the service (as seen above) that the code needs. This can take many forms: it could be done in a constructor, or by holding a direct reference to a service object, or could even use some sort of service locator to provide an instance of a particular service object. What all these approaches are doing is holding references of service objects within the consuming object, which strongly ties the consuming object to the instance of the service objects, which may not be desirable, as the consumer now depends on the service objects.

What Dependency Injection does, is allow this dependency on service classes to be inverted, so they are no longer created in the consuming object.

DI can either use property or constructor parameters, which must be of the desired service types, and when the object that needs these service types is created, an implementation of the desired service type is automatically passed to the object being constructed by some external mechanism. Bingo, no more internal dependencies on service types within the consuming object.

Dependency Injection is more flexible than holding internal references, as it allows an alternative implementation of a given service to be created and literally injected into the object that requires the service type. The actual service implementation type may be configured in a config file, so one could easily swap out one service type implementation for another. Imagine a situation where you have written some software that needs to work with SQL Server and then your company decides you must also support Oracle; if we use DI and config files, we could configure the solution to hold either a Oracle service type or a SQL Server service type, and the code that utilises these services could work without being recompiled.

Another area where DI is especially useful is when using Mocks; you can use a Mock service type by simply setting the config file to point at a Mock implementation of some service. This is very useful. We have actually done just this at work, and it allows us a lot of flexibility with our Unit/Integration tests.

Obviously, with this level of configurability comes what is known as explosion of interfaces, so DI also has its own drawbacks. However, the benefits that DI can bring could easily outweigh the number of interfaces that you will wind up working with. Obviously, there should be a valid and just reason to use DI; it's worth having a think about though.

There are a few good DI implementations out there which allow the configuration of types to be done via config files/special attributes. Generally, these frameworks all offer DI under the umbrella name of IOC, which stands for "Inversion of control".

According to Wikipedia, IOC is:

"Inversion of Control, or IoC, is an abstract principle describing an aspect of some software architecture designs in which the flow of control of a system is inverted in comparison to the traditional architecture of software libraries."

Pretty much most (if not all) of the IOC frameworks out there simply act as containers for service types. You can think of the container as a special/clever dictionary that knows how to grab a service type and provide it when needed. The basic idea is that you have a container that knows about all the service types (or other types you wish to use with DI). The IOC framework will inject these service types when an object that requires one of these known/stored (in the container) service types need one.

In the remainder of this article, I will talk about how to do DI using some of the free frameworks out there, and at the end of the article, I will provide links to more DI/IOC frameworks that you may choose to investigate by yourself.

The Common Demo Code Example

The attached demo code contains three projects:

CastleWindsorIOC: Shows how to work with constructor DI and Generics support

UnityIOC: Shows how to work with constructor DI and Generics support

UnityIOCPropertyResolution: Shows how to work with property DI

Both the CastleWindsorIOC and the UnityIOC projects set out to demonstrate exactly the same problem. The problem that they are setting out to demonstrate are quite simple. There is a single interface called IMessageFormatter which has two implementations: DateTimeMessageFormatter and SimpleMessageFormatter, which can be used by providing the correct settings in the config file.

There is also an example of how to work with a IGenericFormatter<T> generic interface, where the implementation is done in a class called DummyObjectFormatter.

There is also a simple Form (Form1) object that requires a IMessageFormatter and a IGenericFormatter<DummyObject> implementation passed into the constructor in order to work correctly.

It can be seen that we simply create a custom Castle config section, and in that custom Castle section, we configure the container to tell it what types it should be able to resolve. This is done via a new component element per type that is required.

We can see that this config files has two types (one if commented out, which you could uncomment to try it out, but don't forget to comment the current one if you want to try the currently commented one) which are two different implementations of the same IMessageFormatter interface, thus effectively providing two different services, albeit very simple services, in this case.

Castle Windsor Container: Constructor Support

As you saw from the class diagram above, there is a IMessageFormatter interface that has two different implementations (SimpleMessageFormatter and DateTimeMessageFormatter). The config file that you just saw shows how to add these types to the Castle Windsor container.

So how do we go about using one of these types from the Castle Windsor container? Well, that's fairly simple. We just do something like this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using Castle.Windsor;
using Castle.Windsor.Configuration.Interpreters;
using Castle.Core.Resource;
namespace CastleWindsorIOC
{
staticclass Program
{
///<summary>/// The main entry point for the application.
///</summary> [STAThread]
staticvoid Main()
{
IWindsorContainer container =
new WindsorContainer(
new XmlInterpreter(new ConfigResource("castle")));
// use the Current Message Formatter (see the App.Config)var currentIMessageFormatter =
(IMessageFormatter)container.Resolve("CurrentFormatter");
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1(currentIMessageFormatter));
}
}
}

It can be seen from this example that we are firstly configuring the Castle Windsor container and then we are obtaining all the types we need from the container, and then constructing a new Form1 object and passing these container objects to the constructor of the Form1 object.

From here, we can see that the types that the Form1 object needs for its constructor have been resolved by the Castle Windsor container and supplied to the Form1 constructor. Cool.

So what happens when we run the app? We get a message formatted using the current (App.Config type that is used) IMessageFormatter interface implementation.

Castle Windsor Container: Generics Support

So that's cool, we now have DI working with constructor parameters using the Castle Windsor container. So what else can we do? Surely there is more. Well yeah, there is actually. We can use the DI with Generics. Here is an example of how to do this.

The demo code has an IGenericFormatter<T> interface which is declared like this:

And if we examine the constructor of a Form1 object that requires such a type to be provided, it should be pretty obvious that all we need to do is pass the container obtained generic object to the Form1 object's constructor.

Castle Windsor Container: Property Support

Is should be possible to not only inject constructor parameters but also use DI/IOC to inject property values. I had a go of this using the Castle Windsor container, but didn't get any where with it. I am sure it can be done, I just didn't manage it... But like I say, I think it is possible.

Unity Container

The basic idea behind using Unity is that you have a container that can be configured though code/config files, much the same as Castle Windsor. I think the best way to demonstrate this is by working through the same small example as we did with Castle Windsor above.

So let's do that.

Unity Container: Config

I like to work with a config file as it offers the greatest level of flexibility as we can literally alter the config file without the need to recompile the code.

It can be seen that we simply create a custom Unity config section (much the same as Castle Windsor), and in that custom Unity section, we configure the container to tell the container which types it will know about at runtime.

We can see that this config file has two types (one if commented out, which you could uncomment to try it out, but don't forget to comment the current one if you want to try the currently commented one) which are two different implementations of the same IMessageFormatter interface, thus effectively providing two different services, albeit very simple services, in this case. It should still demonstrate the idea.

Unity Container: Constructor Support

We are using the same example as the Castle Windsor, where we use the same IMessageFormatter interface and have two different implementations of this interface (SimpleMessageFormatter and DateTimeMessageFormatter) that we saw in the Castle Windsor example above. The config file that you just saw shows how to add these types to the Unity container.

So how do we go about using one of these types from the Unity container? Well, that's fairly simple. We just do something like this:

It can be seen from this example that we are firstly configuring the Unity container, and then we are obtaining all the types we need from the container and then constructing a new Form1 object and passing these container objects to the constructor of the Form1 object.

From here, we can see that the types that the Form1 object needs for its constructor have been resolved by the Unity container and supplied to the Form1 constructor. Cool.

So what happens when we run the app? Well, much the same as the Castle Windsor example; we get a message formatted using the current (App.Config type that is used) IMessageFormatter interface implementation.

Unity Container: Generics Support

So that's cool, we now have DI working with constructor parameters using the Unity container. What else can we do? Surely, there is more. Well yeah, there is actually. Much the same as Castle Windsor allowed us to work with Generics, so does Unity. Here is an example (again, using the same interfaces as the Castle Windsor example) of how to do this.

Here is what you need to do for the App.Config file to support Generics:

And if we examine the constructor of a Form1 object that requires such a type to be provided, it should be pretty obvious that all we need to do is pass the container obtained generic object to the Form1 object's constructor.

Unity Container: Property Support

I was a little luckier when working with Unity than I was with Castle, and managed to get it to work by injecting property values as well as constructor values. I am positive Castle Windsor does this also, I think I just missed a trick somewhere.

Anyway, what you need to do in Unity to get a DI property to work is simply mark the property up with a special Unity attribute, which is shown below.

Here is a simple program file to launch a simple form which has a single property that requires a type to be supplied by the Unity container:

If we examine what this looks like when running, we can see the CurrentFormatter got resolved just fine, by the Unity container.

Quick Round Up

I quite like both Unity and Castle Windsor; I spent a bit of time examining other frameworks such as those listed below, but I leant towards the two I talked about here. In my humble opinion, both Unity and Castle Windsor are excellent products that fill the IOC/DI gap nicely, so if you find you would like to try these out, I would recommend either of these.

Other Frameworks Worth a Mention

Spring .NET: A quite mature (but I found quite tricky to use) framework covering all sorts of cool stuff, such as: AOP/Persistence/IOC/DI, amongst other things.

Lin Fu: This is a framework that offers DynamicProxy/IOC amongst other things; this is by a very, very talented guy called Philip Laureano, and he has published all the source code right here at CodeProject. He is very, very smart, and his ideas are well worth a look.

That's it

That is all I have to say. I hope this article has helped you a little. If you liked it, could you please be kind enough to leave a vote or a message? Thanks.

So every part of this list is a big player in todays devarchitecture. Looking at code like Rob Connerys Storefront http://asp.net/mvc (scroll at the bottom) you'll notice a beautifully structured codelayout using Windsor. Todays devs and architects are evolving

my in box is already plagued by emails from another group I am in, I hardly have time to keep up with that I'm afraid. My interest really lies in UX type stuff though I do like forward thinking groups type stuff. So ill check the links you gave me from time to time.

Sacha Barber

Microsoft Visual C# MVP 2008

Codeproject MVP 2008

Your best friend is you.
I'm my best friend too. We share the same views, and hardly ever argue