Code Aesthetics

Programming, agility, technical stuff ...

Inversion Of Control

Introducing inversion of control into your enterprise application improves flexibility and maintainability. In this article I want to explain the concepts of inversion of control and dependency injection using an illustrating example based on unity.

Inversion of Control

Inversion of control (IoC) is a generic term for giving away the control of component creation and controlling to a framework or container ("You do not call us, we call you").

Let's create a simple application which manages contacts:

Class Diagram Persons

Our domain model contains two classes: A person class which encapsulates all information about a person we want to work with  and a PersonRepository class which encapsulates any logic for persisting persons. To keep it simple we have only 3 properties on the person class and id, first and last name.

If we now want to use our domain model the code could be similar to the following

[csharp] var repository = new PersonRepository();
repository.Save(new Person("Johannes", "Täuber"));
repository.Save(new Person("Sylvain", "Chery"));
repository.Print();
[/csharp]

There is nothing wrong with this code, but it limits us. We have tight coupling, because we create an instance of PersonRepository directly. Even if we would use an interface here somewhere in the code there would be this first line.
If we need to exchange PersonRepository with an SqlPersonRepository which persists Persons in a database, we have to find all occurences and replace them with the new implementation. Also implementing cross cutting concerns such as logging or validation can be difficult: We need to change all repository classes (e.g. by introducing a new base class).

Using inversion of control we can overcome this problem. We use a the ServiceLocator pattern in order to create an instance of the repository using a generic interface:

[csharp] var repository = ServiceLocator.Current.GetInstance<IRepository<Person>>();
repository.Save(new Person("Johannes", "Täuber"));
repository.Save(new Person("Sylvain", "Chery"));
repository.Print();
[/csharp]

This version uses the interface to retrieve an instance of the repository from the IoC container (in this example unity). We can now simply exchange the implementation of IRepository<Person> without changing this piece of code. This can for example be done using a configuration file:

[xml]

<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" /> </configSections> <unity> <typeAliases> <typeAlias alias="RepositoryInterface" type="Samples.InversionOfControl.Concepts.IRepository`1[[Samples.InversionOfControl.Models.Person, Samples.InversionOfControl]], Samples.InversionOfControl" />
<typeAlias alias="PersonRepository" type="Samples.InversionOfControl.Models.PersonRepository, Samples.InversionOfControl" />
</typeAliases> <containers> <container> <types> <type type="RepositoryInterface" mapTo="PersonRepository" /> </types> </container> </containers> </unity> </configuration>

[/xml]

The real advantage is that we can chain repositories using the configuration file. Let us implement a cross-cutting feature:  we want to log all calls to the PersonRepository to the console for debugging purposes. For this we now can a use generic decorator chain. There also other possibilities to implement cross cutting concerns such as AOP for example. But here we focus in this simple and elegant solution.

The generic logger looks like this:

[csharp]

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Samples.InversionOfControl.Concepts;

namespace Samples.InversionOfControl.Logging {

class RepositoryLogger<T> : IRepository<T> {
IRepository<T> _inner;

public RepositoryLogger(IRepository<T> inner) { _inner = inner; }

public T FindBy(Guid id) { Console.WriteLine("FindBy '{0}'", id); return _inner.FindBy(id); }

public IEnumerable<T> FindAll() { Console.WriteLine("FindAll '{0}'"); return _inner.FindAll(); }

public IEnumerable<T> FindByCriteria(Predicate<T> x) { Console.WriteLine("FindByCriteria"); return _inner.FindByCriteria(x); }

public void Save(Models.Person p) { Console.WriteLine("Saving " + p.ToString()); _inner.Save(p); }

public void Delete(Models.Person p) { Console.WriteLine("Deleting " + p.ToString()); _inner.Delete(p); }

public void Print() { Console.WriteLine("Printing ... "); _inner.Print(); } } }

[/csharp]

Since we have a container which is responsible for the creation of our repository we can simply change the configuration file. The client code can stay the same. No compiling needed. The modified configuration file looks like this:

[xml]

<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" /> </configSections> <unity> <typeAliases>

<typeAlias alias="RepositoryInterface"

type="Samples.InversionOfControl.Concepts.IRepository`1[[Samples.InversionOfControl.Models.Person, Samples.InversionOfControl]], Samples.InversionOfControl" /> <typeAlias alias="PersonRepository"

type="Samples.InversionOfControl.Models.PersonRepository, Samples.InversionOfControl" />
<typeAlias alias="PersonRepositoryLogger"

type="Samples.InversionOfControl.Logging.RepositoryLogger`1[[Samples.InversionOfControl.Models.Person, Samples.InversionOfControl]], Samples.InversionOfControl.Logging" />
</typeAliases> <containers> <container> <types> <type type="RepositoryInterface" mapTo="PersonRepository" name="storage"/> <type type="RepositoryInterface" mapTo="PersonRepositoryLogger" > <constructor> <param name="inner"> <dependency name="storage"/> </param> </constructor> </type> </types> </container> </containers> </unity> </configuration>

[/xml]

The full example code can be downloaded from here.

Dependency Injection

Where Inversion Of Control solves the problem of decoupling the "client" code from the actual implementation, dependency injection can solve the problem of dependencies between classes. Unity as the IoC container I use for my example supports constructor, property, and method call injection.

What is a dependency?

Let's say the PersonRepository class uses another class to track the changes. A unit of work.

[csharp] public interface IUnitOfWork
{ // code left out for simplicity }

class UnitOfWork : IUnitOfWork
{
    // code left out for simplicity
}

class PersonRepository {
    private IUnitOfWork _unitOfWork;

    public PersonRepository() {
        _unitOfWork = new UnitOfWork();
    }

    // code left out for simplicity
}

[/csharp]

The PersonRepository class has now a dependency on the UnitOfWork class because it is using it. How can this issue be solved? First we should pass in the dependency from outside.

Constructor Injection

[csharp] class PersonRepository {
private IUnitOfWork _unitOfWork;

    public PersonRepository(IUnitOfWork unitOfWork) {
        _unitOfWork = unitOfWork;
    }

    // code left out for simplicity
}

[/csharp]

Now different implementations of the unit of work can be passed into our class. If we now use an inversion of control container to retrieve the implementation of our class, the container will try to resolve existing dependencies by looking at the types registered with the container and automatically pass in the correct implementation. This is called constructor injection.

Property Injection

The dependency can also be resolved after creation. Using property injection the code looks like this:

[csharp]

class PersonRepository {
private IUnitOfWork _unitOfWork;

    public PersonRepository() {
    }

    [Dependency]
    public IUnitOfWork UnitOfWork {
        get {
            return _unitOfWork;
        }
        set {
            _unitOfWork = value;
        }
    }

    // code left out for simplicity
}

[/csharp]

Method Injection

Using unity's method injection the code would change to this:

[csharp] class PersonRepository {
private IUnitOfWork _unitOfWork;

    public PersonRepository() {
    }

    [InjectionMethod]
    public void Initialize(IUnitOfWork unityOfWork) {
        _unitOfWork = unityOfWork;
    }

    // code left out for simplicity
}

[/csharp]

The difference is that the dependencies are filled in as soon as we call the method.

Summary

Using inversion of control and dependency injection code can become loosely coupled and it can become more cohesive. It allows developers to produce more flexible designs which can be extended an maintained easily.

Johannes Täuber

I am a software architect and agility advocate. I am interested in all technologies out there and like to discuss options. My platform of choice is the .NET framework.