我已经开始使用Simple Injector作为我的DI容器(主要是出于性能原因:如果有人有建议,请告诉我),但我编写的一些类使用HttpContextBase作为构造函数参数。 我现在已经解决了从构造函数中删除它并创建一个Property,如下所示:
public HttpContextBase HttpContext
{
get
{
if (null == _httpContext)
_httpContext = new HttpContextWrapper(System.Web.HttpContext.Current);
return _httpContext;
}
set
{
_httpContext = value;
}
}
但我不喜欢这个解决方案...任何建议?
答案 0 :(得分:23)
你应该总是喜欢构造函数注入而不是其他任何东西。这几乎总是可行的。您可以按如下方式注册HttpContextBase
:
container.Register<HttpContextBase>(() =>
new HttpContextWrapper(HttpContext.Current),
Lifestyle.Scoped);
这可能会在调用Verify()
时导致问题,因为在应用程序启动期间HttpContext.Current
为null
,而HttpContextWrapper
不允许将null传递给构造函数。
尝试keep your configuration verifiable总是好的,您可以将注册更改为以下内容:
container.Register<HttpContextBase>(() =>
{
var context = HttpContext.Current;
if (context == null && container.IsVerifying) return new FakeHttpContext();
return new HttpContextWrapper(context);
},
Lifestyle.Scoped);
FakeHttpContext
是一个空的HttpContextBase
实现,用于防止在容器验证时返回null
。 FakeHttpContext
就是这样:
public class FakeHttpContext : HttpContextBase { }
请注意,HttpContext是运行时数据和injecting runtime data into components during construction is an anti-pattern。您应该创建一个特定于应用程序的抽象,为消费者提供实际需要的抽象(例如用户身份或租户ID),而不是将HttpContext或其任何抽象注入到组件中。这种抽象的实现可以简单地在内部调用HttpContext.Current,这完全可以防止注入HttpContext。