HttpContextWrapper and HttpContextBase, as explained here, were introduced to make HttpContext more mockable/testable.
I'm trying to use it with S#arp Architecture, and hitting some problems.
My MVC Controllers are set up to accept an HttpContextBase argument in the constructor, and during Application_Start, HttpContextBase is registered with Castle.Windor as follows:
container.Register(Component.For<HttpContextBase>().UsingFactoryMethod(
() => new HttpContextWrapper(HttpContext.Current)));
This seemed to work OK for a bit, but then I realised Castle is only running that Factory method once, so all requests get the original HttpContextWrapper. Really it needs to be re-created for every request. The Castle.Windsor command for that would be:
container.Register(Component.For<HttpContextBase().
LifeStyle.PerWebRequest.UsingFactoryMethod(
() => new HttpContextWrapper(HttpContext.Current)));
... but it turns out that Castle.Windsor doesn't allow LifeStyle.PerWebRequest to be used within Application_Start (as explained here)
What should I be doing? Is there an easy way round this or should I give up on HttpContextWrapper and inject my own factory to make new ones as needed?
My MVC Controllers are set up to accept an HttpContextBase argument in the constructor
You gotta be doing something extremely wrong here, so stop before it's too late and damage has been caused (material, moral and human casualties :-)). You already have the HttpContext inside the controller.
Don't register any HttpContexts in your DI framework. The HttpContext handling is the job of ASP.NET.
As Darin noted, it makes no sense to inject an HttpContext into an MVC controller. However, if you need it for other kind of services and also need it in Application_Start(), use an hybrid perwebrequest-transient lifestyle. Or, since it's trivial to build, just make it transient.
As others have stated - you are doing it wrong. My big question is:
What are you doing that requires you to inject HttpContextBase in your controller? It might be more helpful to people wanting to help you if you would provide us more context about what you are really trying to do. Lets take Castle out of it and get down to what your controller is doing.
BTW, your controller already has a reference to HttpContext. If you are doing this for testability, there is nothing you need to do at the controller level. You would just need to mock the HttpContextBase object as needed in your controller tests.
来源:https://stackoverflow.com/questions/5464785/castle-windsor-and-httpcontextwrapper