Introducing The Unity.Mvc3 NuGet Package To Reconcile MVC3, Unity and IDisposable

Most IDependencyResolver implementations using Unity do not work with IDisposable and using them can lead to memory leaks and connection issues. Unity.Mvc3 is an assembly that includes a fuller implementation of IDependencyResolver that uses a child container per web request to ensure that IDisposable instances are disposed of at the end of each request. All of these complexities are taken care of by the assembly and integration into a project is as simple as adding a single line of code.

UPDATE: Unity.Mvc3 1.1 is now available.

Background

ASP.NET MVC 3 has a new mechanism for integrating an IoC container into the MVC pipeline. It involves writing an implementation of IDependencyResolver and registering it using the static DependencyResolver.SetResolver method. It is a trivial process to write a simple DependencyResolver for Unity, but the vast majority of versions that you will see do not handle IDisposable, leading to memory leaks in your applications when dealing with disposable components. Here is a typically naive implementation:

public class OverlySimpleUnityDependencyResolver : IDependencyResolver
{
  private readonly IUnityContainer _container;

  public OverlySimpleUnityDependencyResolver(IUnityContainer container)
  {
    _container = container;
  }

  public object GetService(Type serviceType)
  {
    return _container.IsRegistered(serviceType) 
      ? _container.Resolve(serviceType) 
      : null;
  }

  public IEnumerable<object> GetServices(Type serviceType)
  {
    return _container.ResolveAll(serviceType);
  }
}

Whilst this works perfectly well for most types, if you were to register a type that implements IDisposable, you will find that the Dispose method never gets called. If you use an object relational mapper (ORM) such as NHibernate or Entity Framework, failing to dispose of your ISession / ObjectContext / DBContext will leave connections open, resulting in database timeouts and other serious problems. It is therefore imperative to handle IDisposable correctly within your IoC container.

In the vast majority of IoC containers, you can solve this problem relatively easily by registering your IDisposable objects with a lifestyle of per web request. That way, at the end of the request, the container will automatically call dispose for you. It is a shame that Unity does not come with such a lifestyle and whilst you can find many implementations on the Net, most are far too simplistic and do not deal with the IDisposable issue at all.

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();
  }
}

This example does ensure that only a single instance of a type is instantiated per web request, but has no code to deal with IDisposable. It is possible to use the Application_EndRequest method in the Global.asax and loop through all objects in the HttpContext.Current.Items collection, check if they implement IDisposable and if so, call Dispose, but this is rather long-winded and it is far from ideal.

Fortunately, there is another technique that is simple and effective and is how Unity.Mvc3 addresses the problem - the child container. All the leading IoC containers (including Unity) allow the creation of a child container from the main, application level container. The key point that makes a child container useful is that whilst the main container is around for the lifetime of the application, a child container can have a much shorter lifetime. Once the child container is disposed, all the objects that have been instantiated by the child container (and registered with an appropriate lifetime) will also be disposed. Using this feature, we can write a dependency resolver to ensure that a child container is created for every web request and at the end of the request, the child container is disposed and thus all IDisposable objects resolved by the container are also disposed.

This is exactly what the Unity.Mvc3 project does which is now available as a NuGet package Unity.Mvc3 and also via CodePlex. NOTE that I have not put a dependency on the Unity NuGet package as I am assuming that many people will have the Unity DLL's from a source other than NuGet. Therefore, please ensure that you also download Unity either as a NuGet package or as part of Enterprise Library.

Using Unity.Mvc3

The code needed to integrate Unity.Mvc3 is very straightforward. As you would normally do when using an IoC container, we create the container and configure it using the fluent interface (obviously you can use the XML configuration if you are feeling sadistic). Note that we are using the RegisterControllers extension method which is included with the Unity.Mvc3 assembly. This method register all non-abstract controllers in the calling assembly, alleviating the need to explicitly register each one. Then we call the static SetResolver method to use the Unity.Mvc3 resolver. And that is all there is to it.

protected void Application_Start()
{
    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);

    var container = new UnityContainer();
    container.RegisterType<IService1, Service1>();
    container.RegisterType<IService2, Service2>();
    container.RegisterType<IExampleContext, ExampleContext>(new HierarchicalLifetimeManager());

    container.RegisterControllers();
    
    DependencyResolver.SetResolver(new UnityDependencyResolver(container));
}

The only thing that is unusual in this code is the lifetime of the DbContext - HierarchicalLifetimeManager. This lifetime is very important as without it, DbContext will not be disposed. Referring to the MSDN documentation, HierarchicalLifetimeManager is "a special lifetime manager which works like ContainerControlledLifetimeManager, except that in the presence of child containers, each child gets it's own instance of the object, instead of sharing one in the common parent". This is exactly what we want. By using this lifetime, DbContext is a singleton within the child container and when the child container gets disposed, so does the DbContext.

To put it simply, in order for Unity to dispose of any object resolved using the child container, you must register that object type using the HierarchicalLifetimeManager.

Conclusion

It is extremely important to dispose of IDisposable objects and failing to do so can lead to memory issues and problems with other finite resources. In an ASP.NET MVC3 website scenario, many types will need to have a lifetime of per web request. Bu using the Unity.Mvc3 NuGet package or downloading the assembly or source from CodePlex, you can address these requirements and deal with IDisposable safely and efficiently. Integration is very straightforward and the source code is available under the MIT licence, so there is very little reason not to use the Unity.Mvc package in your future projects.

Useful or Interesting?

If you liked the article, I would really appreciate it if you could share it with your Twitter followers.

Share on Twitter

Comments

Avatar for Brian Vallelunga Brian Vallelunga wrote on 01 Apr 2011

Thanks, this is the cleanest implementation I've seen of how to properly dispose of objects with Unity. Microsoft should really have built this in to Unity/MVC.

Avatar for Holger Kreissl Holger Kreissl wrote on 04 Apr 2011

Great article. Describes exactly what i was looking for. HierarchicalLifetimeManager... Cheers. I was wondering what kind of lifetimemanager enables request based containers and I didnt found a really smart implementation. Until i found this post. tyvm

Avatar for AroglDarthu AroglDarthu wrote on 01 May 2011

I noticed that both the NuGet package and the example in the source download do not register the RequestLifetimeHttpModule. Am I correct in assuming that it is not necessary for disposal of the child container?

Avatar for Paul Hiles Paul Hiles wrote on 01 May 2011

@AroglDarthu - the RequestLifetimehttpModule is registered but not in the conventional way. If you look inside PreApplicationStartCode.cs, you will see that I am using the DynamicModuleUtility.RegisterModule method which is a great new addition to .NET 4.0 that allows you to register a module without editing the web.config. We are also using PreApplicationStartMethod (in AssemblyInfo.cs) which is another new .NET 4.0 feature which allows you to execute a method at application startup. In this case, we are calling the PreStart method in PreApplicationStartCode.cs which registers the HttpModule. Hope this clears up the confusion.

Avatar for Leandro Leandro wrote on 06 Jul 2011

Hi Paul,

I've noticed that the Unity.Mvc3 still reference the old version of Unity (2.0.414) and of course the assembly binder complains... Do you think you can create the NuGet package so that it is dependent on the Unity package (and getting to use always the latest version) rather than being standalone?

Regards,

Avatar for Paul Hiles Paul Hiles wrote on 06 Jul 2011

@Leandro - I am not sure why there would be an assembly binding issue with the Unity 2.1 update. The Unity.Mvc3 DLL is not strongly named so should work fine with the later version of the Unity DLL's without any modifications required. I have tried it myself - downloading the Unity.Mvc3 NuGet package and the latest Unity NuGet package and it is working for me. Maybe you can let me know your exact scenario so I can reproduce it?

I have not added a NuGet dependency on Unity because many developers will already have the Unity DLL's installed on their machines as part of Enterprise Library, so forcing these users to download the NuGet package as well seemed unnecessary, but if there are issues with this approach, I will certainly look at adding the package dependency. I would be interested to hear what other people think?

Avatar for Leandro Leandro wrote on 06 Jul 2011

HI Paul,

What I did was simply get from NuGet the Unity package, the Unity.Interception package end the Unity.Mvc3... as soon as I start my MVC app I get the dreaded "manifest definition mismatch" problem:

Could not load file or assembly 'Microsoft.Practices.Unity, Version=2.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

As you see, Unity.Mvc3 is trying to locate v2.0.414.0 while I have v2.1.505.0 referenced. I could (probably) solve this with a binding redirect in the web.config but I would expect it to work with any Unity dll version.

Avatar for Paul Hiles Paul Hiles wrote on 12 Jul 2011

@Leandro - Thanks for the additional information. I have updated the package to reference Unity 2.1 now so you should not have any further issues. I have also added a Unity dependency to the NuGet package as your suggested.

I still cannot replicate your issue but I am wondering if it is down to NuGet versions. From NuGet 1.2, it is supposed to automatically put in BindingRedirects if it determines that they are necessary and this is exactly what it does for me (using NuGet 1.4). There are a few reports of some bugs in this functionality on the NuGet CodePlex site though.

Avatar for Lee Lee wrote on 30 Aug 2011

Hi, but how would you register this for NHibernate. Currently i say:

container.RegisterType<ISessionFactory>(new ContainerControlledLifetimeManager(), new InjectionFactory(c => {
return CreateSessionFactory();
}));
container.RegisterType<ISession>(new InjectionFactory(c => {
var sessionFactory = container.Resolve<ISessionFactory>();
return sessionFactory.OpenSession();
}));
container.RegisterType<IDataContext, NHibernateDataContext>(new PerRequestLifetimeManager<IDataContext>());

Avatar for Johanna Hawkins Johanna Hawkins wrote on 15 Sep 2011

I just tried downloading this and it does not work with previous versions of unity. I have version 2.0 and get version mismatch error when trying to reference Unity.Mvc3.

Assembly 'Unity.Mvc3, Version=1.1.0.0, Culture=neutral, PublicKeyToken=null' uses 'Microsoft.Practices.Unity, Version=2.1.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' which has a higher version than referenced assembly 'Microsoft.Practices.Unity, Version=2.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' c:\Temp\Unity.Mvc3.dll

Avatar for Paul Hiles Paul Hiles wrote on 16 Sep 2011

@Johanna - The latest version of Unity.Mvc3 on CodePlex (version 1.1) references Unity 2.1. If you are still using Unity 2.0, you have 2 choices:

1) Download the 1.0 version available on CodePlex which targets Unity 2.0.

2) Add a binding redirect in your web.config to redirect Unity 2.0 to Unity 2.1


<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.Practices.Unity" publicKeyToken="31BF3856AD364E35" culture="neutral"/>
<bindingRedirect oldVersion="2.0.414.0" newVersion="2.1.505.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>

Hope this helps.

Avatar for Adam Tuiper Adam Tuiper wrote on 16 Nov 2011

Doesn't the HierarchicalLifetimeManager take care of this for you? When I use it, my dispose method is called on every request.

Avatar for Paul Hiles Paul Hiles wrote on 17 Nov 2011

@Adam - no, the HierarchicalLifetimeManager creates components for the lifetime of the container or child container if present. Unity.Mvc3 creates a child container per request but out of the box, your main Unity container is (or should be) around for the lifetime of the application meaning that the components are not disposed until the end of the application. The only exception is the controller itself which gets disposed of automatically by the MVC framework. Typically though, your IDisposable dependencies will be further down the object hierarchy (the classic one is obviously an ORM context).

Avatar for sebastian sebastian wrote on 06 Mar 2012

Hi Paul,

I installed Unity.Mvc3 and inside installation files I found a reference to your blog. First of all thank you so much for this work. I checked files and I found that it is oriented to codefirst approach using dbcontext. I would like to know if its possible to work with database approach using edmx files. If yes, could you please shed some light of what do I have to do in order to configure the database for that approach inside the files?.

thank you so much. sebastian.

Avatar for Paul Hiles Paul Hiles wrote on 08 Mar 2012

@sebastian - Most of the examples use DbContext as you say but there is nothing in Unity.Mvc3 that ties you to using Code First. For EF with edmx files, you will have an auto-generated ObjectContext implementation instead of a DbContext. This implements IDisposable so needs to be treated in the same way as a DbContext. This means that you should register it with Unity using the HierarchicalLifetimeManager. e.g.

container.RegisterType<ObjectContext, MyDbEntities>(
new HierarchicalLifetimeManager());

Avatar for sebastian sebastian wrote on 08 Mar 2012

thank you so much, I´ve been trying to do that with no success. then I realized that changing the edmx file properties to:
1- Code generation move to: Default
2- lazyloading : false
it was recognized and give me the chance to declare the edmx file using its entity container name as a container.registertype. I will try to use it in that way. thank youso much for your time!!

Avatar for Tara Tara wrote on 13 Mar 2012

Hi Paul
Just started using Unity.Mvc3 and have been able to register simple things like services etc(Thanks for the work and the great tutorials). But I'm running into a problem when registering my db entities. As stated above i have declared

container.RegisterType<myEntities, myEntities>(new HierarchicalLifetimeManager());

I get the error 'myEntities has multiple constructors of length 1. Unable to disambiguate.'

I assume that unity is unable to resolve which constructor to use. But I'm not quite sure what I've missed.

If you could point the way I would be most grateful.
Tara

Avatar for Paul Hiles Paul Hiles wrote on 15 Mar 2012

@Tara - Unity will try and resolve a component using the longest constructor it can find. In the case of auto-generated EF contexts, it creates two constructors with a single parameter so Unity cannot work out which one to use without a little help.

This will make it use the default parameterless constructor:

container.RegisterType<myEntities>(new HierarchicalLifetimeManager(), new InjectionConstructor());

or this will allow you to inject a connection string:

var connectionString = "... get from config";

container.RegisterType<myEntities>(new HierarchicalLifetimeManager(), new InjectionConstructor(connectionString));

Avatar for tara tara wrote on 16 Mar 2012

Thanks for your reply Paul

Managed eventually to get there myself before I read your reply, but I really appreciate you taking to the time to confirm the right syntax.

Avatar for Mariano Mariano wrote on 25 Apr 2012

this is my BuildUnityContainer in BootStrapper:

private static IUnityContainer BuildUnityContainer()
{
var container = new UnityContainer();

container.RegisterType<IUnitOfWork, UnitOfWork>();
container.RegisterType<IPostRepository, PostRepository>();
container.RegisterType(Type.GetType(
container.RegisterType<IDatabaseFactory, DatabaseFactory>();
container.RegisterType<IPostService, PostService>();

container.RegisterControllers();

return container;
}


Controller ...

public PostsController( IPostService postService)
{
this._postservice = postService;
}

But, I have the following problem with Postcontroller

An error occurred when trying to create a controller of type 'Blog.API.Controllers.PostsController'. Make sure that the controller has a parameterless public constructor.

Should I build a ControllerFactory?

Avatar for Paul Hiles Paul Hiles wrote on 26 Apr 2012

@Mariano - Did you forget to add Bootstrapper.Initialise(); to the Application_Start() method in global.asax?

Avatar for Vitaliy Vitaliy wrote on 21 Aug 2012

Hi Paul, thank you for your work. I have a question:
I've set resolver from your dll

DependencyResolver.SetResolver(new UnityDependencyResolver(container));

and registered couple types with HierarchicalLifetimeManager.
I run first web request and watched a hash code of the object registered with HierarchicalLifetimeManager. After I run another request(s) and hash code was the same. Looks like container resolved same object for those requests, but you say new instance of type must be created on each request. Can you point me what is wrong?

thank you

Avatar for Sebas Sebas wrote on 30 Sep 2012

HI, I'm new with DI and a have a few questions. I am using unit.mvc3 in a new project, with mvc4 and I'm not being able to run it.

How can I register generic types?

Scenario:

I have a BaseService<T>, with the following constructor:

public BaseService(IEntityRepository<T> repository, IUnitOfWork unitOfWork)

and I registered :
RegisterType<IPersonRepository, PersonRepository>
RegisterType<IPersonService, PersonService>

However, this is not working, I'm getting the error
"The current type, ...IEntityRepository`1[Person], is an interface and cannot be constructed. Are you missing a type mapping?

It seems because can not resolve the repository on the BaseService, even when I registered the concrete PersonService.

How should I register my types in this case?
Can I register only the BaseService<T> and IRepository<T> and not the concrete classes?


Thank you
Any help would be appreciated.

Avatar for Naskar Naskar wrote on 20 Nov 2012

In large projects, it's interesting your project use strong name for the assembly.

Is there any reason to you don't sign the assembly ?

Avatar for Joe Joe wrote on 21 Mar 2013

HierarchicalLifetimeManager is a disaster!
I built a new ASP.NET MVC3 app.
When I used NuGet to add Unity.MVC3 I got a readme file.
The file directed me to this web page.
I read the page and followed the advice. I used HierarchicalLifetimeManager.
What a huge disaster. It caused eavery web user to share the same instance of the DbContext which caused them to single thread.
We had a terrible performance problem. Just terrible.
We got through DEV and QA without noticing.
When we went to production the app performance sucked. I thought my boss was gonna fire me!
After much pain, blaming the database, etc. I changed back to the default TransientLifetimeManager and all the single threaded bottle neck problems went away.
I cannot understand any scenario where a single instance is the best architecture for a web app.
Warning: Do not use HierarchicalLifetimeManager for DbContext in a web app!

Comments are now closed for this article.