Passing in the type of the declaring class for NLog using Autofac

前端 未结 3 1116
野趣味
野趣味 2021-01-06 08:11

Following on from this question I would like autofac to inject the type of the declaring object into the constructor of my NLog service, so that it can correctly log which t

3条回答
  •  离开以前
    2021-01-06 08:55

    There is no real good way to do this with Autofac, because does not have support for 'context based injection' (which is what you are trying to do). There is a workaround, but it aint pretty...

    What you can do is revert to property injection and define a base class or interface for that ILogService property. For instance, you can define the following interface:

    public interface ILoggerContainer
    {
        public ILogService Logger { get; set; }
    }
    

    Now you can implement this interface on all types that need a logger:

    public class Consumer : IConsumer, ILoggerContainer
    {
        public ILogService Logger { get; set; }
    }
    

    With this in place you can configure Autofac as follows:

    builder.RegisterType()
        .OnActivating(e =>
    {
        var type = typeof(LogService<>)
            .MakeGenericType(e.Instance.GetType());
        e.Instance.Logger = e.Context.Resolve(type);
    });
    

    Another workaround, that you may find cleaner is to inject an ILogger with the same type as the type of the parent type:

    public class Consumer : IConsumer
    {
        public Consumer(ILogger logger) { }
    }
    

    This makes the configuration much easier and prevents you from having to have a base class. Which one is most appropriate is up to you.

    As I said, these are workarounds, but to be honest, you might need to reconsider your logging strategy in your application. Perhaps you are logging at too many places. In the applications I write there is hardly ever a need to log, and when I do, I write an logging message that is expressive enough so that there is no need to communicate the type that triggered the event. And when you log exception, you will always have a complete stack trace (and exception logging should almost only happen in the outer layer of your application and not within services anyway).

提交回复
热议问题