Cia*_*her 4 .net c# asp.net enterprise-library
我一直在按照"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<Control> GetControlTree(Control root)
{
foreach (Control child in root.Controls)
{
yield return child;
foreach (Control c in GetControlTree(child))
{
yield return c;
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
此代码及其随附的说明存在许多问题.
1)说明中没有提到放置此代码的位置.由于它是一个类,我将它放在我的ASP.NET网站项目的App_Code文件夹中.
实际上,这里是这段代码的说明:
在项目中创建一个新的ASP.NET HTTP模块类(例如,命名为UnityHttpModule),用于捕获PreRequestHandlerExecute事件并执行遍历当前页面请求的完整控制树的代码,并将Unity BuildUp方法应用于每个控件.
2)HttpContext.Current.Application.GetContainer()方法对我来说不存在,即使我使用了相同的DLL引用(我在.NET 4.0中编码).
3)OnPageInitComplete事件引用一个'context'变量...在这个上下文中似乎不存在.
关于我在这里缺少什么的想法?
似乎文档组织严密.
在回答(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();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
关于依赖注入模块代码,我实际上只是使用基本方法来获取容器的实例,就我所关注的而言,它也同样适用.文档说依赖注入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();
}
}
Run Code Online (Sandbox Code Playgroud)
因此,使用扩展代码和我的global.asax文件中的代码来创建Enterprise Library容器的实例,唯一要做的就是编写代码以根据需要获取容器的实例.所以,当我想获得LogWriter类的实例时,我会写这个:
using Unity.Web;
public LogWriter getLogWriter()
{
var container = HttpContext.Current.Application.GetContainer();
return container.Resolve<LogWriter>();
}
Run Code Online (Sandbox Code Playgroud)
需要Unity.Web命名空间才能允许我们调用GetContainer()扩展方法.
| 归档时间: |
|
| 查看次数: |
1797 次 |
| 最近记录: |