This example shows you how to setup a simple ASP.NET MVC 4 application using Enterprise Library Unity 3 for its dependency injection.
Firstly use nuget to add the Unity 3 package:
Create a new static class which will be used to get the root UnityContainer.
public static class MvcUnityContainer { public static IUnityContainer Container { get; set; } }
Create a new class which inherits from the DefaultControllerFactory, otherwise you must implement everything yourself:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using System.Web.Routing; using Microsoft.Practices.Unity; namespace MvcUnity3Test { public class UnityControllerFactory: DefaultControllerFactory { protected override IController GetControllerInstance(RequestContext reqContext, Type controllerType) { IController controller; if (controllerType == null) throw new HttpException( 404, String.Format( "The controller for path '{0}' could not be found" + "or it does not implement IController.", reqContext.HttpContext.Request.Path)); if (!typeof(IController).IsAssignableFrom(controllerType)) throw new ArgumentException( string.Format( "Type requested is not a controller: {0}", controllerType.Name), "controllerType"); try { controller = MvcUnityContainer.Container.Resolve(controllerType) as IController; } catch (Exception ex) { throw new InvalidOperationException(String.Format( "Error resolving controller {0}", controllerType.Name), ex); } return controller; } } }
In Global.asax add the following:
- InitUnityAndRegisterTypes()
- using Microsoft.Practices.Unity;
- (In the Application_Start method) InitUnityAndRegisterTypes();
ControllerBuilder.Current.SetControllerFactory(typeof(UnityControllerFactory));
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Http; using System.Web.Mvc; using System.Web.Optimization; using System.Web.Routing; using Microsoft.Practices.Unity; namespace MvcUnity3Test { // Note: For instructions on enabling IIS6 or IIS7 classic mode, // visit http://go.microsoft.com/?LinkId=9394801 public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { InitUnityAndRegisterTypes(); ControllerBuilder.Current.SetControllerFactory(typeof(UnityControllerFactory)); AreaRegistration.RegisterAllAreas(); WebApiConfig.Register(GlobalConfiguration.Configuration); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); } public void InitUnityAndRegisterTypes() { IUnityContainer container = new UnityContainer() .RegisterTypes(AllClasses.FromLoadedAssemblies(), WithMappings.FromMatchingInterface, WithName.Default, WithLifetime.ContainerControlled); //.RegisterType<Business.IBusinessClass, Business.BusinessClass>() //.RegisterType<Business.IDoSomething, Business.DoSomething>(); MvcUnityContainer.Container = container; } } }
New in Unity 3, we can scan assemblies, classes etc to register the different types. Only the interfaces which require special lifetime containers need to be defined separate.
IUnityContainer container = new UnityContainer() .RegisterTypes(AllClasses.FromLoadedAssemblies(), WithMappings.FromMatchingInterface, WithName.Default, WithLifetime.ContainerControlled);
Now the code is ready to use. Here’s an example of construction injection in the HomeController:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace MvcUnity3Test.Controllers { public class HomeController : Controller { private readonly Business.IBusinessClass _businessClass; public HomeController(Business.IBusinessClass businessClass) { _businessClass = businessClass; } public ActionResult Index() { _businessClass.Hello(); return View(); } } }
And here’s an example of Property injection
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using Microsoft.Practices.Unity; namespace MvcUnity3Test.Controllers { public class PropertyDependencyController : Controller { [Dependency] public Business.IDoSomething _doSomethingUtil { get; set; } public ActionResult Index() { return View(); } } }
This shows you how simple Unity 3 can be and we have a ASP.NET MVC application which is easy to use to implement unit tests…
No complicated unity configurations are required.
You don’t need to Register all interfaces to classes, only if you want.
You can extend the Registration by Convention
Who said Unity was complicated…
Source code:
https://github.com/damienbod/MVCEL6Unity3Test
Unity also comes with 2 nuget packages which does the same as above (a little bit different and more complete):
Here are the 2 links:
http://nuget.org/packages/Unity.Mvc/
https://nuget.org/packages/Unity.AspNet.WebApi/
Next steps are to define our LifeTimeManagers, Containers/Sub-Containers, improve our unity scan code and also explain/implement unity configuration.
Part 2 Enterprise Library 6, Unity 3 and MVC 4, LifetimeManagers Part 2
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:
https://entlib.codeplex.com/downloads/get/668951
https://entlib.codeplex.com/releases/view/64243
http://blogs.msdn.com/b/agile/archive/2013/03/12/unity-configuration-registration-by-convention.aspx
http://blogs.msdn.com/b/agile/archive/2013/04/25/just-released-microsoft-enterprise-library-6.aspx
http://msdnrss.thecoderblogs.com/2013/05/microsoft-enterprise-library-6-wave-2-release/