我见过很多使用IoC容器的代码示例,其注册如下:
// Autofac
builder.Register(c => new HttpContextWrapper(HttpContext.Current))
.As<HttpContextBase>()
.InstancePerRequest();
// Again Autofac
builder.RegisterModule(new AutofacWebTypesModule());
(参见src for AutofacWebTypesModule HERE)
// Castle Windsor
container.Register(Component.For<HttpContextBase()
.LifeStyle.PerWebRequest
.UsingFactoryMethod(() => new HttpContextWrapper(HttpContext.Current)));
与使用构造函数注入的控制器一起:
public class HomeController : Controller
{
private readonly HttpContextBase _httpContext;
public HomeController(HttpContextBase httpContext)
{
_httpContext = httpContext;
}
//....
}
请解释一下包装HttpContextBase,HttpRequestBase等的原因..?
注入的HttpContextBase 与 HttpContext (Controller的属性)vs System.Web.HttpContext.Current
在代码中使用哪个HttpContext,注入一个,或者通过 HttpContext 和 System.Web.HttpContext.Current ?如果双向调用会有任何问题吗?
答案 0 :(得分:4)
回答1
HttpContext
在测试方面是一个臭名昭着的痛苦,因为它只存在于请求的上下文中。 Since .net 3.5 HttpContextBase
is an abstraction of HttpContext
并且有助于通过IOC框架注入
通过让IOC容器处理它,您可以注册在测试时注入组件的不同/确定性实例。在普通代码中,您将注入HttpContextWrapper
,这是默认实现
从链接页面:
HttpContextBase类是一个包含相同内容的抽象类 成员作为HttpContext类。 HttpContextBase类启用 你可以创建类似于HttpContext类的派生类,但是 您可以自定义并在ASP.NET管道外工作。 执行单元测试时,通常使用派生类 实现具有满足方案的自定义行为的成员 你正在测试。
回答2
注入的HttpContextBase
将返回测试成功所需的数据:特定的查询字符串,特定的查询等。通常注入的实现只包含测试所需的方法,忽略所有其他的,例如上下文.User.Identity.Name
属性,以便测试身份验证。
回答3
在代码中,您必须始终使用注入的HttpContextBase
,因为您不希望依赖于在测试时可能失败的具体实现。如果同时调用两种方式,您可能会遇到问题,尤其是在测试中,因为HttpContext.Current
将返回null。