通过使用构造函数注入 HttpModule 来注入 HttpContext 是否错误?
Is Injecting HttpContext by using constructor injection into HttpModule wrong?
我有一个自定义的 HttpModule,我在其中跟踪 http 请求,部分实现如下;
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<WebSessionContext>()
.As<ISessionContext>().InstancePerRequest();
builder.Register(c => (new HttpContextWrapper(HttpContext.Current) as HttpContextBase))
.As<HttpContextBase>()
.InstancePerRequest();
builder.Register(c => c.Resolve<HttpContextBase>().Request)
.As<HttpRequestBase>()
.InstancePerRequest();
builder.Register(c => c.Resolve<HttpContextBase>().Server)
.As<HttpServerUtilityBase>()
.InstancePerRequest();
builder.Register(c => c.Resolve<HttpContextBase>().Session)
.As<HttpSessionStateBase>()
.InstancePerRequest();
这里的问题是 HttpModule 只构造一次,而 HttpContext 需要为每个请求注入。我找到的解决方案是将 DependencyResolver 用作 ;
HttpContextBase _httpContext = DependencyResolver.Current.GetService<HttpContextBase>();
但是,我想避免这种用法,因为 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();
}
我假设 Autofac 也可以注入 Func`1
个实例。如果没有,您可能需要创建一个简单的 class 作为 HttpContext 的工厂。
然后可以注入:
- 正常运行→
() => HttpContextWrapper(HttpContext.Current)
- 当testing/mocking→
() => new HttpContextMock()
我有一个自定义的 HttpModule,我在其中跟踪 http 请求,部分实现如下;
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<WebSessionContext>()
.As<ISessionContext>().InstancePerRequest();
builder.Register(c => (new HttpContextWrapper(HttpContext.Current) as HttpContextBase))
.As<HttpContextBase>()
.InstancePerRequest();
builder.Register(c => c.Resolve<HttpContextBase>().Request)
.As<HttpRequestBase>()
.InstancePerRequest();
builder.Register(c => c.Resolve<HttpContextBase>().Server)
.As<HttpServerUtilityBase>()
.InstancePerRequest();
builder.Register(c => c.Resolve<HttpContextBase>().Session)
.As<HttpSessionStateBase>()
.InstancePerRequest();
这里的问题是 HttpModule 只构造一次,而 HttpContext 需要为每个请求注入。我找到的解决方案是将 DependencyResolver 用作 ;
HttpContextBase _httpContext = DependencyResolver.Current.GetService<HttpContextBase>();
但是,我想避免这种用法,因为 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();
}
我假设 Autofac 也可以注入 Func`1
个实例。如果没有,您可能需要创建一个简单的 class 作为 HttpContext 的工厂。
然后可以注入:
- 正常运行→
() => HttpContextWrapper(HttpContext.Current)
- 当testing/mocking→
() => new HttpContextMock()