I have an application (Legacy code)
that contains interface Icomponent with save() methods
and many classes that implement it.
I want to add log after every save().
updae:
I had few design ideas:
- Singelton Logger – that will be called after every logged-able action
I think LogService is a classic case of singelton, but I read it would be hard for unit-testing.
- Decorator + logger init with Ioc
use the decorator pattern to Icomponent with additional log() method.
create LogService class which is called from each decorator’s log()
- AOP – aspect orient programming
I read about this a bit, but don’t know it.
Is it applicable to c# ?
- What would be your design to that solution?
update2
After reading the code, I see there is another layer of interfaces
before the concrete layer. I don’t think I should decorate every specific interface. right?
I_AComponente : IComponente
I_BComponente : IComponente
A : I_AComponente
B : I_BComponente
It doesn’t have to be singleton at all. Consider:
Since you’ll be injecting decorated components to decorator anyways, might just as well inject logger (which then is rather easy to test). Where
loggercomes from will be irrelevant from unit test perspective.Also, instead of rolling your own loggers you should check existing ones, like Apache log4net.
Edit:
The claim that singleton logger is hard to test might come from that fact that singleton in C# will usually be implemented with
staticfield somewhere, or static class. Say you had:Now, in your decorators’ methods you’ll probably have to do something along those lines:
This makes testing of the
Savemethod nearly impossibly, as you have tightly coupled dependency inside your method. It’s not that bad if you can configureLoggerServicefor tests not to write to file system (but still, it’s rather going around the problem instead of solving it).In the inject via interface that problem is gone naturally.
LoggerServicemight still be static class, but it could simply provide non-static loggers (and manage their lifetime/scope). This doesn’t make unit testing difficult at all.