Castle.Windsor和HttpContextWrapper

时间:2011-03-28 20:37:12

标签: asp.net-mvc castle-windsor httpcontext s#arp-architecture

引入了HttpContextWrapper和HttpContextBase,如explained here,使HttpContext更具可模拟性/可测试性。

我正在尝试将其与S#arp Architecture一起使用,并遇到一些问题。

我的MVC控制器被设置为在构造函数中接受HttpContextBase参数,并且在Application_Start期间,HttpContextBase在Castle.Windor中注册,如下所示:

container.Register(Component.For<HttpContextBase>().UsingFactoryMethod(
    () => new HttpContextWrapper(HttpContext.Current)));

这似乎工作正常,但后来我意识到Castle只运行一次Factory方法,所以所有请求都获得了原始的HttpContextWrapper。真的需要为每个请求重新创建它。 Castle.Windsor命令将是:

container.Register(Component.For<HttpContextBase().
    LifeStyle.PerWebRequest.UsingFactoryMethod(
    () => new HttpContextWrapper(HttpContext.Current)));

...但事实证明,Castle.Windsor不允许在Application_Start(as explained here)中使用LifeStyle.PerWebRequest

我该怎么办?有没有一个简单的方法可以解决这个问题,还是应该放弃HttpContextWrapper并注入我自己的工厂来制作新的工厂?

3 个答案:

答案 0 :(得分:8)

  

我的MVC控制器设置为接受构造函数中的HttpContextBase参数

你必须在这里做一些极其错误的事情,所以在它为时已晚之前停止并造成损害(物质,道德和人员伤亡:-))。你已经在控制器中有了HttpContext。

不要在DI框架中注册任何HttpContexts。 HttpContext处理是ASP.NET的工作。

答案 1 :(得分:2)

正如Darin所说,将HttpContext注入MVC​​控制器是没有意义的。但是,如果您需要其他类型的服务并且在Application_Start()中也需要它,请使用hybrid perwebrequest-transient lifestyle。或者,由于构建起来很简单,只需将其设置为瞬态。

答案 2 :(得分:0)

正如其他人所说 - 你做错了。我的大问题是:

你在做什么需要你在控制器中注入HttpContextBase?如果您想为我们提供有关您真正想要做的事情的更多背景信息,那对想要帮助您的人可能会更有帮助。让我们把Castle拿出来,然后了解你的控制器正在做什么。

顺便说一下,你的控制器已经有了对HttpContext的引用。如果您这样做是为了测试性,那么您无需在控制器级别执行任何操作。您只需要在控制器测试中根据需要模拟HttpContextBase对象。