ASP.NET依赖注入HTTP模块(MS企业库) [英] ASP.NET Dependency Injection HTTP Module (MS Enterprise Library)

查看:161
本文介绍了ASP.NET依赖注入HTTP模块(MS企业库)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在继微软企业库5.0文档中的步骤来创建一个HTTP模块注入一个参考企业库容器到ASP.NET Web应用程序的页面。

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)的说明没有提到在何处放置此代码。由于它是一类的,我把它放在我的ASP.NET网站项目的App_Code文件夹中。

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:

在项目中创建一个新的ASP.NET HTTP模块类(命名,例如,
UnityHttpModule)捕获的
的PreRequestHandlerExecute事件并执行它遍历当前页面的
完全控制树码要求,运用统一
堆积的方法来控制各

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中)。

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)OnPageInitComplete事件引用了语境变量...这似乎并没有在这方面存在的。

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?

推荐答案

似乎文档组织混乱。

在响应于(2),什么没有被解释的是,HttpContext.Current.Application.GetContainer()方法实际上是一种扩展方法,这是象实施所示的代码 这里

In response to (2), what wasn't explained is that the HttpContext.Current.Application.GetContainer() method is actually an extension method, which is implemented like the code shown here.

要使用这个扩展方法,你只需要导入Unity.Web'命名空间。

To use this extension method, you simply have to import the 'Unity.Web' namespace.

下面是扩展方法的副本:

Here is a copy of the extension method:

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模块代码提高可测试性和可发现,这是一个有点含糊。

With regards to the the dependency injection module code, I actually just used the basic method for getting an instance of the container, which as far as I'm concerned works just as well. The documentation says that the dependency injection HTTP module code improves 'testability' and 'discoverability', which is a little vague.

总之,这里的为基本方法的代码:

Anyway, here's the code for the basic approach:

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文件来创建企业库容器的实例,剩下要做的唯一事情就是写代码需要得到容器的一个实例。所以,当我想要得到的日志写类的一个实例,我会写这样的:

So with the extension code in place, and code in my global.asax file to create an instance of the Enterprise Library container, the only thing left to do is write the code to get an instance of the container as needed. So when I want to get an instance of the LogWriter class, I would write this:

using Unity.Web;

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



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

The Unity.Web namespace is needed to allow us to invoke the GetContainer() extension method.

这篇关于ASP.NET依赖注入HTTP模块(MS企业库)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆