如何在Unity中实现这个(HttpContext)依赖?

Mic*_*hel 8 c# asp.net inversion-of-control unity-container httpcontext

我们有一个依赖于的类HttpContext.我们已经实现了这样:

public SiteVariation() : this(new HttpContextWrapper(HttpContext.Current))
{
}
public SiteVariation(HttpContextBase context)
{}
Run Code Online (Sandbox Code Playgroud)

现在我想要做的是实例化SiteVariationUnity,所以我们可以创建一个构造函数.但我不知道如何HttpContextWrapper(HttpContext.Current))在配置方式中在Unity中配置这个新功能.

ps这是我们使用的配置方式

<type type="Web.SaveRequest.ISaveRequestHelper, Common" mapTo="Web.SaveRequest.SaveRequestHelper, Common" />
Run Code Online (Sandbox Code Playgroud)

Chr*_*edh 36

Microsoft已经构建了很好的包装和抽象HttpContext,HttpRequest并且HttpResponse包含在.NET中,所以我肯定会直接使用它们而不是自己包装它们.

您可以HttpContextBase使用InjectionFactory如下配置Unity for :

var container = new UnityContainer(); 

container.RegisterType<HttpContextBase>(new InjectionFactory(_ => 
    new HttpContextWrapper(HttpContext.Current)));
Run Code Online (Sandbox Code Playgroud)

另外,如果你需要HttpRequestBase(我倾向于使用最多)HttpResponseBase,你可以这样注册:

container.RegisterType<HttpRequestBase>(new InjectionFactory(_ => 
    new HttpRequestWrapper(HttpContext.Current.Request)));

container.RegisterType<HttpResponseBase>(new InjectionFactory(_ => 
    new HttpResponseWrapper(HttpContext.Current.Response)));
Run Code Online (Sandbox Code Playgroud)

您可以轻松地模拟HttpContextBase,HttpRequestBaseHttpResponseBase在没有自定义包装器的单元测试中.

  • 你的答案很棒,所以这纯粹是一种风格的选择:因为你在lamda中返回一个简单的对象,你不需要正式的代码块.所以你可以简单地写一行:container.RegisterType <HttpContextBase>(new InjectionFactory(c => new HttpContextWrapper(HttpContext.Current))); (2认同)
  • @BlackjacketMack谢谢!是的,我更喜欢这样.我用这个更新了答案.为了遵循惯例,我还更新了使用下划线来表示不使用该参数. (2认同)
  • 尼斯.这是我第一次看到下划线会议,但我喜欢它!非常沟通. (2认同)

BFr*_*ree 11

我不会HttpContextBase直接依赖.我会在它周围创建一个包装器,并使用你需要的位:

public interface IHttpContextBaseWrapper
{
   HttpRequestBase Request {get;}
   HttpResponseBase Response {get;}
   //and anything else you need
}
Run Code Online (Sandbox Code Playgroud)

那么实施:

public class HttpContextBaseWrapper : IHttpContextBaseWrapper
{
   public HttpRequestBase Request {get{return HttpContext.Current.Request;}}
   public HttpResponseBase Response {get{return HttpContext.Current.Response;}}
   //and anything else you need
}
Run Code Online (Sandbox Code Playgroud)

这样,您的类现在只依赖于包装器,并且不需要实际的HttpContext来运行.使注入更容易,并且更容易测试:

public SiteVariation(IHttpContextBaseWrapper context)
{

}

var container = new UnityContainer();
container.RegisterType<IHttpContextBaseWrapper ,HttpContextBaseWrapper>();
Run Code Online (Sandbox Code Playgroud)

  • @Michel:这句话有很多道理.由于DI/IoC是当时的风格,我一直在为许多"遗留"代码编写包装器(代码在某些情况下不会超过几年)以使其更易于测试.现在感觉这是正确的事情.从现在开始的3年后,我们都会说"男人,WTF,我们正在考虑所有这些一次性接口!" (4认同)