引入了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并注入我自己的工厂来制作新的工厂?
答案 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对象。