Search code examples
c#dependency-injectionlight-inject

How can I inject class-specific logger using LightInject?


Many logging frameworks provide class-specific loggers:

NLog: Logger.GetLogger(typeof(MyClass).Name)

Serilog: Log.Logger.ForContext<MyClass>()

To be able to inject these class specific loggers, one would do something like this in Ninject:

        Bind<ILog>().ToMethod(context =>
        {
            var typeForLogger = context.Request.Target != null ? context.Request.Target.Member.DeclaringType : context.Request.Service;
            return context.Kernel.Get<ILoggerFactory>().GetLogger(typeForLogger);
        });

where context.Request.Target provides the type that will receive the injection.

I can't find any way to do the same using LightInject; is this feature not supported (yet)?


Solution

  • Turns out someone else had the same problem: https://github.com/seesharper/LightInject/issues/186

    Basically, the solution is to use a logger class that takes in the classname as a constructor parameter:

    public interface ILog
    {
        void Debug(string message, params object[] args);
    }
    
    public class SeriLogger : ILog
    {
        static SeriLogger ()
        {
            LoggerConfig = new LoggerConfiguration()
                .MinimumLevel.Debug()
                .WriteTo.Trace();
        }
    
        private readonly ILogger logger;
        private static readonly LoggerConfiguration LoggerConfig;
    
        public SeriLogger(Type type)
        {
            logger = LoggerConfig.CreateLogger().ForContext(type);
        }
    
        public void Debug(string message, params object[] args)
        {
            logger.Debug(message, args);
        }
    }
    

    And then register the logger using RegisterConstructorDependency:

    // Wherever you register your types
    container.RegisterConstructorDependency<ILog>((factory, info) => new SeriLogger(info.Member.DeclaringType));