Dependency Injection in ASP.NET MVC NerdDinner App using Unity 2.0

In my previous post Dependency Injection in ASP.NET MVC NerdDinner App using Ninject, we did dependency injection in NerdDinner application using Ninject. In this post, I demonstrate how to apply Dependency Injection in ASP.NET MVC NerdDinner App using Microsoft Unity Application Block (Unity) v 2.0.

Unity 2.0

Unity 2.0 is available on Codeplex at http://unity.codeplex.com . In earlier versions of Unity, the ObjectBuilder generic dependency injection mechanism, was distributed as a separate assembly, is now integrated with Unity core assembly. So you no longer need to reference the ObjectBuilder assembly in your applications. Two additional Built-In Lifetime Managers - HierarchicalifetimeManager and PerResolveLifetimeManager have been added to Unity 2.0.

Dependency Injection in NerdDinner using Unity

In my Ninject post on NerdDinner, we have discussed the interfaces and concrete types of NerdDinner application and how to inject dependencies through controller constructors. The following steps will configure Unity 2.0 to apply controller injection in NerdDinner application.

Step 1 – Add reference for Unity Application Block

Open the NerdDinner solution and add  reference to Microsoft.Practices.Unity.dll and Microsoft.Practices.Unity.Configuration.dll
You can download Unity from at http://unity.codeplex.com .

Step 2 – Controller Factory for Unity

The controller factory is responsible for creating controller instances.We extend the built in default controller factory with our own factory for working Unity with ASP.NET MVC.

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;

    }

 

}

 

public static class MvcUnityContainer

{

    public static IUnityContainer Container { get; set; }

}

 

Step 3 – Register Types and Set Controller Factory

private void ConfigureUnity()

{

    //Create UnityContainer          

    IUnityContainer container = new UnityContainer()

    .RegisterType<IFormsAuthentication, FormsAuthenticationService>()

    .RegisterType<IMembershipService, AccountMembershipService>()

    .RegisterInstance<MembershipProvider>(Membership.Provider)

    .RegisterType<IDinnerRepository, DinnerRepository>();

    //Set container for Controller Factory

    MvcUnityContainer.Container = container;

    //Set Controller Factory as UnityControllerFactory

    ControllerBuilder.Current.SetControllerFactory(

                        typeof(UnityControllerFactory));           

}

Unity 2.0 provides a fluent interface for type configuration. Now you can call all the methods in a single statement.The above Unity configuration specified in the ConfigureUnity method tells that, to inject instance of DinnerRepositiry when there is a request for IDinnerRepositiry and  inject instance of FormsAuthenticationService when there is a request for IFormsAuthentication and inject instance of AccountMembershipService when there is a request for IMembershipService. The AccountMembershipService class has a dependency with ASP.NET Membership provider. So we configure that inject the instance of Membership Provider.

After the registering the types, we set UnityControllerFactory as the current controller factory.

//Set container for Controller Factory

MvcUnityContainer.Container = container;

//Set Controller Factory as UnityControllerFactory

ControllerBuilder.Current.SetControllerFactory(

                    typeof(UnityControllerFactory));


When you register a type  by using the RegisterType method, the default behavior is for the container to use a transient lifetime manager. It creates a new instance of the registered, mapped, or requested type each time you call the Resolve or ResolveAll method or when the dependency mechanism injects instances into other classes.

The following are the LifetimeManagers provided by Unity 2.0


ContainerControlledLifetimeManager - Implements a singleton behavior for objects. The object is disposed of when you dispose of the container.

ExternallyControlledLifetimeManager - Implements a singleton behavior but the container doesn't hold a reference to object which will be disposed of when out of scope.

HierarchicalifetimeManager - Implements a singleton behavior for objects. However, child containers don't share instances with parents.

PerResolveLifetimeManager - Implements a behavior similar to the transient lifetime manager except that instances are reused across build-ups of the object graph.

PerThreadLifetimeManager - Implements a singleton behavior for objects but limited to the current thread.

TransientLifetimeManager - Returns a new instance of the requested type for each call. (default behavior)

We can also create custome lifetime manager for Unity container. The following code creating a custom lifetime manager to store container in the current HttpContext.

public class HttpContextLifetimeManager<T> : LifetimeManager, IDisposable

{

    public override object GetValue()

    {

        return HttpContext.Current.Items[typeof(T).AssemblyQualifiedName];

    }

    public override void RemoveValue()

    {

        HttpContext.Current.Items.Remove(typeof(T).AssemblyQualifiedName);

    }

    public override void SetValue(object newValue)

    {

        HttpContext.Current.Items[typeof(T).AssemblyQualifiedName]

            = newValue;

    }

    public void Dispose()

    {

        RemoveValue();

    }

}


 Step 4 – Modify Global.asax.cs for configure Unity container

 In the Application_Start event, we call the ConfigureUnity method for configuring the Unity container and set controller factory as UnityControllerFactory

void Application_Start()

{

    RegisterRoutes(RouteTable.Routes);

 

    ViewEngines.Engines.Clear();

    ViewEngines.Engines.Add(new MobileCapableWebFormViewEngine());

    ConfigureUnity();

}



Download Code

You can download the modified NerdDinner code from http://nerddinneraddons.codeplex.com


Published Friday, May 7, 2010 12:59 AM by shiju
Filed under: , ,

Comments

# re: Dependency Injection in ASP.NET MVC NerdDinner App using Unity 2.0

Friday, May 7, 2010 3:21 AM by <a href="http://www.richonet.com/">RamPravesh</a>

its really helpful

Thanks

# re: Dependency Injection in ASP.NET MVC NerdDinner App using Unity 2.0

Friday, May 7, 2010 12:06 PM by Koen Rouwhorst

thanks, useful article!

# re: Dependency Injection in ASP.NET MVC NerdDinner App using Unity 2.0

Sunday, May 16, 2010 7:39 AM by Thanigainathan

Hi,

Does Microsoft.Net doesn't provide a better dependency injection ? Why we need to go for a third party here ?

Thanks,

Thanigainathan.S

# re: Dependency Injection in ASP.NET MVC NerdDinner App using Unity 2.0

Sunday, May 16, 2010 11:05 PM by shiju

@Thanigainathan - Unity is descent DI framework from Microsoft

# re: Dependency Injection in ASP.NET MVC NerdDinner App using Unity 2.0

Monday, May 17, 2010 3:11 AM by tomekst

Very nice, I really this concept of extending Nerd Dinner. Hope you continue to take this further...

# re: Dependency Injection in ASP.NET MVC NerdDinner App using Unity 2.0

Thursday, May 20, 2010 11:13 PM by shiju

@Anders - Thanks for pointing this. I have updated the codeplex repository with Global.asax.cs file

# re: Dependency Injection in ASP.NET MVC NerdDinner App using Unity 2.0

Wednesday, October 13, 2010 7:26 PM by kilonet

good article, Shiju

however in my case IUnityContainer.Resolve method looks like (System.Type, string, params Microsoft.Practices.Unity.ResolverOverride[]) (and no overloads). it seems wired because I downloaded Unity from link at unity.codeplex.com. I'm quite frustrated...

# re: Dependency Injection in ASP.NET MVC NerdDinner App using Unity 2.0

Thursday, November 18, 2010 1:28 PM by Aaron

You call "Resolve" to get the controller, but I'm not seeing anywhere that you actually registered a controller...  Am I missing something?

# re: Dependency Injection in ASP.NET MVC NerdDinner App using Unity 2.0

Wednesday, January 5, 2011 12:38 AM by shuvo_haq

Don't we need to put [Dependency] for controller properties?

# re: Dependency Injection in ASP.NET MVC NerdDinner App using Unity 2.0

Wednesday, January 5, 2011 1:03 AM by shiju

@shuvo_haq - You don't have to put Dependency attribute for  constructor injection. This is only need for when you are doing property injection.

# re: Dependency Injection in ASP.NET MVC NerdDinner App using Unity 2.0

Friday, February 25, 2011 6:19 PM by Jason Wingfield

Nice job, this is exactly what I needed and it worked for me within 10 minutes!

# re: Dependency Injection in ASP.NET MVC NerdDinner App using Unity 2.0

Wednesday, July 25, 2012 1:09 AM by Vicentita

Hi Nag,Can you give me more details on what you try to acmscplioh? You can add a NestedList to views without a need to instantiate it in the initComponent, so be more precise.PS: about your token of friendship: I am glad if these posts helped you and the other guys and your comments keep me going.Although I must say that this blog does provide a way to show some special gratitude using that plugin right under the article which allows you to choose from FB like to paypal donation (the  Buy me a beer  button)

Leave a Comment

(required) 
(required) 
(optional)
(required)