2014-02-06 33 views
7

我已经开始使用Simple Injector作为我的DI容器(主要是出于性能的原因:如果有人有建议,请告诉我)但我写的一些类使用HttpContextBase作为构造函数参数。 我已经解决了,现在从构造函数中删除,并创建一个属性,是这样的:简单的注射器:如何注入HttpContext?

public HttpContextBase HttpContext 
    { 
     get 
     { 
      if (null == _httpContext) 
       _httpContext = new HttpContextWrapper(System.Web.HttpContext.Current); 
      return _httpContext; 
     } 
     set 
     { 
      _httpContext = value; 
     } 
    } 

,但我不喜欢这种解决方案有何意见?

回答

22

您应该始终偏爱构造函数注入。这几乎总是可能的。可以按如下方式注册您的HttpContextBase

container.Register<HttpContextBase>(() => 
    new HttpContextWrapper(HttpContext.Current), 
    Lifestyle.Scoped); 

这可以调用Verify()的时候,因为在应用程序启动HttpContext.Currentnull导致一个问题,HttpContextWrapper不允许空传递到构造函数。

它总是好的尝试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。您应该创建一个特定于应用程序的抽象,为消费者提供实际需要的内容(例如用户标识或租户标识),而不是将HttpContext或任何抽象注入到组件中。这种抽象的实现可以简单地在内部调用HttpContext.Current,这完全防止了需要注入HttpContext。

+0

我觉得很蠢......你的解决方案完美无缺,谢谢! – MizRaeL

相关问题