This may be somewhat related to Pass ILogger or ILoggerFactory to constructors in AspNet Core?, however this is specifically about Library Design, not about
The default approach is meant to be ILogger<T>
. This means that in the log the logs from the specific class will be clearly visible because they will include the full class name as the context. For example if the full name of your class is MyLibrary.MyClass
you will get this in the log entries created by this class. For example:
MyLibrary.MyClass:Information: My information log
You should use the ILoggerFactory
if you want to specify your own context. For example that all the logs from your library have the same log context instead every class. For example:
loggerFactory.CreateLogger("MyLibrary");
And then the log will look like this:
MyLibrary:Information: My information log
If you do that in all classes then the context will be just MyLibrary for all classes. I imagine you would want to do that for a library if you don't want to expose the inner class structure in the logs.
Regarding the optional logging. I think you should always require the ILogger or ILoggerFactory in the constructor and leave it to the consumer of the library to turn it off or provide a Logger that does nothing in the dependency injection if they don't want logging. It is very easy to turn of the logging for a specific context in the configuration. For example:
{
"Logging": {
"LogLevel": {
"Default": "Warning",
"MyLibrary": "None"
}
}
}
For library design good approach would be:
1.Do not force consumers to inject logger to your classes. Simply create another ctor passing NullLoggerFactory.
class MyClass
{
private readonly ILoggerFactory _loggerFactory;
public MyClass():this(NullLoggerFactory.Instance)
{
}
public MyClass(ILoggerFactory loggerFactory)
{
this._loggerFactory = loggerFactory ?? NullLoggerFactory.Instance;
}
}
2. Limit number of categories which you use when you create loggers to allow consumers configure logs filtering easily.
this._loggerFactory.CreateLogger(Consts.CategoryName)