日志记录,面向方面的编程和依赖注入 - 试图让所有这些都有意义 [英] Logging, Aspect Oriented Programming, and Dependency Injection - Trying to make sense of it all

查看:110
本文介绍了日志记录,面向方面的编程和依赖注入 - 试图让所有这些都有意义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道日志记录是AOP的主要用例。另外,当您要使用DI时,还可以使用日志记录封装器作为示例,以便类不与特定的日志记录实现相结合。但是,有些考虑到日志记录包装器具有反模式 。首先,这样的看法是因为在大多数情况下,包装器往往是简单的,并且消除了日志框架特有的许多特征。如果您实现这些特定功能,为什么不直接使用框架。



我知道 Common.Logging 立面,试图为您提供大量的log4Net,EntLib,NLog的功能。然而,即使在这里,我们仍然依赖于Common.Logging。不是关于接口等的代码/单元测试方法,但是如果项目中断(自上次发布以来已经有一年以上),或者您希望后者切换到不支持的记录器,那么可能会导致问题。

这就是说,如果通过AOP来实现日志记录,那么甚至有必要使用DI来进行日志依赖关系(即为什么不直接引用说NLog)?是的,代码的AOP部分将紧密耦合,但是要进行单元测试的类的逻辑没有记录依赖关系(至少在编织之前)。在这一点上,我有点迷失(我还没有尝试过AOP)。编织后,没有使用DI作为AOP代码会导致测试单元测试的问题?还是可以在不编织AOP代码的情况下进行一个单元测试?



除非记录是软件用户的要求,否则我不知道用mock测试日志是否有用。我会认为被测方法的业务逻辑是最有兴趣的测试。最后,如果想使用TDD / BDD,那么在AOP代码中不需要使用DI来记录依赖关系?或者只是一个人不要试用驱动器的AOP方面的东西?



正如你所看到的,我想知道最实际的方法是开发一个应用程序,这个应用程序将使用AOP进行交叉切换,关注和DI设计/测试。 由于AOP是比较新的,而日志记录是最常见的例子,建议的方法是什么?

解决方案

p>日志记录不是一个服务,它是一个交叉关注。因此,最好使用装饰器实现。但是,添加大量装饰器只是为了记录各种不同的服务,往往违反 DRY ,在这种情况下,您可以进一步将这些装饰器演变成单个拦截器。



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



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



以下是一个例子,讲述了装饰器和拦截器的工具(非常类似于日志记录)。



如果您想了解有关AOP和DI的更多信息,可以在线阅读我在GOTO哥本哈根2010年给出的讲话


I know that logging is a prime use case for AOP. Additionally logging wrappers are also exemplified as cases when you want to use DI so that classes aren't coupled with a specific logging implementation. However, some consider logging wrappers an anti-pattern. Primarily, such a view is because in most cases the wrapper tends to be simplistic and removes many of the features specific of the logging framework. If you implement those specific features, why not just use the framework directly.

I am aware of the Common.Logging facade that attempts to abstract a good amount of the features of log4Net, EntLib, NLog for you. However, even here we still have a dependency of sorts on Common.Logging. Not in a code/unit testing way regarding interfaces and such, but if the project dies (it's been over a year since the last release) or you want to latter switch to a logger not supported, that can cause problems.

That said, if logging is achieved via AOP, is it even necessary to use DI for the logging dependency (i.e. why not just directly reference say NLog)? Yes that AOP portion of code would be tightly coupled, but the logic of the classes that one wants to unit test is devoid of logging dependencies (at least before the weaving happens). It's at this point that I'm a bit lost (I haven't tried AOP yet). After weaving, would having not used DI for the AOP code cause problems for unit testing the method under test? Or can one unit test without weaving the AOP code?

Unless logging is a requirement of the user of the software, I'm not sure how useful it is to test that logging has occured with mocks. I would think that the business logic of the method under test is what most would be interested in testing. Lastly, if one wants to use TDD/BDD, wouldn't one have to use DI for the logging dependencies in the AOP code? Or would one just not test drive the AOP side of things?

As you can see, I'm trying to get a feel for what the most practical approach is for developing an application that would be using both AOP for cross-cutting-concerns and DI for design/testing. Since AOP is relatively new, and logging is the most common example, what is the recommended approach?

解决方案

Logging is not a Service, it's a cross-cutting concern. As such, it's best implemented with a Decorator. However, adding lots of Decorators just to enable logging of various different services tend to violate DRY, in which case you can then further evolve those Decorators into a single Interceptor.

While you can use IL weaving to implement AOP, a better option is to use a DI Container that supports dynamic interception, as it's a far more lightweight solution.

This enables you to completely decouple concrete services from logging. In that case then, I'd say that there's no reason to wrap any particular logging framework, because if you ever want to change the logging framework, you can just change that single Interceptor.

Here's an example that talks about Decorators and Interceptors for instrumentation (very similar to logging).

If you want to learn more about AOP and DI, you can view online this talk I gave at GOTO Copenhagen 2010.

这篇关于日志记录,面向方面的编程和依赖注入 - 试图让所有这些都有意义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆