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?
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.