Click here to Skip to main content
15,891,033 members
Articles / MVC / MVC3

Dependency Injection in MVC 3 Was Made Easier

Rate me:
Please Sign up or sign in to vote.
4.33/5 (5 votes)
18 Oct 2010CPOL2 min read 35.3K   8   9
Dependency Injection in MVC 3 was made easier

In the past, I wrote a post that showed how to implement Dependency Injection using Unity in ASP.NET MVC Framework. This post revisits that post and shows how you can do the same thing easily in MVC 3. Pay attention that the supplied code is based on MVC 3 beta and may change in the future.

The IDependencyResolver and DependencyResolver

MVC 3 introduces a new interface – the IDependencyResolver. This interface enables service location by providing two methods:

  • GetService(Type serviceType) – This method gets a service type and returns an object if the resolver succeeded in resolving the type. If the resolver couldn’t resolve the type, you must return null in order to activate the default MVC behavior.
  • GetServices(Type serviceType) – This method gets a service type and returns an IEnumerable<object> of all the resolved objects. If the resolver couldn’t resolve the type, you must return an empty collection to activate the default MVC behavior.

The DependencyResolver is a static class that you can use to register your custom IDependencyResolver. After you implement the IDependencyResolver, you set it in the DependencyResolver using one of the SetResolver overloaded methods. Then you will be able to use the Current property to get the current DependencyResolver in order to resolve types. If you don’t like to use the DependencyResolver ability, you need to implement nothing. There is default resolving behavior that is built inside the MVC implementation.

Building and Using a UnityDependencyResolver

Here is a simple implementation of a UnityDependencyResolver:

C#
public class UnityDependencyResolver : IDependencyResolver
{
    #region Members
   
    private IUnityContainer _container;    
   
    #endregion
   
    #region Ctor
   
    public UnityDependencyResolver(IUnityContainer container)
   {
      _container = container;
   }
    
   #endregion
    
   #region IDependencyResolver Members
    
   public object GetService(Type serviceType)
    {
     try
      {
       return _container.Resolve(serviceType);
      }
     catch (Exception ex)
      {
       return null;
      }
   }
    
   public IEnumerable<object> GetServices(Type serviceType)
    {
     try
      {
       return _container.ResolveAll(serviceType);
      }
     catch (Exception ex)
      {
       return new List<object>();
      }
   }
    
   #endregion
}

In order to use this resolver, the appropriate place to build the container is the Global.asax file. Here is the implementation:

C#
public class MvcApplication : System.Web.HttpApplication
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
   {
      filters.Add(new HandleErrorAttribute());
   }
    
   public static void RegisterRoutes(RouteCollection routes)
    {
     routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    
     routes.MapRoute(
          "Default", // Route name
         "{controller}/{action}/{id}", // URL with parameters
          new { controller = "Home", 
          action = "Index", id = UrlParameter.Optional } // Parameter defaults
     );    
   }
    
   protected void Application_Start()
    {
     AreaRegistration.RegisterAllAreas();
      
     RegisterGlobalFilters(GlobalFilters.Filters);
      RegisterRoutes(RouteTable.Routes);
     
      var container = InitContainer();
     DependencyResolver.SetResolver(new UnityDependencyResolver(container));       
    }
   
    private static IUnityContainer InitContainer()    
   {                   
      var container = new UnityContainer();        
   
      // Register the relevant types for the         
     // container here through classes or configuration                      
      container.RegisterType<IMessageService, MessageService>();
     return container;
    }
}

As you can see, I added the initialization of the container and also I set the DependencyResolver to the Unity implementation. The Message service and the controller are the same classes that I showed in my previous post:

C#
public interface IMessageService 
{ 
  string GetMessage();
}
 
public class MessageService : IMessageService
{
 #region IMessageService Members
 
 public string GetMessage()
  {
   return "Hello Controller!";
  }
 
  #endregion
}

and:

C#
public class HomeController : Controller
{
  #region Members     
 
  [Dependency]    
 public IMessageService MessageService { get; set; }
           
 #endregion
 
 #region Actions    
 
 public ActionResult Index()
  {
   ViewModel.Message = MessageService.GetMessage();
 
   return View();
  }
 
  public ActionResult About()
 {
    return View();
 }
 
 #endregion
}

After running this example, we will get the following expected result:

HomeController Result

Summary

Let's sum up, in MVC 3 beta, there is a new way to use DI and IoC containers by implementing the IDependencyResolver interface and registering it in the DependencyResolver static class. There are other injection points that you can use like the IControllerActivator which I’ll write about in a following post.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Technical Lead sparXys
Israel Israel
Gil Fink is a web development expert and ASP.Net/IIS Microsoft MVP. He is the founder and owner of sparXys. He is currently consulting for various enterprises and companies, where he helps to develop Web and RIA-based solutions. He conducts lectures and workshops for individuals and enterprises who want to specialize in infrastructure and web development. He is also co-author of several Microsoft Official Courses (MOCs) and training kits, co-author of "Pro Single Page Application Development" book (Apress) and the founder of Front-End.IL Meetup. You can read his publications at his website: http://www.gilfink.net

Comments and Discussions

 
BugNot working properly Pin
Ucp-200918-Dec-12 22:58
Ucp-200918-Dec-12 22:58 
QuestionAuthorizeAttribute problem Pin
ILICHPOST19-Jul-12 14:01
ILICHPOST19-Jul-12 14:01 
QuestionHow do you inject a view Pin
Mike Wassermann 19414-Jun-12 11:17
professionalMike Wassermann 19414-Jun-12 11:17 
GeneralResolveAll doesn't return the default instance Pin
James Skimming23-Feb-11 4:04
James Skimming23-Feb-11 4:04 
GeneralMy vote of 5 Pin
Rouslan Grabar [Russ]26-Nov-10 1:35
Rouslan Grabar [Russ]26-Nov-10 1:35 
QuestionDI with Ninject? Pin
wayne_wolf4-Nov-10 10:00
wayne_wolf4-Nov-10 10:00 
AnswerRe: DI with Ninject? Pin
Gil Fink5-Nov-10 2:53
Gil Fink5-Nov-10 2:53 
Hi,

For dependency injection I use Unity or StructureMap so I'm not an expert in ninject.
What you need to understand is that the Unit of Work should exists per http request. This means that you configure the lifetime of the unit of work to be bound to the current HttpContext and dispose it when the context ends. You can see a very good example with an implementation of HttpLifetimeManager for Unity in this post: http://weblogs.asp.net/shijuvarghese/archive/2008/10/24/asp-net-mvc-tip-dependency-injection-with-unity-application-block.aspx (this example shows how to inject repositories).
I guess that there is a very close solution like this one in ninject.

I hope it will help you.
GeneralMy vote of 1 Pin
acidhorse3-Nov-10 5:18
acidhorse3-Nov-10 5:18 
GeneralRe: My vote of 1 Pin
Gil Fink3-Nov-10 6:03
Gil Fink3-Nov-10 6:03 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.