I've seen lots of code samples using an IoC Container with registrations such as:
// Autofac
builder.Register(c => new HttpContextWrapper(HttpContext.Current))
.As<HttpContextBase>()
.InstancePerRequest();
// Again Autofac
builder.RegisterModule(new AutofacWebTypesModule());
(see src for AutofacWebTypesModule HERE )
// Castle Windsor
container.Register(Component.For<HttpContextBase()
.LifeStyle.PerWebRequest
.UsingFactoryMethod(() => new HttpContextWrapper(HttpContext.Current)));
Together with controllers using contructor injection:
public class HomeController : Controller
{
private readonly HttpContextBase _httpContext;
public HomeController(HttpContextBase httpContext)
{
_httpContext = httpContext;
}
//....
}
Can you please explain the reason of wrapping HttpContextBase,HttpRequestBase and so on..?
What would be the difference between the Injected HttpContextBase vs HttpContext (Controller's property) vs System.Web.HttpContext.Current
Which HttpContext to use in code, the Injected One or it is also good to call it through HttpContext and System.Web.HttpContext.Current? Are there any issues if calling both ways?
Answer 1
HttpContext
is a notorious pain when it comes to testing, since it only exists in the context of a request. Since .net 3.5 HttpContextBase
is an abstraction of HttpContext
and lends itself to being injected through IOC frameworks
By letting the IOC container handle it you can register a different/deterministic instance be injected into your components at test time. In normal code you would inject the HttpContextWrapper
that is the default implementation
From the linked page:
The HttpContextBase class is an abstract class that contains the same members as the HttpContext class. The HttpContextBase class enables you to create derived classes that are like the HttpContext class, but that you can customize and that work outside the ASP.NET pipeline. When you perform unit testing, you typically use a derived class to implement members with customized behavior that fulfills the scenario you are testing.
Answer 2
The injected HttpContextBase
would return data that is needed in order for the test to succeed: a specific query string, a specific query, etc. Usually the injected implementation would only contain the needed methods for the test, ignoring all others, e.g the context .User.Identity.Name
property in order to test authentication.
Answer 3
In code, you must always use the HttpContextBase
that is injected, since you don't want to depend on a concrete implementation that may fail at test time. If calling both ways you may encounter problems, most notably in tests since the HttpContext.Current
will return null.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With