Monday, November 15, 2010

Dependency Injection

Introduction

Dependency Injection (DI) is a design pattern which allows us to "inject" the concrete object into a class instead of having this initialization within the class itself.
One common way to achive similar result is using "Factory Method" design pattern.
"Factory Method" is a method, responsible for creating and returning of an instance of a class.
Usually a variable is passed to the "Factory" method to signalize which specific subclass should be returned.
The major drawbacks of the "Factory Method" are:
1. The method implementation is too specific and therefore cannot be used across other applications.
2. The creation options are hardcoded into "Factory" implementation, which means that all dependencies are known at compile time and cannot be dynamically extented without re-compiling.
3. The class which calls "Factory" method should know which subclass to create (sounds like dependency itself).

Just to make it clear: I'm not saying that using factories is bad. There are many applications in which using factories is valuable and sufficient, but if you need more flexible solution, that's when DI enters the picture.

Dependency Injection

DI is implemented by using so-called containers - configurable components that host the abstraction, create the concrete instance variables and inject it into appropriate classes.
There are many DI providers available on the market, here is the partial list:


In the following example we will use the Unity 2.0 components which is part of Enterprise Library 5.0.

The Example

Lets start with creating of a simple interface IDatabase containing a single method "Save"

interface IDataBase
{
void Save();
}

Now, we'll add two classes that implement IDatabase:

class OracleDatabase : IDataBase
{
public OracleDatabase()
{
Console.WriteLine("OracleDatabase Constructor");
}

public void Save()
{
Console.WriteLine("Save with Oracle");
}
}

And

public class SqlDatabase : IDataBase
{
public SqlDatabase()
{
Console.WriteLine("SqlDatabase Constructor");
}

public void Save()
{
Console.WriteLine("Save with SQL Server");
}
}

The "Customer" class will be the main class which uses the services of IDatabase component:

class Customer
{
private IDataBase m_Database = null;
[Dependency]
public IDataBase Database
{
get { return m_Database; }
set { m_Database = value; }
}

public void Save()
{
m_Database.Save();
}
}

The "Dependency" attribute is part of the Unity application block and it's simply a gateway used by the Unity container for the concrete type injection.

The mapping between the abstract variable and the concrete type may be performed through the code or by adding a special configuration section to App.config file.

The final usage is quite simple:

IUnityContainer container = new UnityContainer();
UnityConfigurationSection configSection = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
configSection.Configure(container);
Customer customer = container.Resolve();
customer.Save();
The complete example could be downloaded here

That's it,
Mark.