Simple Injector: how to inject HttpContext?

谁说胖子不能爱 提交于 2019-12-18 13:20:11

问题


I have started using Simple Injector as my DI container (mostly for performance reason: if somebody has suggestions, please let me know) but some of the classes I wrote use HttpContextBase as constructor parameter. I have resolved for now removing it from the constructor and creating a Property, something like this:

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

but I don't like this solution... any advices?


回答1:


You should always favor constructor injection over anything else. This is almost always possible. You can register your HttpContextBase as follows:

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

This can cause a problem when calling Verify(), since during application startup HttpContext.Current is null, and HttpContextWrapper does not allow passing null into the constructor.

It's always good to try to keep your configuration verifiable, and you can change that registration to the following:

container.Register<HttpContextBase>(() =>
{
    var context = HttpContext.Current;
    if (context == null && container.IsVerifying) return new FakeHttpContext();
    return new HttpContextWrapper(context);
},
    Lifestyle.Scoped);

FakeHttpContext is an empty HttpContextBase implementation to prevent returning null in case the container is verifying. The FakeHttpContext is simply this:

public class FakeHttpContext : HttpContextBase { }

Do note however that HttpContext is runtime data and injecting runtime data into components during construction is an anti-pattern. Instead of injecting the HttpContext or any abstraction over it into your components, you should create an application-specific abstraction that provides the consumer with what it actually needs (for instance a user identity or tenant id). The implementation of this abstraction can simply call HttpContext.Current internally which completely prevents the need for HttpContext to be injected.



来源:https://stackoverflow.com/questions/21600678/simple-injector-how-to-inject-httpcontext

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!