Generic Decorators and Unity IoC - Cast Out Thy Cross-Cutting Concerns

Those of you who have attended my presentations on Unity and/or AOP know that I have a fondness for Decorators and Generic Decorators as a method of pulling cross-cutting concerns and other orthogonal ideas from my classes. Of course, creating interceptors with proxies that work with your dependency injection container of choice does it just as nicely, too.

The point being that you want to keep your classes adhering to the Single-Responsibility Principle ( SRP ) and Open-Closed Principle ( OCP ) as it makes your applications so much more maintainable. Doing so allows you to modify or add behavior to your applications such that you are not modifying or changing any existing code, but rather 1) adding new code or 2) changing the configuration of your container to provide the desired effect.

 

Generic Decorators in Action

Let's take a simple IDAO interface that saves an instance of T as follows:

 

public interface IDAO<T>

{

    void Add(T instance);

}

 

and an implementation that uses LINQ To SQL, but strips away a lot of the underlying detail to get to the point:

 

public class DAO<T> : IDAO<T>

{

    public void Add(T instance)

    {

        _dataContext.InsertOnSubmit(instance);

    }

}

 

Now, of course, we want to validate the instance of T before we insert it into the database. Let's not stick validation in the DAO implementation, but instead put it in a decorator class that implements IDAO and will do only one thing - validation.

 

public class ValidatingDAODecorator<T> : IDAO<T>

{

    private readonly IDAO<T> _inner;

 

    public ValidatingDAODecorator(IDAO<T> inner)

    {

        _inner = inner;

    }

 

    public void Add(T instance)

    {

        instance.Validate();

        if (!instance.IsValid)

            throw new ValidationException(instance.Errors, "instance");

 

        _inner.Add(instance);

    }

}

 

The idea here is that the decorator class looks, smells, and acts like an IDAO so we can substitute it anywhere in our application that wants an IDAO. It requires an IDAO in its constructor that will actually handle the peristence mechanism. In this case, DAO.

The beauty is that now when a class requests an implementation of IDAO, we can use a little Unity configuration magic to provide DAO wrapped with the ValidatingDAODecorator class:

 

container.RegisterType(

    typeof (IDAO<>),

    typeof (DAO<>),

    "DAO");

container.RegisterType(

    typeof(IDAO<>),

    typeof(ValidatingDAODecorator<>),

    new InjectionConstructor(

        new ResolvedParameter(

            typeof(IDAO<>),

            "DAO")));

 

Rather ugly, but it essentially says that when a class requires an IDAO, pass it an instance of ValidatingDAODecorator. It also says that when ValidatingDAODecorator is constructed make sure you inject an instance of DAO into its constructor to do the actual persistence.

The beauty here is that 1) I have completely separated validation from persistence, 2) I can now test each in isolation, and 3) I can remove or add a different implementation of validation by only adding code and/or changing configuration. If I instead add the Unity configuration to a configuration file, I could possibly make this happen without any source code changes. Pretty dang cool!

 

David Hayden

 

posted on Wednesday, July 22, 2009 5:18 PM

Main

David Hayden Google +

David Hayden Twitter

Health & Fitness

JavaScript Patterns Book Review

HTML 5 and CSS3 - Develop with Tomorrow's Standards Today

Professional ASP.NET Design Patterns Book Review

Beginning Mac Programming Book Review

C# in Depth Book Review

ASP.NET MVC

Orchard CMS

Categories