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

标签 c# asp.net .net enterprise-library

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

它包含以下代码(也出现在网上 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;
        }
      }
    }
  }
}

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

1) 说明没有提到将此代码放在哪里。由于是一个类,所以我把它放在了我的ASP.NET网站项目的App_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) HttpContext.Current.Application.GetContainer() 方法对我来说不存在,即使我使用了相同的 DLL 引用(我正在编码在 .NET 4.0 中)。

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

关于我在这里缺少什么的任何想法?

最佳答案

似乎文档组织不当。

针对(2),没有解释的是HttpContext.Current.Application.GetContainer()方法实际上是一个扩展方法,它的实现就像所示的代码here .

要使用此扩展方法,您只需导入“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();
      }
    }
  }
}

关于依赖注入(inject)模块代码,其实我只是用了basic method用于获取容器的实例,就我而言,它也同样有效。文档说依赖注入(inject) 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 文件中编写了创建企业库容器实例的代码,剩下要做的唯一一件事就是编写代码以根据需要获取容器实例。所以当我想获取 LogWriter 类的实例时,我会这样写:

using Unity.Web;

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

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

关于c# - ASP.NET 依赖注入(inject) HTTP 模块(MS 企业库),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20632019/

相关文章:

c# - 如何在 asp.net c# 中使用 HashSet 比较两个数据集

c# - Wpf Dpi 和像素完美的 WriteableBitmap

由 C# 调整图像大小

c# - 在 C# 中获取和设置

c# - ASP.net 中的 OnCLick 问题

c# - Orchard Shape 类型 ResizeMediaUrl 未找到异常,MediaLibrary 组件不工作

C# 4.0 MemoryCache - 如何在对其依赖项进行更改时逐出依赖缓存条目

java - 为什么我的 Java RSA 加密会出现算术异常?

c# - SOAP,在上传 c# 时获取上传请求的进度

c# - 类型安全的枚举模式在 C# 6+ 版本中是否仍然可行