The World’s Leading Microsoft .NET Magazine
   
 
The .NET Addict's Blog

My Top Tags

                                                           

My RSS Feeds








I heart FeedBurner

Latest Diggs - Programming

Computers Blogs - Blog Top Sites

Site Hits

Total: 4,741,459
since: 19 Jan 2005

Upgrading the default ASP.NET MVC project with IoC and the Unity Controller Factory

posted Mon 04 May 09

The ASP.NET MVC framework is one of the coolest things to happen to ASP.NET since its creation. One of the things that I love about the MVC framework more than anything else is its flexibility. This flexibility allows it to be configured anyway the developer likes, including replacing the factory that creates controllers.

There are two main things that I wanted to accomplish with the Unity integration. The first was that I wanted my controllers to have the objects on which they depend injected into them in standard DI fashion. Secondly, I wanted the controllers themselves to be resolved through the IoC container rather than being tightly coupled by the routing rules. This would allow me to yank in and out different controller implementations if I need to (I figured this would come in quite handy for TDD and unit testing).

The first part is easy, just grab the Unity DLLs and reference them in your MVC project. At this point, you're now free to use Unity to inject whatever you feel like. Rigging up the controller factory so that it will use Unity to resolve controllers is equally easy because the mvc contrib codeplex site has already created a class called UnityControllerFactory that does just this. Once you've added references to Unity and Mvc.Contrib.Unity from your MVC project, you can change your global.asax.cs file to look something like this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using MvcContrib.Unity;
using Microsoft.Practices.Unity;
using UlyssesAgenda.Controllers;
using System.Web.Security;

namespace UlyssesAgenda
{
    // Note: For instructions on enabling IIS6 or IIS7 classic mode,
    // visit http://go.microsoft.com/?LinkId=9394801

    public class UlyssesApplication : HttpApplication, IUnityContainerAccessor
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.IgnoreRoute("{filename}.ico"); // IE8 requests this and it tries to hit a controller for it.
            //routes.IgnoreRoute("{filename}.png");

            routes.MapRoute(
                "Default",                                              // Route name
                "{controller}/{action}/{id}",                           // URL with parameters
                new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
            );

        }

        protected void Application_Start()
        {
            InitializeContainer();
            RegisterRoutes(RouteTable.Routes);           
        }

        protected virtual void InitializeContainer()
        {
            if (_container == null)
            {
                _container = new UnityContainer();             
                ControllerBuilder.Current.SetControllerFactory(typeof(UnityControllerFactory));                               
               
                _container.RegisterType(typeof(HomeController), typeof(HomeController));
                _container.RegisterInstance(typeof(AccountController), new AccountController());               
            }
        }
       
        #region IUnityContainerAccessor Members

        private static UnityContainer _container;

        public static IUnityContainer Container
        {
            get { return _container; }
        }

        IUnityContainer IUnityContainerAccessor.Container
        {
            get { return Container; }
        }
        #endregion
    }
}

You'll notice that I mapped the HomeController type and allowed Unity to manage the instantiation of it. However, with AccountController I created my own instance. The main reason for this is that account controller relies directly upon a service which relies upon a SqlMembershipProvider instance. If I attempt to constructor-inject the AccountController, I get stuck in a quagmire where I have to register my own instances of SqlMembershipProvider and SqlProfileProvider and much more - and that removes the flexibility I get from defining that stuff in the Web.config file (and potentially breaks other ASP.NET functionality by not having it in that file).. So (just this once!) I am allowing the AccountController to be a manually created instance that is injected by Unity.

Next, I'll be posting about how to convert the default Unit Tests for the AccountController into tests that use Moq rather than hand-mocked POCOs.

tags:          

links: digg this    del.icio.us    technorati    reddit

AddThis Social Bookmark Button




1. Craig left...
Wed 13 May 09 2:41 pm :: http://www.typemismatch.com/

Why would you want to do this? What is the use case for wanting your own controller factory? It has already started causing problems, i.e. membership etc - what was your reasoning? :)


2. Kevin Hoffman left...
Wed 13 May 09 2:43 pm

I don't really have to explain why Inversion of Control and Dependency Injection is a good thing, do I?? :)


3. Craig left...
Thu 14 May 09 3:50 pm

Yup .. seriously - I love keeping things simple and so to me IoC and DI is abstraction on steroids and only java developers should use it ;-) Seems like engineering for the sake of engineering or maybe I'm thick :P


4. Roman left...
Fri 07 Aug 09 1:17 pm :: http://romanroz.blogspot.com

Kevin, how are u handling lifetime of the controllers. The default is transient lifetime manager. Is that sufficient for asp.net mvc?


5. Lee Smith left...
Sat 16 Jan 10 8:05 pm :: http://mvcunity.codeplex.com/

I've just added this project to codeplex: http://mvcunity.codeplex.com/

It may save someone some work.


Tag Related Posts

Html.JqGrid - Cleaning up your jqGrid Code

Tue 22 Dec 09 8:46 P GMT-05
tags:              

How to Build your First Azure-Powered MVC App

Tue 29 Sep 09 2:16 P GMT-05
tags:        

ViewState is the Froo-It of the Dev-Il

Wed 23 Sep 09 3:09 P GMT-05
tags:      

Fix for Minor Bug in ASP.NET MVC New Project Template

Mon 04 May 09 2:48 A GMT-05
tags:      

NYC SharePoint Developer Needed

Mon 12 May 08 12:09 P GMT-05

Scott Guthrie Updates the ASP.NET MVC Roadmap

Wed 13 Feb 08 3:49 P GMT-05
tags:    

Volta is to Ajax what Tums is to my Stomach

Wed 30 Jan 08 4:11 P GMT-05

ASP.NET 3.5 Extensions Preview Released

Mon 10 Dec 07 2:10 P GMT-05

Microsoft unveils an MVC framework for ASP.NET

Mon 08 Oct 07 12:58 P GMT-05
tags:      

Exploring the MVC Pattern in WPF

Tue 10 Apr 07 12:51 P GMT-05
tags:                      

ASP.NET Ajax v1.0 Beta

Fri 27 Oct 06 6:17 P GMT-05
tags:      

ASP.NET vs Ruby on Rails : Round 2 (Agility)

Thu 05 Oct 06 11:02 A GMT-05
tags:                      

ASP.NET vs Ruby on Rails : Round 1

Wed 04 Oct 06 1:37 P GMT-05
tags: