Sharing logger between different .NET frameworks

2020-06-18 09:35发布

问题:

I am creating an application framework that can be shared between .Net Core 1.2, .Net Core 2.0 and .NET Framework 4.6+. So I choose the target framework of my project as .NET Standard. In my framework project I have factory class that is used to send a text message or email. On application startup, each application configures the factory with the supported services as singleton instance with DI framework.

public class MyFactory : IMyFactory
{
      private ILogger _logger;
      private IDictionary<string,IMyService> _container = new Dictionary<string,IMyService>();

    // this method is called on application startup to configure supported services
    public void Configure(string[] keys, ILogger logger)
    {  
        foreach(var key in keys)
        {
             if(key == "text")
             {
                 container.Add(key,new TextMessageService());
             }   

             if(key == "email")
             {
                 container.Add(key,new EmailService());
             }
        }
    }

    //application call this method to send message
    public bool SendMessage(string key, string message)
    {
         // we don't want application to stop when publish fail, so we add try-catch and log the message
         var flag = false;

         try
         {
             var service= container[key];
             service.Publish(message);
             flag = true;
         }
         class(Exception ex)
         {
            _logger.Error(ex);
         }

         return flag;
    }
}

Issue: the publish method could fail for any reason. And in such case I don't want application to stop, instead the framework should log the error message. My problem is since the framework can be shared between different .NET frameworks, I don't know which type of ILooger I should be using that can be shared between .NET Core and .NET Full.

I am trying to avoid creating my own ILogger interface. Also currently all applications are using Serilog but in future that could change.

Can Microsoft.Extensions.Logging be used here?

回答1:

Yes it can. If you have to support netcore 1, then

Install-Package Microsoft.Extensions.Logging -Version 1.1.2 

would work:

  • https://www.nuget.org/packages/Microsoft.Extensions.Logging/1.1.2 tells that it requires netstandard1.1
  • https://github.com/dotnet/standard/blob/master/docs/versions.md tells you that all of your three target platforms implement netstandard1.1

But better still your reusable component only need rely on the Abstractions:

Install-Package Microsoft.Extensions.Logging.Abstractions -Version 1.1.2 

Your component only need reference ILogger, and the applications that use your component are not tied to using the MS extensions logger. In particular, if you look at the dependencies for

Serilog.Extensions.Logging -Version 2.0.2 

At https://www.nuget.org/packages/Serilog.Extensions.Logging/ , you can see that it depends on Abstractions but doesn't depend on the MS Extensions logger. Serilog does depend on netstandard1.3. But again the netstandard version page tells you all your targets support it.

The applications using your framework can then carry on using Serilog, so long as they know how to wrap a serilogger as a MS.Extensions ILogger. the SerilogLoggerProvider in Serilog.Extensions.Logging does the trick:

var msFrameworkLogger= new SerilogLoggerProvider(myExistingSerilog).CreateLogger("name");