ASP.NET Dependency Injection HTTP Module
You can use an HTTP module, an extension to the ASP.NET HttpApplicationState class, and code in Global.asax to force ASP.NET to automatically inject dependent objects at every page request, as discussed in the topic ASP.NET Web Forms Applications.
The following code shows a suitable HTTP module that captures the PreRequestHandlerExecute event to insert itself into the ASP.NET execution pipeline. On each page request, the handler resolves the current HTTP handler through the container using the BuildUp method and then captures the OnPageInitComplete event. When the OnPageInitComplete executes, the module code walks the complete control tree, resolving each control through the container using the BuildUp method.
The BuildUp method takes an existing object instance, resolves and populates any dependencies specified for the class, and then returns the instance. If there are no dependencies, it simply returns the original instance.
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;
}
}
}
}
}
'Usage
Imports System
Imports System.Collections.Generic
Imports System.Web
Imports System.Web.UI
Imports Microsoft.Practices.Unity
Namespace Unity.Web
Public Class UnityHttpModule
Implements IHttpModule
Public Sub Init(ByVal context As HttpApplication) _
Implements System.Web.IHttpModule.Init
AddHandler context.PreRequestHandlerExecute, AddressOf OnPreRequestHandlerExecute
End Sub
Public Sub Dispose() Implements System.Web.IHttpModule.Dispose
End Sub
Private Sub OnPreRequestHandlerExecute(ByVal sender As Object, ByVal e As EventArgs)
Dim currentHandler As IHttpHandler = HttpContext.Current.Handler
HttpContext.Current.Application.GetContainer().BuildUp( _
currentHandler.[GetType](), currentHandler)
' User Controls are ready to be built up after page initialization is complete
Dim currentPage = TryCast(HttpContext.Current.Handler, Page)
If Not currentPage Is Nothing Then
AddHandler currentPage.InitComplete, AddressOf OnPageInitComplete
End If
End Sub
' Build up each control in the page's control tree
Private Sub OnPageInitComplete(ByVal sender As Object, ByVal e As EventArgs)
Dim currentPage = DirectCast(sender, Page)
Dim container As IUnityContainer = _ HttpContext.Current.Application.GetContainer()
For Each c As Control In GetControlTree(currentPage)
container.BuildUp(c.[GetType](), c)
Next
RemoveHandler context.PreRequestHandlerExecute, AddressOf OnPreRequestHandlerExecute
End Sub
' Get the controls in the page's control tree excluding the page itself
Private Function GetControlTree(ByVal root As Control) As IEnumerable(Of Control)
Dim controlList As New List(Of Control)
For Each child As Control In root.Controls
If child Is Nothing Then
Exit For
Else
controlList.Add(child)
End If
For Each c As Control In GetControlTree(child)
If child Is Nothing Then
Exit For
Else
controlList.Add(child)
End If
Next
Next
Return controlList
End Function
End Class
End Namespace