ASP.NET 依赖注入 HTTP 模块(MS 企业库)

2023-12-22

我一直按照“Microsoft Enterprise Library 5.0”文档中的步骤创建一个 HTTP 模块,将对 Enterprise Library 容器的引用注入到 ASP.NET Web 应用程序的页面中。

它包含以下代码(也出现在网上here http://msdn.microsoft.com/en-us/library/ff664534%28v=pandp.50%29.aspx):

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;
        }
      }
    }
  }
}

该代码及其附带的说明存在许多问题。

1)说明没有提到在哪里放置此代码。由于它是一个类,因此我将其放置在我的 ASP.NET 网站项目的 App_Code 文件夹中。

事实上,这是这段代码的说明:

创建一个新的 ASP.NET HTTP 模块类(例如,命名为 UnityHttpModule )在您的项目中捕获 PreRequestHandlerExecute 事件并执行遍历的代码 当前页面请求的完整控制树,应用Unity 每个控件的 BuildUp 方法。

2) The HttpContext.Current.Application.获取容器()方法对我来说不存在,即使我使用了相同的 DLL 引用(我在 .NET 4.0 中编码)。

3) OnPageInitComplete 事件引用了一个“上下文”变量...该变量似乎不存在于该上下文中。

关于我在这里缺少什么有什么想法吗?


似乎文档组织得很糟糕。

针对(2),没有解释的是,HttpContext.Current.Application.GetContainer()方法实际上是一个扩展方法,其实现方式如所示代码here http://msdn.microsoft.com/en-us/library/ff664704%28v=pandp.50%29.aspx.

要使用此扩展方法,您只需导入“Unity.Web”命名空间。

这是扩展方法的副本:

using System.Web;
using Microsoft.Practices.Unity;

namespace Unity.Web
{
  public static class HttpApplicationStateExtensions
  {
    private const string GlobalContainerKey = "EntLibContainer";

    public static IUnityContainer GetContainer(this HttpApplicationState appState)
    {
      appState.Lock();
      try
      {
        var myContainer = appState[GlobalContainerKey] as IUnityContainer;
        if (myContainer == null)
        {
          myContainer = new UnityContainer();
          appState[GlobalContainerKey] = myContainer;
        }
        return myContainer;
      }
      finally
      {
          appState.UnLock();
      }
    }
  }
}

关于依赖注入模块代码,我实际上只是使用了基本方法 http://msdn.microsoft.com/en-us/library/ff664622%28v=pandp.50%29.aspx用于获取容器的实例,就我而言,它也同样有效。文档说依赖注入 HTTP 模块代码提高了“可测试性”和“可发现性”,这有点模糊。

无论如何,这是基本方法的代码:

protected void Application_Start(object sender, EventArgs e)
{
  Application.Lock();
  try
  {
    var myContainer = Application["EntLibContainer"] as IUnityContainer;
    if (myContainer == null)
    {
      myContainer = new UnityContainer();
      myContainer.AddExtension(new EnterpriseLibraryCoreExtension());
      // Add your own custom registrations and mappings here as required
      Application["EntLibContainer"] = myContainer;
    }
  }
  finally
  {
    Application.UnLock();
  }
}          

因此,扩展代码就位,并且在我的 global.asax 文件中创建用于创建 Enterprise Library 容器实例的代码后,唯一要做的就是编写代码以根据需要获取容器实例。因此,当我想获取 LogWriter 类的实例时,我会这样写:

using Unity.Web;

public LogWriter getLogWriter()
{
    var container = HttpContext.Current.Application.GetContainer();
    return container.Resolve<LogWriter>();
}

需要 Unity.Web 命名空间来允许我们调用 GetContainer() 扩展方法。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ASP.NET 依赖注入 HTTP 模块(MS 企业库) 的相关文章

随机推荐