Aug 13

How to Inject Dependency in Action Filter

How to Inject Dependency in Action Filter

1.  Introduction

In designing an object-oriented application, a major tenet of design is “loose coupling”. Furthermore, an object’s dependencies should be on interfaces and not on “concrete” objects, when possible. Loose coupling promotes greater reusability, easier maintainability. “Dependency Injection” (DI), also more cryptically known as “Inversion of Control” (IoC), can be used as a technique for encouraging this loose coupling. There are two primary approaches to implementing DI: constructor injection and setter injection.
Constructor Injection:
Constructor Injection is the DI technique of passing an object’s dependencies to its constructor.
Setter Injection:
Setter Injection does not force dependencies to be passed to the constructor. Instead, the dependencies are set onto public properties exposed by the object in need. The primary motivators for doing this include:
1.       Supporting dependency injection without having to modify the constructor of a legacy class, and
2.       Allowing expensive resources or services to be created as late as possible and only when needed.
What is Service Locator?
Service Locator is a provider-driven abstract factory design pattern, which is be used to create instances of component servers. It supports configurable as well as run-time dependency injection.
Microsoft Unity Framework
The Unity Application Block (Unity) is a lightweight, extensible dependency injection container that supports constructor injection, property injection, and method call injection. It also facilitates building loosely coupled applications

2.  Description

As we learned the basic concept behind the Dependency injection and its usage in introduction. There are many ways to inject dependency in ASP.NET MVC i.e. through the Controller constructor or by creating property in controller. In ASP.NET MVC we are applying Action filter Attributes to Controller and Particular action or we can register the action filter in global register. This attribute generally don’t have any parameterized constructor. Suppose, I have created ActionExecutionTimerAttribute and registered into global action filter as below
   public class FilterConfig
   {
        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new HandleErrorAttribute());
            filters.Add(new ActionExecutionTimerAttribute());
        }
}
This function is called from global.asax.cs file as below.
   public class MvcApplication : System.Web.HttpApplication
   {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            AuthConfig.RegisterAuth();
            Bootstrapper.Initialise();
        }
}
Now, Let’s assume that my business service IActionExecutionTimerService has the business logic to log the information of Begin and End time of a particular action method. I have registered the interface and its service implementation mapping in Bootstrapper.cs file as below
   public static void RegisterTypes(IUnityContainer container)
   {
        container.RegisterType<IActionExecutionTimerService, ActionExecutionTimerService>();
   }
Now let’s create the ActionExecutionTimerAttribute attribute. In ActionExecutionTimerAttribute I will create the two constructors i.e. default and one parameterized constructor. In this I used DependencyResolver as the service locator to resolve dependency and type cast the service and implementation as below.
   Namespace MyApplication.Web.UI.Filters
   {
 [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
 public class ActionExecutionTimerAttribute : IActionFilter
 {
     private readonly IActionExecutionTimerService _actionExecutionTimerService = null;
     private long startTimeTics;
     private long endTimeTics;
     public ActionExecutionTimerAttribute()
         : this(DependencyResolver.Current.GetService(typeof(ActionExecutionTimerService) as IActionExecutionTimerService)
     {
       
     }
     public ActionExecutionTimerAttribute(IActionExecutionTimerService actionExecutionTimerService)
     {
         _actionExecutionTimerService = actionExecutionTimerService;
     }
     public void OnActionExecuting(ActionExecutingContext filterContext)
     {
         //  Business logic to track start timing
         startTimeTics = DateTime.Now.Ticks;
     }
     public void OnActionExecuted(ActionExecutedContext filterContext)
     {
         // Business logic to log
         endTimeTics = DateTime.Now.Ticks;
                var controllerName = filterContext.RouteData.Values[“controller”].ToString();
         var actionName = filterContext.RouteData.Values[“action”].ToString();
         var actionExecutionTimer = new ActionExecutionTimer
         {
             Controller = controllerName,
             Action = actionName,
             StartTime = startTimeTics,
             EndTime = endTimeTics
         };
         _actionExecutionTimerService.Insert(actionExecutionTimer);
     }
 }
}
In this way the GetService() method used to resolve singly registered services that support arbitrary object creation.

3.  Summary

In this article we learned what is Dependency injection, methods to inject dependency , Service Locator and Microsoft Unity framework to inject dependency. I hope this article would help you to understand and use dependency injection in MVC action filters.

Leave a Reply