Quantcast
Channel: Gil Fink's Blog
Viewing all articles
Browse latest Browse all 95

Dependency Injection in MVC 3 Was Made Easier

$
0
0

Dependency Injection in MVC 3 Was Made Easier

In the past I wrote apost that showed how to implement Dependency InjectionDependency Injection in MVC 3 Was Made Easierusing 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:

publicclass UnityDependencyResolver : IDependencyResolver
{
#region Members
private IUnityContainer _container;    
#endregion
#region Ctor
public UnityDependencyResolver(IUnityContainer container)
    {
      _container = container;
    }
#endregion
#region IDependencyResolver Members
publicobject GetService(Type serviceType)
    {
try
      {
return _container.Resolve(serviceType);
      }
catch (Exception ex)
      {
returnnull;
      }
    }
public IEnumerable<object> GetServices(Type serviceType)
    {
try
      {
return _container.ResolveAll(serviceType);
      }
catch (Exception ex)
      {
returnnew 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:

publicclass MvcApplication : System.Web.HttpApplication
{
publicstaticvoid RegisterGlobalFilters(GlobalFilterCollection filters)
    {
      filters.Add(new HandleErrorAttribute());
    }
publicstaticvoid 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
      );
    }
protectedvoid Application_Start()
    {
      AreaRegistration.RegisterAllAreas();
      RegisterGlobalFilters(GlobalFilters.Filters);
      RegisterRoutes(RouteTable.Routes);
      var container = InitContainer();
      DependencyResolver.SetResolver(new UnityDependencyResolver(container));       
    }
privatestatic 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:

publicinterface IMessageService 
{ 
string GetMessage();
}
 
publicclass MessageService : IMessageService
{
#region IMessageService Members
 
publicstring GetMessage()
  {
return"Hello Controller!";
  }
 
#endregion
}

and

publicclass 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 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.


Viewing all articles
Browse latest Browse all 95

Trending Articles