Skip to content

Instantly share code, notes, and snippets.

@danielgreen
Created June 4, 2013 14:28
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save danielgreen/5706345 to your computer and use it in GitHub Desktop.
Save danielgreen/5706345 to your computer and use it in GitHub Desktop.
Using Unity in MVC - setting up Dependency Injection for your application. See http://www.devtrends.co.uk/blog/integrating-the-unity.mvc3-1.1-nuget-package-from-scratch
using System.Web.Mvc;
using Microsoft.Practices.Unity;
using Unity.Mvc4;
namespace MvcApplication1
{
public static class Bootstrapper
{
public static void Initialise()
{
var container = BuildUnityContainer();
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
}
private static IUnityContainer BuildUnityContainer()
{
var container = new UnityContainer();
// Define an inline function to make the rest of this function neater
Func<LifetimeManager> LM = () => { return new HierarchicalLifetimeManager(); };
// register all your components with the container here
// e.g. container.RegisterType<ITestService, TestService>();
container.RegisterType<IUnitOfWork, UnitOfWork>(LM());
// If we want to register an instance against a child container, e.g. inject the HTTP Context per request
// we can't do that directly as Unity.MVC4 doesn't expose the child containers to let us use RegisterInstance.
// Instead we could use RegisterType with an InjectionFactory - needs tested however.
// See http://stackoverflow.com/questions/7771097/ioc-register-instance-issue-with-mvc3-unity-nhibernate-unity-mvc3-lib-from
container.RegisterType<IHttpContextBase>(new InjectionFactory(c => new HttpContextWrapper(HttpContext.Current)), LM());
return container;
}
}
}
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
Bootstrapper.Initialise();
}
Install the Unity.MVC4 package to your Web project (although Unity.MVC4 may have issues - see http://stackoverflow.com/questions/16089137/unity-mvc4-doesnt-dispose). If necessary use Unity.MVC3 package instead. NuGet packages also exist to use Unity with WCF and WebAPI.
Unity.MVC4 provides a UnityDependencyResolver, which handles creating child containers per HTTP request, storing the child container in the HTTP Context, using it to resolve objects, and disposing of it at the end of the request (with a custom HTTP module). See http://unitymvc3.codeplex.com/SourceControl/latest#Unity.Mvc3/UnityDependencyResolver.cs
Ensure that you call Bootstrapper.Initialise in Application_Start within Global.asax.cs.
Amend Bootstrapper.cs to register the types and instances your classes expect to be injected. They can be assigned a Lifetime Manager, ususally the HierarchicalLifetimeManager which ensures they are disposed at the end of each request.
Unity only constructs objects when they are required to be injected and not before, but there is also the possibility of using the Lazy<T> wrapper to further delay object construction. That requires Unity 3, whereas Unity.MVC4 still uses Unity 2.1. However the Unity 3 release notes suggest that it includes built-in support for ASP.NET MVC. Worth some more investigation? See http://unity.codeplex.com/wikipage?title=Unity3ReleaseNotes&referringTitle=Unity3
A downside of having Unity-related code in your Web project is that the project may have reference many other projects in the solution (for the purpose of configuring the dependencies in the Unity container) that it would otherwise be isolated from, such as low-level data access libraries.
You can get around this by creating a separate Web.Bootstrapper project to handle the Unity configuration. Your Web project references Web.Bootstrapper and any other projects it is directly dependent on. Web.Bootstrapper references Unity and potentialy all other projects in your solution.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment