I had a habit to pass logger to constructor, like:
public class OrderService : IOrderService { public OrderService(ILogger logger) { } }
But that is quite annoying, so I've used it a property this for some time:
private ILogger logger = NullLogger.Instance; public ILogger Logger { get { return logger; } set { logger = value; } }
This is getting annoying too - it is not dry, I need to repeat this in every class. I could use base class, but then again - I'm using Form class, so would need FormBase, etc. So I think, what would be downside of having singleton with ILogger exposed, so veryone would know where to get logger:
Infrastructure.Logger.Info("blabla");
UPDATE: As Merlyn correctly noticed, I've should mention, that in first and second examples I am using DI.
It is better to have an explicit dependency than to hide it via a singleton. But if singletons save you significant time, including all refactoring you will ever have to do (crystal ball time!), I suppose you might be able to live with them. If ever there were a use for a Singleton, this might be it.
It is used where only a single instance of a class is required to control the action throughout the execution. A singleton class shouldn't have multiple instances in any case and at any cost. Singleton classes are used for logging, driver objects, caching and thread pool, database connections.
Singleton Logging ServiceLogging service that is guaranteed to be a singleton. Based on Python logging, but every instantiation of LoggingService from any of an application's modules returns the same logger instance.
3 Answers. Show activity on this post. IMHO yes, services should not hold state and should therefore be made singleton.
I put a logger instance in my dependency injection container, which then injects the logger into the classes which need one.
This is getting annoying too - it is not DRY
That's true. But there is only so much you can do for a cross-cutting concern that pervades every type you have. You have to use the logger everywhere, so you must have the property on those types.
So lets see what we can do about it.
Singletons are terrible <flame-suit-on>
.
I recommend sticking with property injection as you've done with your second example. This is the best factoring you can do without resorting to magic. It is better to have an explicit dependency than to hide it via a singleton.
But if singletons save you significant time, including all refactoring you will ever have to do (crystal ball time!), I suppose you might be able to live with them. If ever there were a use for a Singleton, this might be it. Keep in mind the cost if you ever want to change your mind will be about as high as it gets.
If you do this, check out other people's answers using the Registry
pattern (see the description), and those registering a (resetable) singleton factory rather than a singleton logger instance.
There are other alternatives that might work just as well without as much compromise, so you should check them out first.
You could use Visual Studio code snippets to speed up the entrance of that repetitive code. You will be able to type something like logger
tab, and the code will magically appear for you.
You could eliminate a little bit of that property injection code by using an Aspect Oriented Programming (AOP) framework like PostSharp to auto-generate some of it.
It might look something like this when you're done:
[InjectedLogger] public ILogger Logger { get; set; }
You could also use their method tracing sample code to automatically trace method entrance and exit code, which might eliminate the need to add some of the logger properties all together. You could apply the attribute at a class level, or namespace wide:
[Trace] public class MyClass { // ... } // or #if DEBUG [assembly: Trace( AttributeTargetTypes = "MyNamespace.*", AttributeTargetTypeAttributes = MulticastAttributes.Public, AttributeTargetMemberAttributes = MulticastAttributes.Public )] #endif
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With