ASP.NET MVC 3: How to use the Unit of Work pattern with Unity 2.0

Update 2013-04-18 I’ve updated the EndRequest event handler to only commit the changes if no error occurred in the current HTTP request.

In one of my last post, I showed how to set up the Unity 2.0 dependency injection container in an ASP.NET MVC 3 web application.
In this post, I will show how to use the Unit of Work pattern in combination with the Unity dependency resolver in an ASP.NET MVC 3 web application. The Unit of Work pattern is described by Martin Fowler as follows:

Maintains a list of objects affected by a business transaction and coordinates the writing out of changes and the resolution of concurrency problems.

In a web application writing changes to the database is typically done at the end of each request. To accomplish this, we need to create an instance of the Unit of Work implementation for each request, share this instance in all business objects (i.e. use Unity to inject the Unit of work into the business objects) and commit the changes at the end the request. The concrete implementation of the Unit of Work pattern is not part of this post (you can find more information on other pages like “Using Repository and Unit of Work patterns with Entity Framework 4.0”).
In the following I will give step-by-step instructions how to integrate the Unit of Work in your ASP.NET MVC 3 web application. First we first need an implementation of Unity’s LifetimeManager class that makes sure that the Unit Of Work instance lives exactly for one request (I’m using an implementation found in this post):

public class HttpContextLifetimeManager<T> : LifetimeManager, IDisposable
{
  public override object GetValue()
  {
    return HttpContext.Current.Items[typeof(T).AssemblyQualifiedName];
  }
  public override void RemoveValue()
  {
    HttpContext.Current.Items.Remove(typeof(T).AssemblyQualifiedName);
  }
  public override void SetValue(object newValue)
  {
    HttpContext.Current.Items[typeof(T).AssemblyQualifiedName] = newValue;
  }
  public void Dispose()
  {
    RemoveValue();
  }
}

The remaining configuration is done in the Global.asax file:

  • Configure the Unity container in the Application_Start method and use the HttpContextLifetimeManager (see above) when registering the Unit of Work type (the interface is typically named IUnitOfWork). The implementation of the UnityDependencyResolver used in the example code below can be found in one of my previous post “ASP.NET MVC 3: Dependency injection with Unity 2.0“.
  • In the constructor of your MVC application, register an event handler for the “end request” event and use the Unit of Work to commit all changes to the database.
  • Of course, you have to inject the Unit of Work instance to all business objects that do database changes, e.g. by using Unity’s constructor or property injection.

The important parts of the Global.asax.cs are shown below:

public YourMvcApplication()
{
  [...]
  EndRequest += new EventHandler(GlobalApplication_EndRequest);
}
 
protected void Application_Start()
{
  [...]
  var container = new UnityContainer();
  container.RegisterType<IUnitOfWork, ConcreteUnitOfWork>(new HttpContextLifetimeManager<IUnitOfWork>());
  [...]
  DependencyResolver.SetResolver(new UnityDependencyResolver(container));
  [...]
}
 
void GlobalApplication_EndRequest(object sender, EventArgs e)
{
  if (HttpContext.Current.Error != null) return;
  var unitOfWork = _container.Resolve<IUnitOfWork>();
  unitOfWork.Save();
}