2016-06-03 7 views
6

Serilog позволяет создавать контекстно-зависимые регистратор:ILogger Serilog в впрыскивают с помощью Log.ForContext <T>, где Т потребитель

Log.ForContext<T>()

Я хотел бы зарегистрировать Serilog с SimpleInjector таким образом, что это T тип потребителя, т. е. какой класс он вводится.

например.

public class Car 
{ 
    public Car(ILogger logger) <= would be injected using Log.ForContext<Car>() 
    {    
    } 
} 

Я вижу это has been done with AutoFac.

И, просматривая SimpleInjector documentation, существует очень многообещающая перегрузка 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); 

однако, я не хочу сказать SimpleInjector который Тип строить, но как построить один.

+2

Мы явно опущены возможность зарегистрируйте делегат с помощью метода «RegisterConditional», поскольку это позволит принимать решения во время выполнения при создании графа объектов и не позволяет Simple Injector делать глубокий анализ на ваших объектных графах. Итак, этот трюк заключается в том, чтобы обернуть вызов 'Log.ForContext ' внутри самоопределяемого общего класса, что и есть то, что советует @janhartmann. Независимо от того, скрываете ли вы Серилог за своей собственной абстракцией, зависит от вас, но я абсолютно согласен с этим. Поэтому для меня ответ Яна - это * правильный ответ. – Steven

+2

Также убедитесь, что вы не слишком много записываете: https://stackoverflow.com/a/9915056/264697 – Steven

ответ

7

Я интегрировал Serilog с простым Injector с помощью следующего кода на основе @Steven гениального ответа на StackOverflow: 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); 
    } 

} 

В вашей композиции Корне:

var container = new Container(); 
container.RegisterLogging(); 
+3

Не реализованы ли потоки «Serilog.ILogger» в потоковом режиме? Я бы предложил сделать условную регистрацию «Синглтон», если это возможно. – Steven

+2

Вы абсолютно правы, @Steven - явно ошибка. Редактирование ответа. – janhartmann

+0

@janhartmann Я обнаружил, что времена, когда c.Consumer может быть нулевым (я считаю, с помощью шаблона Service Locator) и внесли поправки в мою строку следующим образом: 'c => typeof (SerilogLogger <>). MakeGenericType (c.Consumer? .ImplementationType? Typeof (object)). Как вы думаете? – jameskind

 Смежные вопросы

  • Нет связанных вопросов^_^