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

 天使不打雨伞_962 发布于 2023-02-09 20:15

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

它包含以下代码(也可在此处在线显示):

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 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)HttpContext.Current.Application.GetContainer()方法对我来说不存在,即使我使用了相同的DLL引用(我在.NET 4.0中编码).

3)OnPageInitComplete事件引用一个'context'变量...在这个上下文中似乎不存在.

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

1 个回答
  • 似乎文档组织严密.

    在回答(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();
          }
        }
      }
    }
    

    关于依赖注入模块代码,我实际上只是使用基本方法来获取容器的实例,就我所关注的而言,它也同样适用.文档说依赖注入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()扩展方法.

    2023-02-09 20:18 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有