C# 通过将构造函数注入HttpModule来注入HttpContext是否错误?
我有一个自定义的HttpModule,我在其中跟踪http请求,实现的一部分如下C# 通过将构造函数注入HttpModule来注入HttpContext是否错误?,c#,autofac,httpmodule,constructor-injection,dependency-resolver,C#,Autofac,Httpmodule,Constructor Injection,Dependency Resolver,我有一个自定义的HttpModule,我在其中跟踪http请求,实现的一部分如下 private readonly HttpContextBase _httpContext; private readonly ISessionContext _sessionContext; public ASHttpModule(HttpContextBase httpContext, ISessionContext sessionContext) {
private readonly HttpContextBase _httpContext;
private readonly ISessionContext _sessionContext;
public ASHttpModule(HttpContextBase httpContext,
ISessionContext sessionContext)
{
this._httpContext = httpContext;
this._sessionContext = sessionContext;
}
public void Init(HttpApplication context)
{
context.BeginRequest += Context_BeginRequest;
context.EndRequest += Context_EndRequest;
}
private void Context_BeginRequest(object sender, EventArgs e)
{
Stopwatch stopwatch = new Stopwatch();
_httpContext.Items["Stopwatch"] = stopwatch;
stopwatch.Start();
}
private void Context_EndRequest(object sender, EventArgs e)
{
Stopwatch stopwatch = (Stopwatch)_httpContext.Items["Stopwatch"];
if (stopwatch == null)
return;
stopwatch.Stop();
TimeSpan ts = stopwatch.Elapsed;
//Check current httprequest variables and log if have to
}
这里是我的依赖项注册(使用Autofac)
builder.RegisterType()
.As().InstancePerRequest();
注册(c=>(新的HttpContextWrapper(HttpContext.Current)为HttpContextBase))
.As()
.InstancePerRequest();
builder.Register(c=>c.Resolve().Request)
.As()
.InstancePerRequest();
builder.Register(c=>c.Resolve().Server)
.As()
.InstancePerRequest();
builder.Register(c=>c.Resolve().Session)
.As()
.InstancePerRequest();
这里的问题是HttpModule只构造一次,而HttpContext需要为每个请求注入。我找到的解决方案是使用DependencyResolver作为
HttpContextBase _httpContext = DependencyResolver.Current.GetService<HttpContextBase>();
HttpContextBase\u httpContext=dependencysolver.Current.GetService();
然而,我想避免这种用法,因为ServiceLocator被认为是反模式的
是否有任何解决方案可以在不使用DependencyResolver的情况下将HttpContext注入HttpModule?您可以尝试使用工厂来获取正确的HttpContext实例:
private readonly Func<HttpContextBase> _httpContextFactory;
private readonly ISessionContext _sessionContext;
public ASHttpModule(Func<HttpContextBase> httpContextFactory,
ISessionContext sessionContext)
{
this._httpContextFactory = httpContextFactory;
this._sessionContext = sessionContext;
}
private void Context_BeginRequest(object sender, EventArgs e)
{
var httpContext = this._httpContextFactory();
Stopwatch stopwatch = new Stopwatch();
httpContext.Items["Stopwatch"] = stopwatch;
stopwatch.Start();
}
private readonly Func\u httpContextFactory;
私有只读ISessionContext_sessionContext;
公共ASHttpModule(函数httpContextFactory,
ISessionContext(会话上下文)
{
这是.\u httpContextFactory=httpContextFactory;
这._sessionContext=sessionContext;
}
私有void上下文_BeginRequest(对象发送方,事件参数e)
{
var httpContext=this.\u httpContextFactory();
秒表秒表=新秒表();
httpContext.Items[“秒表”]=秒表;
秒表。开始();
}
我假设Autofac也可以注入Func`1
实例。如果没有,您可能必须创建一个简单的类,作为HttpContext的工厂
然后您可以注入:
- 正常运行→ <代码>()=>HttpContextWrapper(HttpContext.Current)
- 测试/模拟时→ <代码>()=>新的HttpContextMock()
private readonly Func<HttpContextBase> _httpContextFactory;
private readonly ISessionContext _sessionContext;
public ASHttpModule(Func<HttpContextBase> httpContextFactory,
ISessionContext sessionContext)
{
this._httpContextFactory = httpContextFactory;
this._sessionContext = sessionContext;
}
private void Context_BeginRequest(object sender, EventArgs e)
{
var httpContext = this._httpContextFactory();
Stopwatch stopwatch = new Stopwatch();
httpContext.Items["Stopwatch"] = stopwatch;
stopwatch.Start();
}