Dependency Injection using the ASP.NET MVC Framework 2.0

Introduction

The Dependency Injection Pattern is one of the most widely used and popular design patterns that can reduce dependencies amongst the components of your application, a technique in which the concerns in an application are injected externally as they are needed. This article discusses the basics of Dependency Injection pattern and shows how to use Dependency Injection together with ASP.NET MVC Framework to design loosely coupled and testable objects in your application

Pre-requisites

To execute the code examples illustrated in this article, you should have the following installed in your system:

  • ASP.NET MVC 2.0
  • Microsoft Visual Studio 2008

Alternatively, you can have Microsoft Visual Studio 2010 installed in your system--you'll get the ASP.NET MVC Framework and the necessary templates you need to work embedded there.

What is Dependency Injection Pattern?

The Dependency Injection Pattern is a popular design technique that can be used to implement loosely coupled, reusable, and testable objects in your software designs by reducing the cohesion amongst the components in your application. You can implement dependency injection in your applications to promote loose coupling, centralized configuration and make your application easier to test and maintain. The Wikipedia states: "Dependency injection (DI) in object-oriented computer programming is a technique for supplying an external dependency (i.e. a reference) to a software component - that is, indicating to a part of a program which other parts it can use. It is a specific form of inversion of control where the concern being inverted is the process of obtaining the needed dependency."

Reference: http://en.wikipedia.org/wiki/Dependency_injection

Types of Dependency Injection

Dependency Injection can be one of the following types:

  1. Constructor Injection
  2. Setter Injection
  3. Interface-based injection

You can learn more about dependency injection from my article here: http://www.devx.com/dotnet/Article/34066/1954

Understanding the Model View Controller Design Pattern

The Model View Controller is one of the most popular and widely used of all design patterns. It is used to facilitate testability, promote a cleaner separation of concerns and also for easier maintenance of the application's code. It should be noted that an application's concern can be of two types--the core concerns (these include the application's business logic and data access logic, etc) and cross cutting concerns (these include logging, exception handling, messaging, etc).

The Model View Controller Design Pattern is comprised of the following three core components:

Model - it is the component that is responsible for handling the application's business logic and data access components.

The View - it is the component that is responsible for presenting the model's data in the user interface.

The Controller - it is the component that manages the interaction amongst the other components and invalidates the View based on the Model's state.

What is the ASP.NET MVC Framework?

The ASP.NET MVC Framework is based on the proven time tested MVC Design Pattern and provides you a platform for designing and implementing web applications where you can have a cleaner separation of concerns, better code organization, seamless extensibility, scalability and code reuse. Applications designed using the ASP.NET MVC Framework are easier to test and maintain. Scott Guthrie states in his blog: "One of the benefits of using an MVC methodology is that it helps enforce a clean separation of concerns between the models, views and controllers within an application. Maintaining a clean separation of concerns makes the testing of applications much easier, since the contract between different application components are more clearly defined and articulated." Reference: http://weblogs.asp.net/scottgu/archive/2007/10/14/aspnet-mvc-framework.aspx.

Using Dependency Injection with ASP.NET MVC Application

You can use dependency injection to inject concrete implementation into the controllers in your ASP.NET MVC applications. This would help you to decouple the application's components, making them easily testable and maintainable.

Now, the DefaultControllerFactory class in ASP.NET MVC framework doesn't support passing dependencies. So, if you need to inject dependencies to your controller, here's what you can do:

  public class StudentController : Controller 
  { 
   
      private IDependency dependency; 
   
      public StudentController() : this(new Dependency()) 
      { 
      } 
   
      public StudentController(IDependency dependency) 
      { 
          this.dependency = dependency; 
      } 
  }

So, you need to use custom dependency injection factories to inject dependencies and make your application's code flexible. You can easily combine your ASP.NET MVC application with Unity or any other IOC container to make your application easily testable, manageable and scalable. There are plenty of dependency injection containers available. Here's a list of the most commonly used out of them:

  • Castle Windsor
  • StructureMap
  • Spring.NET
  • Unity
  • Puzzle.NFactory
  • Ninject
  • PicoContainer.NET

Let's assume you are using the Unity IOC container to inject dependencies to your ASP.NET MVC applications. Unity is a light weight, extensible dependency injection container from Microsoft that provides support for interception, constructor injection and property injection. Unity is freely available from CodePlex. Here's the link to download Unity container from CodePlex: http://unity.codeplex.com/

Here's how you can extend the System.Web.Mvc.DefaultControllerFactory to create your controller factory:

  using System;
  using System.Data;
  using System.Configuration;
  using System.Linq;
  using System.Web;
  using System.Web.Security;
  using System.Web.UI;
  using System.Web.UI.HtmlControls;
  using System.Web.UI.WebControls;
  using System.Web.UI.WebControls.WebParts;
  using System.Xml.Linq;
  using Microsoft.Practices.Unity;
  using System.Web.Mvc;
  
  public class UnityControllerFactory : DefaultControllerFactory
       {
              IUnityContainer unityContainer;
  
              public UnityFactory(IUnityContainer container)
              {
                  unityContainer = container;
              }
  
              protected override IController GetControllerInstance(Type controllerType)
              {
                  if (controllerType!= null)
                      return unityContainer.Resolve(controllerType) as IController;
                  else
                      throw new ArgumentNullException("Controller Type is not supported.");
              }
      }

You can then use the above controller factory in lieu of the default controller factory. To do this, you need to create the Unity container and specify the UnityControllerFactory in lieu of the default in your application's Global.asax file. Here's how you can do it:

  using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Web;
  using System.Web.Mvc;
  using System.Web.Routing;
  using Microsoft.Practices.Unity;
  using MvcDI.Models;
  namespace StudentAdministrationSystem
  {
      public class MvcApplication : System.Web.HttpApplication
      {
          public static void RegisterRoutes(RouteCollection routes)
          {
              routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
              routes.MapRoute(
                  "Default",    // Route name
                  "{controller}/{action}/{id}",  // URL with parameters
                //Specifies the Controller and the Action.
                  new { controller = "Student", 
  			action = "ViewStudent", id = "" } // Parameter defaults
              );
          }
          protected void Application_Start() 
        	{ 
   	   IUnityContainer unityContainer = new UnityContainer(); 
   	   IControllerFactory unityControllerFactory = new UnityControllerFactory(unityContainer); 
  ControllerBuilder.Current.SetControllerFactory(unityControllerFactory); 
     	   RegisterRoutes(RouteTable.Routes);
  	}
      }
  }

The best thing in Unity IOC container is that you wouldn't have to add the controller class to the UnityContainer to create an instance of the controller class along with all of its dependencies.

The following code snippet illustrates how you can use property setter injection in your controller class:

  public class HomeController : Controller
  {
      [Dependency]
      public IStudentDataService StudentDataService { get; set; }
  
      [ControllerAction]
      public void Index()
      {
          List<Student> students = StudentDataService.GetStudentData();
          RenderView("Index", students);
      }
  }

Here's how you can achieve the same using constructor injection:

  public class HomeController : Controller
  {
      private IStudentDataService studentDataService;
      
      public HomeController(IStudentDataService studentDataService)
      {
          this.studentDataService = studentDataService;
      }
  
      [ControllerAction]
      public void Index()
      {
         List<Student> students = studentDataService.GetStudentData();
          RenderView("Index", students);
      }
  }

You would of course need to register the StudentDataService in your UnityContainer in your Global.asax file:

  Container.Register<IStudentDataService, StudentDataService>();

You can also use dependency injection in your controller class to attach repositories as shown in the following code snippet:

public class HomeController : Controller
    {
        protected IStudentRepository studentRepository = null;
        protected IAccountsRepository accountsRepository = null;

        public HomeController(IStudentRepository studentRepository,
            IAccountsRepository accountsRepository)
        {
            this.studentRepository = studentRepository;
            this.accountsRepository = accountsRepository;
        }

 public ActionResult Index()
        {
            return View(studentRepository.ListAllStudents());
        }

  //Other methods
}

The above is an example of constructor injection--you can see the repositories being injected in the constructor of the HomeController class.

Summary

The Wikipedia states: "Inversion of Control, or IoC, is an abstract principle describing an aspect of some software architecture designs in which the flow of control of a system is inverted in comparison to procedural programming. In traditional programming the flow is controlled by a central piece of code. Using Inversion of Control this central control as a design principle is left behind. Although the caller will eventually get its answer, how and when is out of control of the caller. It is the callee who decides how and when to answer." Reference: http://en.wikipedia.org/wiki/Inversion_of_control The Dependency Injection pattern can help you design applications where the architecture links the components rather than the components linking themselves. In essence, if you use the Dependency Injection pattern with the ASP.NET MVC framework, you can easily implement web applications where coupling between the application's components are minimal. In this article we discussed the Dependency Injection Design Pattern and why it is useful. We also discussed the ASP.NET MVC framework and how Dependency Injection Pattern can be used in conjunction with ASP.NET MVC framework to design and implement applications that are loosely coupled, extendable, reusable, and testable.

Suggested Readings

Here are a few good links to resources on this topic for further study:

http://www.asp.net/mvc
target="newFrame">http://dotnetslackers.com/articles/aspnet/a-first-look-at-asp-net-mvc-2.aspx http://msdn.microsoft.com/en-us/library/ee728598(v=VS.100).aspx

Related Articles



About the Author

Joydip Kanjilal

Microsoft Most Valuable Professional, Author and Speaker. Featured in "MSDN Featured Developer of the Fortnight (India)" a number of times. Winner of Community Credit Awards at www.community-credit.com several times. Authored numerous books and articles in Microsoft .NET and its related technologies. Authored the following books:-- ASP.NET 4.0 Programming (Mc-Graw Hill Publishing) Entity Framework Tutorial (Packt Publishing) Pro Sync Framework (APRESS) Sams Teach Yourself ASP.NET Ajax in 24 Hours (Sams Publishing) ASP.NET Data Presentation Controls Essentials (Packt Publishing)

Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: December 11, 2014 @ 1:00 p.m. ET / 10:00 a.m. PT Market pressures to move more quickly and develop innovative applications are forcing organizations to rethink how they develop and release applications. The combination of public clouds and physical back-end infrastructures are a means to get applications out faster. However, these hybrid solutions complicate DevOps adoption, with application delivery pipelines that span across complex hybrid cloud and non-cloud environments. Check out this …

  • Due to internal controls and regulations, the amount of long term archival data is increasing every year. Since magnetic tape does not need to be periodically operated or connected to a power source, there will be no data loss because of performance degradation due to the drive actuator. Read this white paper to learn about a series of tests that determined magnetic tape is a reliable long-term storage solution for up to 30 years.

Most Popular Programming Stories

More for Developers

RSS Feeds