Long overdue in the Unity series, how to use Unity in a web application. You can find the other posts here (Adding Interfaces), here (Registration by Convention), here (Injecting Values), here (Extensions), here (Aspect-Oriented Programming), here (Dependency Injection) and here (Introduction).
So, you want to store instances in the current web request, so that they are only available during the request. The problem is, there is no out of the box functionality in Unity that allows you to do that.
First, you will want to add the Unity.Mvc NuGet package:
This gives you a new lifetime manager, PerRequestLifetimeManager, which stores the request in the HttpContext.Current.Items collection. So, in the beginning of the request, you can register an instance using it:
Or you can also register a type, even in Application_Start, because it will only be resolved when explicitly asked for:
The problem with this approach is that entities instantiated by Unity that implement IDisposable will not be disposed of automatically at the end of the request. For that, we need something else: UnityPerRequestHttpModule. Since this is a regular IHttpModule, we can register it on the Web.config file. What it does is, at the end of the request, it iterates through all of the instances that Unity created using the PerRequestLifetimeManager which happen to be IDisposable and will dispose of them. Mind you, even if this comes in a package called Unity.Mvc, you can certainly use it with Web Forms.
This way, whenever MVC needs to resolve one of its components, it will delegate this to Unity.
ASP.NET MVC has the concept of filters, which offer a sort of Aspect-Oriented Programming model. Filters can be applied to either action methods or the whole controller, and can be of the following kind:
- Authentication Filters (IAuthenticationFilter);
- Authorization Filters (IAuthorizationFilter)
- Action Filters (IActionFilter);
- Result Filters (IResultFilter);
- Exception Filters (IExceptionFilter).
Normally, these filters are either applied through an attribute or globally. The UnityFilterAttributeFilterProvider class can be used to retrieve filters registered in Unity instead. You use it as:
If you have registered components that implement one of the filter interfaces, they will be injected automatically.
The class that MVC uses to create controllers is DefaultControllerFactory. It does its job by inspecting the well-known Controllers namespace of the containing web application assembly. We can create a class that inherits from DefaultControllerFactory and first tries to lookup the controller from Unity:
And for the registration:
Model binding occurs when you call an action method that takes as one of its parameters a class. MVC automatically creates a class of the proper type, but you can add Unity to the loop, in cases where it is not so easy to achieve. For example, consider an action method that receives an ILogger instance. By applying a custom model binder (IModelBinder), you can have MVC resolve it automatically:
You can add as many types as you like, MVC will try each of them until one returns a valid instance.