Serilog的ILogger使用Log.ForContext <T>注入,其中T是消费者

jam*_*ind 9 c# simple-injector serilog

Serilog允许创建一个上下文感知记录器:

Log.ForContext<T>()

我想用SimpleInjector注册Serilog,这T是消费者的类型,即它注入的是哪个类.

例如

public class Car
{
    public Car(ILogger logger) <= would be injected using Log.ForContext<Car>()
    {             
    }
}
Run Code Online (Sandbox Code Playgroud)

我可以看到这已经完成了AutoFac.

通过SimpleInjector文档,有一个非常有希望的重载RegisterConditional()(使用Func<TypeFactoryContext, Type>参数).

c.RegisterConditional(typeof (ILogger),
    x => Log.ForContext(x.Consumer.ImplementationType), <= won't compile as expecting a Type
    Lifestyle.Scoped,
    x => true);
Run Code Online (Sandbox Code Playgroud)

但是,我不想告诉SimpleInjector 要构建哪个 Type,而是如何构建一个.

jan*_*ann 10

我已经将Serilog与Simple Injector集成在一起,其代码基于StackOverflow上的@Steven天才答案:logger wrapper best practice

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

public class SerilogLogger<T> : ILogger
{
    private readonly Serilog.ILogger _logger;

    public SerilogLogger()
    {
        _logger = new LoggerConfiguration()
            .WriteTo
            .Trace(LogEventLevel.Information)
            .CreateLogger()
            .ForContext(typeof (T));
    }

    public void Log(LogEntry entry)
    {
        /* Logging abstraction handling */
    }
}

public static class ContainerExtensions {

    public static void RegisterLogging(this Container container)
    {
        container.RegisterConditional(
            typeof(ILogger),
            c => typeof(SerilogLogger<>).MakeGenericType(c.Consumer.ImplementationType),
            Lifestyle.Singleton,
            c => true);
    }

}
Run Code Online (Sandbox Code Playgroud)

在你的作文根:

var container = new Container();
container.RegisterLogging();
Run Code Online (Sandbox Code Playgroud)

  • @jameskind eemove null检查.如果没有人认为任何人直接从容器请求记录器(这不太可能),就让它破坏.不要掩盖不良行为; 暴露他们! (4认同)
  • 不是`Serilog.ILogger`实现线程安全吗?如果可能的话,我建议进行有条件的注册`Singleton`. (3认同)
  • 你是绝对正确的,@ Steven - 显然是一个错误.现在编辑答案. (2认同)