I have a c# web service. When I get a new request I create a logging instance. I have many other instances of other classes to process the request and I want them to log as well. What is the best way to share logging instance without passing it in constructors or properties ?
-
What logging framework are you using? – Jakub Konecki Oct 21 '10 at 23:59
-
2below answers are good (basically use a static instance, guarded by a singleton). however, consider using a DI container to manage this. makes life easier for everyone. – RPM1984 Oct 22 '10 at 00:06
7 Answers
Often some sort of static class / property is used to share an object without needing to pass references everywhere, for example:
public class Logger
{
static Logger()
{
this.Instance - new Logger();
}
public static Logger Instance
{
get;
private set;
}
// Other non-static members
}
Usage:
Logger.Instance.Log();
Often this (or at least variations on this) are referred to as the singleton pattern.
There are many variations on the above, for example the following slight variation is more common than the above in logging frameworks:
public class Logger
{
static Logger()
{
this.Instance = new Logger();
}
public static Logger Instance
{
get;
private set;
}
public static void Log()
{
Logger.Instance.Log();
}
}
Usage:
Logger.Log();

- 84,773
- 49
- 224
- 367
-
This is an optimal solution; put Logger in its own library so you can reference it from every other project. – Steven A. Lowe Oct 22 '10 at 00:38
Singleton Pattern is an anti-pattern; I can not think of many instances where it should be used or recommended, including in this instance, for logging.
How we handle logging: A logging instance is injected into all classes that need it via constructor injection. For example:
public class MyClass
{
private readonly ILogger _logger;
public MyClass(ILogger logger)
{
_logger = logger;
}
public void DoStuff()
{
_logger.Trace("DoStuff called");
}
}
The logging instance injected can either be a new instance each time, or if you are bent on having a single instance logger it can be created once and passed through as needed.
However: I strongly recommend the first option, using DI to construct your classes using the Composition Root pattern. I also recommend using a logging framework, such as NLog or log4net. These are configurable and easy to use with emails, event viewer, files, etc. and work in multi threaded environments.
We have our own definition of ILogger which has Trace, Warn, Info, Exception, etc., and then implemented this interface using NLog. This means that we can easily change how we log by creating a new implementation of ILogger and then making a simple DI config update. This is one logging solution that has worked really well for us so far.
-
This is an inferior approach - especially if you have several similar requirements, your constructors will look ridiculous. It's far superior to have your classes have intelligence and be autonomous in determining their environments. The whole DI theory is amateurish and sloppy. There is nothing wrong with static classes, if you're writing c# you're already completely bound to them when you reference ANY MS core assemblies. String.Format() - etc... might as well use Logging.Log() – hajikelist May 11 '15 at 16:27
-
I see your point, but an actual case I have run into, is OAuth access tokens. The API which shall not be named only allows each refresh token to be used 4 times a minute so when our server makes 5+ requests in a minute, which it does all the time, the authorization fails. The access token however is good for an hour which solves this problem if I have a static value available on a class that can be shared between components. – CascadiaJS Apr 10 '20 at 21:25
-
"If you have several similar requirements, your constructors will look ridiculous" - constructor injection makes your dependencies visible. Singletons, or static classes, hide them. Using MS core static assemblies like String.Format is very different from creating your own static classes that will have a higher chance of changing / failing. Good class design should limit the number of dependencies needing to be injected - this includes logging; if you are injecting too many things into the constructor, the class is likely doing too much. – joecity Sep 30 '20 at 21:01
Singleton Pattern.
That is, a class with a private constructor. You use a public static method to create only one instance of the class and return the object.
edit: also worth noting that you will need to put this class in its own project so that it can be referenced by all classes.

- 231
- 3
- 6
Well, you could make your logging class contain static methods which do the actual writing into memory/flushing to disk. You could also look into the Singleton Pattern

- 122,712
- 22
- 185
- 265
You can use the Singleton Pattern to ensure that there is only a single instance of your logging object across the system.
Passing the logging object into the Constructor or as a property will actually make your code easier to test, depending on how you implement the Singleton pattern. Logging is one of those annoying cross-cutting concerns that always has trade-offs.

- 188
- 9
Usually it's not a problem to create a new instance of your logger in each class. Log4Net logger constructor takes a type as a parameter to give you better logs.

- 45,581
- 7
- 87
- 126
Use a static field (I assume C# supports theses). The syntax should be similar to this:
private static final Logger logger = new Logger(...);
and just use that whenever you need to log something in the class.

- 6,219
- 1
- 25
- 37