This is an example of an MVC Application using Register by Convention and Unity.MVC
Use nuget to add Unity.MVC to the MVC4 application.
(Unity bootstrapper for ASP.NET MVC 3.0.1304.0)
Now edit the UnityMvcActivator in the App_Start folder. The following code must be included.
Microsoft.Web.Infrastructure.DynamicModuleHelper .DynamicModuleUtility.RegisterModule(typeof(UnityPerRequestHttpModule));
Then change the UnityConfig class. Add a custom function and use this in the RegisterTypes method. Now all objects, instances in the container have a PerRequestLifetimeManager lifetime manager.
public static void RegisterTypes(IUnityContainer container) { // NOTE: To load from web.config uncomment the line below. Make sure to add a Microsoft.Practices.Unity.Configuration to the using statements. // container.LoadConfiguration(); // container.RegisterType<IProductRepository, ProductRepository>(); container.RegisterTypes(AllClasses.FromLoadedAssemblies(), WithMappings.FromMatchingInterface, WithName.Default, PerRequest); } public static Func<System.Type, Microsoft.Practices.Unity.LifetimeManager> PerRequest = (x) => new PerRequestLifetimeManager();
NOTE: The RegisterType method and the WithLifetime are partial classes. We could extend these classes and add our PerRequestLifetimeManager in an extension method or we could use the Custom method to call the PerRequestLifetimeManager.
Here’s an example using the WithLifetime.Custom method:
public static void RegisterTypes(IUnityContainer container) { container.RegisterTypes(AllClasses.FromLoadedAssemblies(), WithMappings.FromMatchingInterface, WithName.Default, WithLifetime.Custom<PerRequestLifetimeManager> ) .RegisterType<IUnitOfWorkExample, UnitOfWorkExampleTest>(new TransientLifetimeManager()); }
And here’s an example using an extension method:
namespace Microsoft.Practices.Unity { public static partial class WithLifetime { public static LifetimeManager PerRequest(Type type) { return new PerRequestLifetimeManager(); } } } public static void RegisterTypes(IUnityContainer container) { container.RegisterTypes(AllClasses.FromLoadedAssemblies(), WithMappings.FromMatchingInterface, WithName.Default, WithLifetime.PerRequest ) .RegisterType<IUnitOfWorkExample, UnitOfWorkExampleTest>(new TransientLifetimeManager()); }
Semantic Logging is used to log the constructor and the dispose methods to the database.
Now the RegisterTypes must be changed. All business objects will be created with a per http request LifeTimeManager and all UnitOfWork objects will be created with each new resolve. Each BusinessManager has its own UnitOfWork. The UnitOfWork must be properly disposed.
The code underneath creates the objects as required, but the UnitOfWork dispose is missing.
To do this the dispose must be implemented explicitly for the TransientLifetimeManager.
public static void RegisterTypes(IUnityContainer container) { container.RegisterTypes(AllClasses.FromLoadedAssemblies(), WithMappings.FromMatchingInterface, WithName.Default, PerRequest) .RegisterType<IUnitOfWorkExample, UnitOfWorkExampleTest>(new TransientLifetimeManager()); }
To dispose of the Unit of Work. (In the business class)
public void Dispose() { _unitOfWorkExample.Dispose(); UnityEventLogger.Log.DisposeUnityMessage("BusinessClass"); if (!_disposed) { _disposed = true; } }
Here are the produced logs:
Now we have a MVC4 application implemented with unity which will work correctly.
code: https://github.com/damienbod/MvcUnityBootstrapperTest.git
Built in Lifetime Management
- ContainerControlledLifetimeManager : singleton instance with dispose
- HierarchicalLifetimeManager : singleton instance per container with dispose
- TransientLifetimeManager : empty manager, always returns new object by resolve, no dispose!
- PerRequestLifetimeManager (Unity.MVC) : singleton instance per http request with dispose
- ExternallyControlledLifetimeManager : code must handle lifetime management
- PerResolveLifetimeManager : like TransientLifetimeManager expect when in same object graph
- PerThreadLifetimeManager : A LifetimeManager that holds the instances given to it, keeping one instance per thread.
Inherit from LifetimeManager or SynchronizedLifetimeManager?
These are the 2 abstract classes which are required to create a custom LifeTimeManager.
SynchronizedLifetimeManager: Base class for Lifetime managers which need to synchronize calls to GetValue().
LifetimeManager: Base class for Lifetime managers – classes that control how and when instances are created by the Unity container.
Here’s an example of a custom lifetime manager:
public class PerRequestLifetimeManager : LifetimeManager { private readonly object key = new object(); public override object GetValue() { if (HttpContext.Current != null && HttpContext.Current.Items.Contains(key)) return HttpContext.Current.Items[key]; else return null; } public override void RemoveValue() { if (HttpContext.Current != null) HttpContext.Current.Items.Remove(key); } public override void SetValue(object newValue) { if (HttpContext.Current != null) HttpContext.Current.Items[key] = newValue; } }
Part 1 Enterprise Library 6, Unity 3 with ASP.NET MVC 4 Part 1
Part 3 Enterprise Library 6, Unity 3 and MVC 4, Registration by Convention Part 3
Part 4 Enterprise Library 6, Unity 3 InterfaceInterceptor with MVC 4
Part 5 Enterprise Library 6, Unity 3, MVC, Validation with Interception ValidationCallHandler
Links
http://pratapreddypilaka.blogspot.ch/2012/06/mvc-unity-dependecy-resolver-lifetime.html
http://www.ladislavmrnka.com/2011/03/unity-build-in-lifetime-managers/
http://msdn.microsoft.com/en-us/library/ff647854.aspx#lifetime_register
http://msdn.microsoft.com/en-us/library/ff647854.aspx#lifetime_registerinstance
http://netpl.blogspot.ch/2013/03/unity-and-http-per-request-lifetime.html
http://stackoverflow.com/questions/4747653/unity-and-lifetime-management
http://stackoverflow.com/questions/6938049/repositories-unitofwork-and-unity
http://dotnetslackers.com/articles/aspnet/Using-Microsoft-Unity-in-ASP-NET-MVC.aspx
http://msdn.microsoft.com/en-us/library/dn178462%28v=pandp.30%29.aspx#sec2
Awesome post! Should you not use the UnityPerRequestHttpModule instead PerRequestLifetimeManager?
Thanks, PerRequestLifetimeManager uses the UnityPerRequestHttpModule. Here’s the source code: http://unity.codeplex.com/SourceControl/latest#Unity/Unity.Mvc/Src/PerRequestLifetimeManager.cs
I wanted a class which inherits from the LifetimeManager so I could use the RegisterTypes method. If you use UnityPerRequestHttpModule directly, you have some advantages but you have to resolve it differently.
greetings Damien
Have to send do an empty comment, since I forgot to click on “Notify me of follow-up comments via email” checkbox..
I believe if we use UnityPerRequestHttpModule, it will default to this, and we could setup other mappings e.g. static cases, explicitly.