Simple Injector: how to inject HttpContext?
.net, dependency-injection, httpcontext, simple-injector
Solution
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.
Problem
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?