ASP.NET MVC建议使用或扩展内置的授权、操作、结果、异常筛选器。 .Net IoC容器(Unity、Ninject、Autofac)建议使用拦截器。 AOP工具(Postsharp)建议使用它们自己的属性。 现在,我感到很混乱。也许我把它们混合了。 我想构建稳健的代码和稳定的方法,我应该使用什么?
一切都始于良好的应用程序设计。当您的应用程序设计正确时,您与 UI 框架公开的 AOP 类似功能交互的原因将大大减少(WCF 也是如此)。例如,当您将所有业务逻辑隐藏在通用接口背后,并传递命令消息时(如本文所示),您的控制器将成为薄包装器,往往只执行这样的业务命令。在这种情况下,您可以通过包装这些业务操作来实现授权和异常过滤,使 UI 代码保持干净,没有属性。这些横切关注点可以使用拦截或旧式装饰者来完成。这使您具有更高的灵活性并保持设计 SOLID (具有许多不太明显的长期优势)。虽然像 PostSharp 这样的代码编织工具很有用,但您应该小心使用它们。它们使用后编译过程将代码注入到您的程序集中。这使得在不触发这些方面的情况下对这些类进行单元测试非常困难。您无法轻松地孤立地测试这些类(这是单元测试的前提条件)。使您的方面依赖于某个静态变量会使方面和单元测试变得更加复杂。静态变量使并行运行单元测试变得困难,并且使用全局常量将要求正确拆除更改的全局设置以防止其他测试受到影响。虽然代码编织工具通常比拦截产生更好的性能,但与使用装饰者相比,没有性能提升。
您引用了三种技术,它们的目的都是在不修改现有代码库的情况下添加功能。ASP.NET MVC和DI限制了您可以在哪些位置使用方面(命名过滤器或拦截器),因为这些技术只能在某些位置添加行为,而不能编辑您的代码。仅基于编译器的技术(例如PostSharp)才能在任何地方添加方面。但是,所有三种都是AOP概念的实现。在许多情况下,与传统面向对象编程相比,方面证明具有显着优势。并非每个问题都可以通过更好的设计以相同的成本解决传统OOP问题。然而,AOP并不是主流技术,使用非主流技术存在成本和风险(AOP诞生于90年代,而OOP诞生于60年代)。与任何创新一样,不同的参与者对风险和利益的敏感度不同,因此可能成为早期或晚期采用者。AOP不是单元测试的障碍,但是该主题缺乏共享经验。通常,方面必须作为单独的代码单元进行测试。有必要和非必要的方面。通常,业务代码必须与关键方面一起进行测试,但必须禁用非必要的方面。您可以在构建时静态禁用方面(仅从构建配置中排除某些方面),也可以在运行时禁用它们(使该方面依赖于您在测试期间设置为false的某些静态变量)。