Remove dependency to logging code
I have more like desing question as I'm refactoring quite big piece of code that I took over.
It's not modular, basically it's pseudo-object-oriented code. It contains hard coded dependencies, no interfaces, multiple responsibilities etc. Just mayhem.
Among others it contains a great deal of internal calls to class called Audit, that contains methods like Log, Info, LogError etc... That class has to be configured in application config in order to work, otherwise it's crash. And that's the main pain for me. And please, let's focus on that issue in responses, namely making client code independent of logging classes/solutions/frameworks.
And now, I would like those classes, that have that Audit class dependency hardcoded, refactored in order to obtain several benefits:
- First is to extract them nicely to different assemblies, as I will need some functionality available in other applications (for instance generating attachments code - let's call it AttachmentsGenerator class, that until now was specyfic to one application, but now that code could be used in many places)
- Remove internal dependencies so that other application that will take advantage of my AttachmentsGenerator class without the need to add reference to other
- Do a magic trick in order to allow AttachmentsGenerator class to report some audit info, traces etc. But I don't want it to have hardcoded implementation. As a matter of fact, I don't want it to be mandatory, so it would be possible to use AttachmentsGenerator without that internal logging configured and without the necessity for the client code to add reference to another assemblies in order to use logging. Bottom line: if client code wants to use AttachmentsGenerato开发者_StackOverflow社区r, it adds reference to assembly that contains that class, then it uses new operator and that's all.
What kind approach can I use in terms of design patterns etc to achieve it? I would appreciate some links to articles that address that issue - as it can be timeconsuming to elaborate ideas in answer. Or if you can suggest simple interface/class/assembly sketch.
Thanks a lot, Paweł
Edit 1: As my question is not quite clear, I'll rephrase it once again: This is my plan, are there other interesting ways to do this?
Seems like the easiest way to do this would be to use dependency injection.
Create a generic
ILogger
interface with methods for logging.Create a concrete implementation of
ILogger
that just does nothing for all the methods (e.g.NullLogger
)Create another concrete implementation that actually does logging via whatever framework you choose (e.g. log4net)
Use a DI tool (spring, structure map, etc.) to inject the appropriate implementation depending on whether or not you want logging enabled.
Implement logging (and any other cross-cutting concerns) as a Decorator. That's way more SOLID than having to inject some ILogger interface into each and every service (which would violate both the Single Responsibility Principle and DRY).
精彩评论