Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the purpose of injecting HttpContextBase in Controller with IoC

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;
    }
    //....
}

Question 1:

Can you please explain the reason of wrapping HttpContextBase,HttpRequestBase and so on..?

Question 2:

What would be the difference between the Injected HttpContextBase vs HttpContext (Controller's property) vs System.Web.HttpContext.Current

Update

Question 3:

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?

like image 652
Cristian E. Avatar asked Sep 29 '22 20:09

Cristian E.


1 Answers

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.

like image 69
samy Avatar answered Oct 11 '22 15:10

samy