Thursday, 30 October 2014

MVC Filters With Dependency Injection


 
One of the most powerful features of the MVC OnRamp is the ability to have MVC Filters injected via our Inversion of Control (IoC) container, Castle.Windsor. There are several types of filters supported by ASP.NET MVC that allow you to handle orthogonal issues such as:
·         IExceptionFilter which is invoked whenever unhandled exceptions occur.
·         IActionFilter which is invoked just before and just after specific actions.
·         IAuthorizationFilter which is invoked when authorizing requests.
·         IResultFilter which is invoked on just before and just after results are returned.
Normally these filters are applied one of two ways:
·         Globally via specification in the App_Start, which can easily be resolved from the IoC container but which must be global in scope, and hence somewhat limiting.
·         Via Attribute on either a Controller or Action, which cannot be resolved from the IoC because we have no control over the instantiation of those attributes.
But MVC allows for another option, which is an IFilterProvider, this interface is called at the outset of any request, and is allowed to return at runtime instances of filters which are to be applied. Using this interface, we have created a class that resolves filters from within Castle.Windsor. Consider the following class:
public class IoCFilterProvider : IFilterProvider
{
    private readonly IEnumerable<Func<ControllerContext, ActionDescriptor, Filter>> registeredFilters;
 
    public IoCFilterProvider(Func<ControllerContext, ActionDescriptor, Filter>[] registeredFilters)
    {
        this.registeredFilters = registeredFilters;
    }
 
    public IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
    {
        return registeredFilters.Select(m => m.Invoke(controllerContext, actionDescriptor)).Where(m => m != null);
    }
}
This simple class takes as a dependencies an array of delegates, speficically an array of Func<> delegates which receive as parameters the ControllerContext and ActionDescriptor and which return an instance of the Filter class.
·         The ControllerContext class describes the controller that is about to be called.
·         The ActionDescriptor class describes the action on that controller which is about to be called.
Given this information, you can decide to either return a Filter which will be applied, or return a null which will take no action.

How do I register a filter?

In our FilterInstaller class you will see an example of registering such a filter:
public class FilterInstaller : IWindsorInstaller
{
    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        container.Register(
            Component.For<IFilterProvider>().ImplementedBy<IoCFilterProvider>(),
            Component.For<ExceptionLoggingFilter>().ImplementedBy<ExceptionLoggingFilter>(),
            Component.For<Func<ControllerContext,ActionDescriptor,Filter>>().Instance(
                (c,a) => new Filter(container.Resolve<ExceptionLoggingFilter>(), FilterScope.Last, int.MinValue))
            );
    }
}
On line 8, we register a Func<ControllerContext,ActionDescriptor,Filter> and state that we will provide a specific instance of that delegate to be used.
On line 9, we use the lambda syntax to declare a delegate, which is provided (c,a) as the parameters of type ControllerContext and ActionDescriptor, and which has a body of:
1
new Filter(container.Resolve<ExceptionLoggingFilter>(), FilterScope.Last, int.MinValue)
In this simple case, we create an instance of the System.Web.Mvc.Filter class and provide it our ExceptionLoggingFilter resolved from the container, and then tell the Filter to run in the FilterScope.Last, aka run this filter after all others, and order it within that scope using the int.MinValue, aka I really mean last of all last filters.
You can easily extend these registrations to include other filters by simply registering their delegates with the container and deciding when to return an instance of Filter and when to return null based on your business need. Our example always returns, because we want to always log exceptions, but that is not required. If your delegate examines the input data and determines it does not need to run a filter, simply return null.


Dependency Injection in MVC 4 using Ninject, Unity and StructureMap (IoCs)


Dependency injection is a software design pattern that allows removing hard-coded dependencies and making it possible to change them.
This software design pattern injects the depended-on element (object or value etc) to the destination automatically by knowing the requirement of the destination.
One of its core principles is the separation of behavior from dependency resolution.
source: Wikipedia.
A dependency is created when your application instantiate a class. Like this:
private MovieRepository _movieRepository = new MovieRepository();
The idea is to use an injector that “injects” this dependency into your application for you.
There are many Dependency Injection Containers also called Inversion of Control Containers (IoC) like:
  • Ninject. Free open source dependency injector for .NET
  • Unity. The Unity Application Block (Unity) is a lightweight extensible dependency injection container with support for constructor, property, and method call injection.
  • StructureMap. StructureMap is a Dependency Injection / Inversion of Control tool for .Net that can be used to improve the architectural qualities of an object oriented system by reducing the mechanical costs of good design techniques. StructureMap is released under the permissive Apache 2 OSS license.  You are free to download, modify, or redistribute StructureMap in any way you see fit  without restriction.
The following examples will use the injectors mentioned previously. It will be based on the Project used for the RepositoryPattern post in this blog.
To use Dependency Injection do the following changes:
1. In MoviesController first we will comment the dependency:
1
2
3
4
5
6
7
8
9
10
public class MoviesController : Controller
{
   // You don't instance a class. Big NO, NO.
   // private MovieRepository _movieRepository = new MovieRepository();
   public ViewResult Index()
   {
      return View(_movieRepository.GetMovies();
   }
}
2. Again in MovieController.cs we change the constructor like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class MoviesController : Controller
{
   // You don't instance a class. Big NO, NO.
   // private MovieRepository _movieRepository = new MovieRepository();
   private IMovieRepository _MovieRepository;
   // Constructor must be named exactly as the class
   public MoviesController(IMovieRepository MovieRepository)
   {
      _MovieRepository = MovieRepository
   }
   public ViewResult Index()
   {
      return View(_movieRepository.GetMovies();
   }
}
That concludes the common changes to use injectors. The following examples will explore 3 different dependency injectors.

Ninject Example.

In Visual Studio 2012 go to Tools\Library Package Manager\Manage NuGet Packages look for Ninject IoC Container for .NET, Ninject.MVC3 and Ninject.Web.Common. Add them to your Project.
In NinjectWebCommon.cs add the following code:
1
2
3
4
5
6
using MVCMovieTraining.Models;
private static void RegisterServices(IKernel kernel)
{
   Kernel.Bind<IMovieRepository>().To<MovieRepository>();
}

Unity Example.

If you already did the Ninject example, first delete the 3 references of Ninject and delete the file NinjectWebCommon.cs from App_Start. If not just go to the next step.
In Visual Studio 2012 go to Manage Nuget Packages and install Unity and Unity.MVC3
In Bootstrapper.cs don’t touch the Initialise method, just add the following code:
1
2
3
4
5
6
7
8
9
10
11
12
13
using MVCMovieTraining.Models;
namespace MVCMovieTraining
{
   ...
   private static IUnityContainer BuildUnityContainer()
   {
     var container = new UnityContainer();
     container.RegisterType<IMovieRepository, MovieRepository>(new HierarchicalLifetimeManager());
     return container;
   }
}
In Global.asax.cs call the Initialise method, put the line at the end of the Application_Start():
1
2
3
4
5
protected void Application_Start()
{
   ...
   Bootstrapper.Initialise();
}

StructureMap Example.

In Package Manager Console:
PM> Install-Package StructureMap.MVC4
Add a class in the root of the Project “BootStrapper.cs”
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
using StructureMap;
using StructureMap.Configuration.DSL;
using MVCMovieTraining.Models;
namespace MVCMovieTraining
{
   public class BootStrapper
   {
      public static void ConfigureDependencies()
      {
         ObjectFactory.Initialize(x => x.AddRegistry<ControllerRegistry());
      }
   }
   public class ControllerRegistry : Registry
   {
      public ControllerRegistry()
      {
         For<IMovieRepository>().Use<MovieRepository>();
      }
   }
}
To explore the 3 Dependency Injectors it’s better to start with the Project without Dependency Injection and copy it 3 times then start from there for each Dependency Injector. Otherwise you need to delete the changes made for the previous Dependency Injector.

Angular Tutorial (Update to Angular 7)

As Angular 7 has just been released a few days ago. This tutorial is updated to show you how to create an Angular 7 project and the new fe...