创建用于 IHttpModules 的 HttpContextProvider 是否错误?
Is it wrong to create an HttpContextProvider for use in IHttpModules?
我有这个遗留的 ASP.NET 网络应用程序,它大部分已转换为 MVC。代码的可测试性通常很差,因为它经常发生在遗留应用程序中:职责混乱,紧密耦合盛行,诸如此类。
几周来我一直在重构应用程序以提高可测试性,尽最大努力遵守 SOLID,现在我需要通过 HttpContext
或 HttpResponse
等到 HttpModule
中的方法。现在,显然 HttpModules
可以获取 HttpApplication
的副本并将其传递到任何地方 - 这就是 atm 的方式 - 但我宁愿不将对如此大的根对象的访问权限授予依赖项。
因为我们的一些 IHttpModules
在 MVC 发挥作用之前就已经初始化了,我在使用 IoC 容器将 HttpContextBase
或 HttpResponseBase
注入构造函数时遇到了问题模块使用的各种助手。因此,我必须将 HttpContextBase
传递给所述助手的方法——这使用起来很费力而且感觉有点不对劲——或者创建这样的东西:
public class HttpContextProvider : IHttpContextProvider {
// ... ctor
public HttpContextBase GetContext() { return HttpContext.Current; }
}
然后我会将一个实现 IHttpContextProvider
的实例注入到助手中,并在稍后根据需要调用 .GetContext()
。
直觉上,我觉得我可能做错了什么,但无法真正理解它可能是什么。整个重构足够复杂 - 并且团队中的总线因素足够低 - 我很犹豫是否要求首席开发人员为这个问题花费太多时间,从实际的角度来看,这几乎可以被视为学术。
我可以提出不同的选择
- 尝试在 IoC 中注册这个对象,但要解决这个问题(class 在它的依赖关系被解析之前被初始化)只需使用 Lazy< T> , 大多数 IoC 都支持它们,检查你的是否
- 像您的示例一样介绍提供商,但我会建议 return 而不是 HttpContext(或 HttpResponse) ,但正是你从这个 classes 中需要的,在测试中模拟这种行为会更容易(你甚至可能根本不需要在那里构造上下文)并且它还会隐藏 [的所有复杂内容=16=]未使用的 HttpContext
只有当您每次都以类似的方式使用这个对象时,第二个选项才会起作用——这样您就可以用 ISmthProvider 的 2-3 个方法替换它。如果您总是以不同的方式使用对象,那么将两种方法结合起来并将最流行的用法提取到某些服务和其他地方路径 Lazy< HttpContextBase> 到构造函数
会更好
在我看来,最好不要直接传递 HttpContext/HttpResponse,因为它提供了太多东西的访问权限,以后人们可能会把它弄得一团糟(使用它而不认为它已经存在)因此很难测试并在以后进行重构。
我有这个遗留的 ASP.NET 网络应用程序,它大部分已转换为 MVC。代码的可测试性通常很差,因为它经常发生在遗留应用程序中:职责混乱,紧密耦合盛行,诸如此类。
几周来我一直在重构应用程序以提高可测试性,尽最大努力遵守 SOLID,现在我需要通过 HttpContext
或 HttpResponse
等到 HttpModule
中的方法。现在,显然 HttpModules
可以获取 HttpApplication
的副本并将其传递到任何地方 - 这就是 atm 的方式 - 但我宁愿不将对如此大的根对象的访问权限授予依赖项。
因为我们的一些 IHttpModules
在 MVC 发挥作用之前就已经初始化了,我在使用 IoC 容器将 HttpContextBase
或 HttpResponseBase
注入构造函数时遇到了问题模块使用的各种助手。因此,我必须将 HttpContextBase
传递给所述助手的方法——这使用起来很费力而且感觉有点不对劲——或者创建这样的东西:
public class HttpContextProvider : IHttpContextProvider {
// ... ctor
public HttpContextBase GetContext() { return HttpContext.Current; }
}
然后我会将一个实现 IHttpContextProvider
的实例注入到助手中,并在稍后根据需要调用 .GetContext()
。
直觉上,我觉得我可能做错了什么,但无法真正理解它可能是什么。整个重构足够复杂 - 并且团队中的总线因素足够低 - 我很犹豫是否要求首席开发人员为这个问题花费太多时间,从实际的角度来看,这几乎可以被视为学术。
我可以提出不同的选择
- 尝试在 IoC 中注册这个对象,但要解决这个问题(class 在它的依赖关系被解析之前被初始化)只需使用 Lazy< T> , 大多数 IoC 都支持它们,检查你的是否
- 像您的示例一样介绍提供商,但我会建议 return 而不是 HttpContext(或 HttpResponse) ,但正是你从这个 classes 中需要的,在测试中模拟这种行为会更容易(你甚至可能根本不需要在那里构造上下文)并且它还会隐藏 [的所有复杂内容=16=]未使用的 HttpContext
只有当您每次都以类似的方式使用这个对象时,第二个选项才会起作用——这样您就可以用 ISmthProvider 的 2-3 个方法替换它。如果您总是以不同的方式使用对象,那么将两种方法结合起来并将最流行的用法提取到某些服务和其他地方路径 Lazy< HttpContextBase> 到构造函数
会更好在我看来,最好不要直接传递 HttpContext/HttpResponse,因为它提供了太多东西的访问权限,以后人们可能会把它弄得一团糟(使用它而不认为它已经存在)因此很难测试并在以后进行重构。