Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.5k views
in Technique[技术] by (71.8m points)

dependency injection - Serilog DI in ASP.NET Core, which ILogger interface to inject?

Context

I've successfully configured Serilog in my ASP.NET Core application, only the DI part remains.

Question

Now I have two ILogger interfaces, one is Serilog.ILogger the other is Microsoft.Extensions.Logging.ILogger. Both works based on my Serilog config, and I do not know which to use? (I mean, after Serilog config in place Microsoft.Extensions.Logging.ILogger also correctly logging through Serilog, so my config is honored)

In case Microsoft.Extensions.Logging.ILogger I do know how to configure DI to make it work. However in case of Serilog.ILogger I see that Serilog has a static Log.Logger instance (probably a singleton)

I do not want to use this static property in my code, mainly for testing reasons, so I would like to to constructor inject it. The solution would be:

services.AddSingleton(Log.Logger); // Log.Logger is a singleton anyway

..but I am concerning about this singleton in a Web Application when many multiple threads will use this very same instance concurrently. Is it thread safe? If it is not, then what would be the solution to use Serilog.ILogger with DI?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Choosing which interface to use within your application is a matter of taste, really. If you prefer Serilog's ILogger shorter method names (e.g. log.Error vs log.LogError), go with that, otherwise use the Microsoft's generic ILogger<>. You have control over all the dependencies you use in your own projects, so there's no strong technical reason to prefer one over the other.

You might be interested in reading this issue on Serilog's repo:

Should I use Microsoft.Extensions.Logging.ILogger or Serilog.ILogger?.

I personally use Serilog's ILogger across all my projects not only because I do prefer the shorter method names, but also because I prefer not to inject a logger in every single constructor of every class, and it's also easy to have a contextual logger for every class using Log.ForContext<>, which is useful when troubleshooting issues. E.g.

public class SomeService
{
    private readonly ILogger _log = Log.ForContext<SomeService>();
    // ...
}

public class SomeRepository
{
    private readonly ILogger _log = Log.ForContext<SomeRepository>();
    // ...
}

If you were developing a library though, I'd recommend using Microsoft's generic ILogger<>, of course, instead of taking a dependency on Serilog and force consumers of your library to also take a dependency on Serilog.


Log.Logger is thread-safe, thus registering as a singleton as you are doing above is correct if you want all classes to share the same instance (without SourceContexts) - nothing wrong with that.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...