Dependency Injection with UNITY and MEF in ASP.NET MVC

Vishvvas
Posted by in Design Pattern & Practices category on for Advance level | Points: 250 | Views : 3161 red flag
Rating: 5 out of 5  
 2 vote(s)

A different approach for DI with UNITY is explored which employs MEF (Managed Extensibility Framework) for detecting the registration of self declaring types.


 Download source code for Dependency Injection with UNITY and MEF in ASP.NET MVC

Recommendation
Read Simple controller dependency injection in ASP.NET MVC before this article.

Introduction and background

Unity framework is definitely one of the very popular DI framework. There are other options like castle Windsor, autofac etc are available and the choice of such framework is based on project needs as well as personal preferences. Unity is available as a part of Microsoft toolkit and on nugget ( https://www.nuget.org/ ).

With Unity, one can enforce DI (dependency injection) for implementing IoC and with unity extensions, the ability for interceptions is available.

The common practice adopted for Unity DI is to register types in unity config file. If any new type is to be registered, it needs to be added into such file. Addition or changes call for compilation of this file. This means that in a way, for implementing DI, there is a dependency on config file. Such config file may be in web project or some other common project.

In this scenario, the assemblies

(i)    where types are added

(ii)   containing config files

(iii)   where the type is used all need to be compiled and deployed.

There is scope for automation in this modality where the registration can be done in place i.e. where the types are defined and such registrations is sensed through reflection. This can eliminated dependency on config file and on one place for registration. To bring this automation and also provide an ability for types to self-declare for registration, this component is developed.

This content assumes that the readers are aware of DI, IoC and Unity framework for DI.

Using the code /Description

Explain the topic of the article with code and description

This small library is intended to provide quick wiring up the dependencies through MEF for asp.net MVC /webapi projects.

The library contains a wrapper over the registration of types through reflection for MEF. This helps to skip the unit config file and also the hard wiring needed at one place.

This enables use of MEF (Managed Extensibility Framework) composition and the types which participates in Inversion of control are declared for exported through attributes.

This offers 2 distinct benefits

  1.  The hooking up for DI is not centralized but part of assembly where types are declared. This way there is no need of common place in solution for IoC and hooking up types and also the responsibility of participating in IoC lies on the types itself.

  2. There is no need of manual coding for direct registration with unity contaier as the types which are declared exportable are registered automatically. This also helps to avoid compiling of client code (web project) and /or the DI wiring code.

 Following steps are involved

Step I: Include/refer this library

Include/reference the dll in web project or any other wrapper project

Step II: Install Nuget packages

Install the following nugget packages in the client project i.e. web project

https://www.nuget.org/packages/Unity/3.0.1304.1

Install-Package Unity -Version 3.5.1404

Install-Package Unity.Mvc -Version 3.5.1404


Step III

User "var" button to wrap your variable or classNnames



Step IV: Initialize Unity

 Hook up the unity bootstrapper in Application_start()

using System.Web;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using UnityIoC;

namespace TestUnityIoC
{
    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            Bootstrapper.Initialise(".\\bin", "TestUnityIoC.*.dll");

        }
    }
}

Step V: Export the Types


The assembly needs to emit the types for registration which is done as following. This code resides in "Service" folder.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using UnityIoC;
using System.ComponentModel.Composition; 

namespace TestUnityIoC
{
    [Export(typeof(IRegistrationType))]
    public class IoCContainerInit : IRegistrationType
    {
        #region "Variables"
        #endregion

        #region "Properties"
        #endregion

        #region "Constructor"
        #endregion

        #region "Public/Protectd Methods"
        public void Initialize(ITypeRegistrar registrar)
        {
            registrar.RegisterType<ITestService, TestService>();
        }
        #endregion

        #region "Private/Helper methods"
        #endregion
    }
}

Step VI: Test the DI for type participating in IoC. The code in"HomeController"is depicted below.  Please see the constructor.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace TestUnityIoC.Controllers
{
    public class HomeController : Controller    {

        private ITestService testService;

        public HomeController(ITestService testServiceForDI)
        {
            testService = testServiceForDI;
        }
        public ActionResult Index()
        {
            return View();
        }
        public ActionResult About()
        {
            ViewBag.Message = "Your application description page.";

            return View();
        }
        public ActionResult Contact()
        {
            ViewBag.Message = "Your contact page.";

            return View();
        }
    }
}

So far so good. Let’s try executing it.

Oops!!! It is not running successfully. What went wrong?



Mostly it looks like that the CLR is not able to find the type mapping. Please see the Fig#2 for the pattern. "TestUnityIoC.*.dll" is the root cause. The assembly is not found where types are registered.

It needs to be corrected as following.

using System.Web;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using UnityIoC;

namespace TestUnityIoC
{
    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            Bootstrapper.Initialise(".\\bin", "TestUnityIoC.dll");

        }
    }
}


And now, executing the projects, yields following result.


Conclusion and Summary

This small library offers ability to types themselves to be declared for registered for DI. Though this also needs an initialize or class for registration of all types in an assembly, the common file at solution level (centralized registration) is not needed more for carrying out the type registration. This also helps to give the ability for type registration to the assembly writers. This eliminates the need to compile the assembly containing centralized registration and just need of compile the assembly containing types.

Though this way multiple class constructs would be needed at different participating assemblies, dependency on centralized registration is eliminated.

This is very crude implementation and could be refined as discussed in future direction.

PS:The dll for library is attached for usage.

Future Direction 

Following enhancements can be done

1.       Add ability to look for multiple patterns for looking up for dlls.

2.     Add an ability to declare the IoC participation at the type level rather than through separate class construct at assembly level. This can be achieved through some custom attribute.

3.      Decide upon the webactivator constructs in Unity , as of now it is part of dll but not exposed.

Recommendation
Read Custom authentication filter in ASP.NET MVC after this article.
Page copy protected against web site content infringement by Copyscape

About the Author

Vishvvas
Full Name: Vishwas Sutar
Member Level: HonoraryPlatinum
Member Status: Member,MVP
Member Since: 5/30/2011 2:13:10 AM
Country: India

http://www.dotnetfunda.com
Extensive and rich experience across gamut of technologies and programming languages like PB,VB,C++,VB.NET, C#, Classic ASP,ASP.NET, ASP.NET MVC.

Login to vote for this post.

Comments or Responses

Posted by: Ashuthinks on: 9/26/2015 | Points: 25
Fantastic ,
I have used Autofac for DI , this is something new to go through , thanks for sharing.
Posted by: Sheonarayan on: 12/26/2015 | Points: 25
Nice step by step article on DI, Thanks Vishwas.

Login to post response

Comment using Facebook(Author doesn't get notification)