Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Logging, Aspect Oriented Programming, and Dependency Injection - Trying to make sense of it all

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?

like image 752
Matt Avatar asked Oct 26 '11 15:10

Matt


1 Answers

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.

like image 119
Mark Seemann Avatar answered Sep 18 '22 12:09

Mark Seemann