ASP.NET Dependency Injection HTTP Module

Topics: Enterprise Library Core
Dec 17, 2013 at 1:44 PM
Edited Dec 17, 2013 at 1:45 PM
I've been following the steps in the 'Microsoft Enterprise Library 5.0' documentation to create a HTTP module to inject a reference to the Enterprise Library container into the pages of ASP.NET web application.

It contains the following code (which also appears online here):
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using Microsoft.Practices.Unity;

namespace Unity.Web
{
  public class UnityHttpModule : IHttpModule
  {
    public void Init(HttpApplication context)
    {
      context.PreRequestHandlerExecute += OnPreRequestHandlerExecute;
    }

    public void Dispose() { }

    private void OnPreRequestHandlerExecute(object sender, EventArgs e)
    {
      IHttpHandler currentHandler = HttpContext.Current.Handler;
      HttpContext.Current.Application.GetContainer().BuildUp(
                          currentHandler.GetType(), currentHandler);

      // User Controls are ready to be built up after page initialization is complete
      var currentPage = HttpContext.Current.Handler as Page;
      if (currentPage != null)
      {
        currentPage.InitComplete += OnPageInitComplete;
      }
    }

    // Build up each control in the page's control tree
    private void OnPageInitComplete(object sender, EventArgs e)
    {
      var currentPage = (Page)sender;
      IUnityContainer container = HttpContext.Current.Application.GetContainer();
      foreach (Control c in GetControlTree(currentPage))
      {
        container.BuildUp(c.GetType(), c);
      }
      context.PreRequestHandlerExecute -= OnPreRequestHandlerExecute;
    }

    // Get the controls in the page's control tree excluding the page itself
    private IEnumerable<Control> GetControlTree(Control root)
    {
      foreach (Control child in root.Controls)
      {
        yield return child;
        foreach (Control c in GetControlTree(child))
        {
          yield return c;
        }
      }
    }
  }
}
There are a number of problems with this code and the instructions that came with it.

1) The instructions don't mention where to place this code. Since it is a class, I placed it in the App_Code folder of my ASP.NET website project.

In fact, here is the instructions for this bit of code:

Create a new ASP.NET HTTP module class (named, for example, UnityHttpModule ) in your project that captures the PreRequestHandlerExecute event and executes code that walks the complete control tree of the current page request, applying the Unity BuildUp method to each control.

2) The HttpContext.Current.Application.GetContainer() method does not exist for me, even though I have the same DLL references used (I'm coding in .NET 4.0).

3) The OnPageInitComplete event references a 'context' variable... which doesn't seem to exist in this context.

Any ideas on what I'm missing here?
Dec 18, 2013 at 5:54 AM
1) The instructions don't mention where to place this code. Since it is a class, I placed it in the App_Code folder of my ASP.NET website project.

It's up to you where to put it; you can put it in App_Code.
2) The HttpContext.Current.Application.GetContainer() method does not exist for me, even though I have the same DLL references used (I'm coding in .NET 4.0).

You also need the helper class, HttpApplicationStateExtensions, found at ASP.NET Application State Extension.
3) The OnPageInitComplete event references a 'context' variable... which doesn't seem to exist in this context.

I believe this is not required.

Here is a link to the original POC: Proof of Concept: a simple DI solution for ASP.NET WebForms.

Also you will need to register the HttpModule:
  <system.web>
    <httpModules>
      <add name="UnityHttpModule" type="Unity.Web.UnityHttpModule"/>
    </httpModules>
...
  </system.web>
~~
Randy Levy
entlib.support@live.com
Enterprise Library support engineer
Support How-to
Marked as answer by ciaran036 on 12/19/2013 at 6:00 AM
Dec 19, 2013 at 2:00 PM
Fantastic. Thanks Randy that's extremely helpful.
Jan 16, 2014 at 6:02 PM
Is it possible to do On-Demand dependency injection using Unity in MVC 5? I want to create a factory that will provide services from Unity’s IOC on-demand. That is, I want to control when/what object is returned from a Unity’s IOC via my factory. I have done some research and found this link in the Enterprise documentation.

http://msdn.microsoft.com/en-us/library/ff664358(v=pandp.50).aspx

But the example given is for Web Forms. Is there a way to do this in MVC 5?

Thank you
Al
Jan 17, 2014 at 7:07 AM
I think you are looking for Unity bootstrapper for ASP.NET MVC. This package provides a DependencyResolver for use with ASP.NET MVC. From the section Resolving in an MVC Application from The Developer's Guide to Dependency Injection Using Unity:

The usage in the MVC application is more sophisticated: the application configures a container that the application will use at start-up, and then resolves the various types as and when it needs them. Remember that this is an ASP.NET MVC application; therefore, the container must be able to inject the MVC controller classes with the various store and queue objects that they need. The “Unity bootstrapper for ASP.NET MVC” NuGet package (search for Unity3 in the NuGet package manager) simplifies this by adding libraries and source code to the project in Visual Studio.

~~
Randy Levy
entlib.support@live.com
Enterprise Library support engineer
Support How-to
Jan 17, 2014 at 1:21 PM
I am aware of the links you shared with me. What I am asking is I can do “on-demand” resolving of the objects in the Unity container in MVC 5?

Let’s say I have registered 5 interface/class pairs in Unity. I do constructor based injection for 2 objects I have registered via Unity/MVC 5 (as per the links you provided) into my Controllers.

Those 2 objects are factories that I can ask for the other 3 objects that are also in the container but were NOT in the constructor for that Controller. I want to pull those objects out of the Unity container myself with something like the following

IMyRepository myRepositoryInstance = container.Resolve<IMyRepository>();

According to the following link

http://msdn.microsoft.com/en-us/library/ff664622(v=pandp.50).aspx

In order to that in MVC I need to get a reference to the Unity container.

I need to place the container in an Application object and pull the container out of the Application object and then use the “container.Resolve” to get my objects (this is not in the above link but I assume so).

Is this the recommended way to do this in MVC 5 (The link above speaks to just to WebForms)?

Do I need to Lock the Application object when I am pulling out my objects out of the container with “container.Resolve”? I assume yes as the container may need to update itself with a new instance of the object being resolved….

There may be a significant performance hit since I will be locking the Application object frequently to get my objects…?

Is there a better way in MVC? Some kind of Service locator that would dip into the Unity container for me instead of me having to store the Unity container in an Application Object and pulling it out myself. Remember, I am trying to do “on-demand” resolution. The objects I want are NOT in the Controller constructor so the existing MVC/Unity framework would not have an opportunity to inject the object into the Controller.

I explored Property injection. But the real problem is getting a reference to the Unity container myself in MVC.

So can I do “on-demand” resolving of the objects in the Unity container in MVC 5?
Jan 18, 2014 at 7:59 AM
Is this the recommended way to do this in MVC 5 (The link above speaks to just to WebForms)?
No.
The typical approach is to inject directly the dependencies into the the constructor. Sometimes this is not possible (as in the case of the ASP.NET example you gave) and in those situations then property injection can be used.

The ASP.NET approach described is not preferred but is the way to use dependency injection in that model. ASP.NET MVC is designed with dependency injection in mind so you shouldn't need to do the same approach.

I think I understand your scenario but I'm not 100% clear on why the typical approach does not work in this case? Is there a reason why you can't create the entire object graph in the composition root at the beginning of the request (modifying the controller constructor)?

Consider the following:
    public class OrderController : Controller
    {
        public OrderController(ILogger logger, IOrderService orderService)
        {
        }
    }

    public class OrderService : IOrderService
    {
        public OrderService(IRepository<Order> orderRepository)
        {
        }
    }

    public class Repository<T> : IRepository<T>
    {
        public Repository(DbContext context)
        {
        }
    }
The entire object graph can be injected at once.

If you really need to register and resolve a class at runtime then the preferred mechanism is usually a factory or resolver overrides. Taking a dependency on the container tightly couples your application to the container which is not desirable.

For example let's say that the Controller might need to use one of three classes (A, B, C) based on some data available only at runtime. One approach would be to have the controller accept all possible objects that may be required (you can use Lazy<T> or Func<T> to avoid unnecessary object creation):
        public OrderController(Lazy<A> a, Lazy<B> b, Lazy<C> c)
        {
            this.a = a;
            this.b = b;
            this.c = c;
        }

        public void Do()
        {
            string runtimeData = GetData();

            if (runtimeData == "A")
            {
                string val = a.Value.GetValue();
            }
        }

Or you could encapsulate within a factory class:
    public class MyFactory
    {
        Lazy<A> a;
        Lazy<B> b;
        Lazy<C> c;
        public MyFactory(Lazy<A> a, Lazy<B> b, Lazy<C> c)
        {
            this.a = a;
            this.b = b;
            this.c = c;
        }

        // get appropriate object or perhaps expose A,B,C as getter properties
        public ILetter GetLetter(string val)
        {
            return a.Value;
        }
    }

// And inject the factory into the controller
        MyFactory myFactory;
        public OrderController(MyFactory factory)
        {
            myFactory = factory;
        }

Do I need to Lock the Application object when I am pulling out my objects out of the container with “container.Resolve”?
No, calls to Resolve are thread safe.

If your scenario is that you can't modify constructors or properties but can only modify the application code to retrieve objects and you really can't avoid using the container then you could create a global service locator (that has the container injected into it) to at least avoid having the application explicitly depend on a Unity container. Bear in mind that this is considered by many to be an anti-pattern.

~~
Randy Levy
entlib.support@live.com
Enterprise Library support engineer
Support How-to