Steven Steven - 23 days ago 9
C# Question

Implementation and usage of logger wrapper for Microsoft.Extensions.Logging

This question is related to Steven’s answer - here. He proposed a very good logger wrapper. I will paste his code below:

public interface ILogger
{
void Log(LogEntry entry);
}

public static class LoggerExtensions
{
public static void Log(this ILogger logger, string message)
{
logger.Log(new LogEntry(LoggingEventType.Information,
message, null));
}

public static void Log(this ILogger logger, Exception exception)
{
logger.Log(new LogEntry(LoggingEventType.Error,
exception.Message, exception));
}

// More methods here.
}


So, my question is what is the proper way to create implementation that proxies to Microsoft.Extensions.Logging and what is the best way to use it later in the code?

Note: this question is a copy of this question about log4net but now specific to Microsoft.Extensions.Logging.

Answer

So, my question is what is the proper way to create implementation that proxies to Microsoft.Extensions.ILogger?

you should create something like:

public sealed class MicrosoftLoggingAdapter  : ILogger
{
    private readonly Microsoft.Extensions.ILogger adaptee;

    public MicrosoftLoggingAdapter (Microsoft.Extensions.ILogger adaptee)
    {
        this.adaptee = adaptee;
    }

    public void Log(LogEntry e) =>
        adaptee.Log(ToLevel(e.Severity), 0, e.Message, e.Exception, (s, _) => s);       

    private static LogLevel ToLevel(LoggingEventType s) =>
        s == LoggingEventType.Debug ? LogLevel.Debug  :
        s == LoggingEventType.Information ? LogLevel.Information :
        s == LoggingEventType.Warning ? LogLevel.Warning :
        s == LoggingEventType.Error ? LogLevel.Error :
        LogLevel.Critical;      
}

what is the best way to use it later in the code?

If you are using a DI container, then just use the DI container to map ILogger to MicrosoftLoggingAdapter. You also need to register Microsoft.Extensions.ILogger, or just give an instance of MS logger to the DI container to inject it to the MicrosoftLoggingAdapter constructor.

If you don't use a DI container, i.e., you use Pure DI, then you do something like this:

var logger = loggerFactory.CreateLogger("Application");

ILogger logging_adapter = new MicrosoftLoggingAdapter(logger);

var myobject = new MyClass(other_dependencies_here, logging_adapter);
Comments