记录,面向方面编程和依赖注入 - 试图理解这一切

Mat*_*att 33 .net logging aop unit-testing dependency-injection

我知道日志记录是AOP的主要用例.此外,日志记录包装器也可以作为您希望使用DI的示例,以便类不与特定的日志记录实现相结合.但是,有些人认为日志包装器是一种反模式.首先,这样的视图是因为在大多数情况下,包装器往往是简单的并且删除了特定于日志框架的许多特征.如果您实现这些特定功能,为什么不直接使用框架.

我知道Common.Logging外观试图为您提取log4Net,EntLib,NLog的大量功能.但是,即使在这里,我们仍然依赖于Common.Logging.不是关于接口等的代码/单元测试方式,但如果项目死亡(自上次发布以来已超过一年)或者您希望后者切换到不支持的记录器,则可能导致问题.

也就是说,如果通过AOP实现日志记录,是否有必要使用DI作为日志记录依赖项(即为什么不直接引用说NLog)?是的,AOP部分代码将紧密耦合,但是想要进行单元测试的类的逻辑缺乏记录依赖性(至少在编织发生之前).在这一点上,我有点迷失(我还没有尝试过AOP).编织后,没有使用DI作为AOP代码会导致单元测试被测方法的问题吗?或者可以在不编织AOP代码的情况下测试一个单元吗?

除非日志记录是软件用户的要求,否则我不确定测试日志是否与模拟有关是多么有用.我认为被测方法的业务逻辑是大多数人对测试感兴趣的东西.最后,如果想要使用TDD/BDD,是否必须在AOP代码中使用DI来记录日志依赖?或者只是不测试驱动 AOP方面的东西?

正如您所看到的,我正在尝试了解最实用的方法是开发一个应用程序,该应用程序将AOP用于横切关注点,DI用于设计/测试.由于AOP相对较新,而日志记录是最常见的例子,推荐的方法是什么?

Mar*_*ann 54

记录不是服务,它是一个贯穿各领域的关注点.因此,最好用装饰器实现.但是,添加大量装饰器只是为了启用各种不同服务的记录往往会违反DRY,在这种情况下,您可以进一步将这些装饰器演变为单个拦截器.

虽然您可以使用IL编织来实现AOP,但更好的选择是使用支持动态拦截的DI容器,因为它是一个更轻量级的解决方案.

这使您可以将具体服务与日志记录完全分离.在那种情况下,我会说没有理由包装任何特定的日志框架,因为如果你想要更改日志框架,你可以只更改那个单一的拦截器.

这是一个讨论装饰器和拦截器的示例(非常类似于日志记录).

如果您想了解有关AOP和DI的更多信息,您可以在线查看我在GOTO Copenhagen 2010上发表的演讲.

  • 动态拦截也是*也是*AOP :)但是,我通过IL编织将您的问题解释为与AOP有关.在这种情况下,在绿地项目中,我看到它绝对没有任何好处,但是对于遗留代码它可能是实用的,因为它允许您将方面应用于静态,内部和/或私有类型和成员,而动态拦截需要您'对接口(或基类)进行编程. (3认同)
  • @Vijay如果你需要在*方法调用之间记录*,是否表明该方法做得太多(违反[SRP](http://en.wikipedia.org/wiki/Single_responsibility_principle))? (2认同)