Enterprise Library 6, Unity 3 with ASP.NET MVC 4 Part 1

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:
NugetUntiy3

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:

  1. InitUnityAndRegisterTypes()
  2. using Microsoft.Practices.Unity;
  3. (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://entlib.codeplex.com/

http://msdnrss.thecoderblogs.com/2013/05/microsoft-enterprise-library-6-wave-2-release/

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: