Simple Injector:如何注入HttpContext?

时间:2014-02-06 10:47:46

标签: .net dependency-injection httpcontext simple-injector

我已经开始使用Simple Injector作为我的DI容器(主要是出于性能原因:如果有人有建议,请告诉我),但我编写的一些类使用HttpContextBase作为构造函数参数。 我现在已经解决了从构造函数中删除它并创建一个Property,如下所示:

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

但我不喜欢这个解决方案...任何建议?

1 个答案:

答案 0 :(得分:23)

你应该总是喜欢构造函数注入而不是其他任何东西。这几乎总是可行的。您可以按如下方式注册HttpContextBase

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

这可能会在调用Verify()时导致问题,因为在应用程序启动期间HttpContext.Currentnull,而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实现,用于防止在容器验证时返回nullFakeHttpContext就是这样:

public class FakeHttpContext : HttpContextBase { }

请注意,HttpContext是运行时数据和injecting runtime data into components during construction is an anti-pattern。您应该创建一个特定于应用程序的抽象,为消费者提供实际需要的抽象(例如用户身份或租户ID),而不是将HttpContext或其任何抽象注入到组件中。这种抽象的实现可以简单地在内部调用HttpContext.Current,这完全可以防止注入HttpContext。