Injecting NLog with Autofac's RegisterGeneric

后端 未结 2 814
时光取名叫无心
时光取名叫无心 2020-12-14 13:05

Note: Updated with suggested improvements, closer but still not quite there!

Similar to this question - Passing in the type of the declaring class for NLog using Aut

相关标签:
2条回答
  • 2020-12-14 13:35

    Logger wrappers need to call .Log() and pass additional info for callsite to work. For example:

    _logger.Log(typeof (NLogger<T>), new LogEventInfo(LogLevel.Debug, _logger.Name, null, format, args));
    

    EDIT: Since you're still having trouble, here's how I do it, and I know it's behaving correctly:

    public interface ILog
    {
        [StringFormatMethodAttribute("format")]
        void Debug(string format, params object[] args);
        [StringFormatMethodAttribute("format")]
        void Info(string format, params object[] args);
        [StringFormatMethodAttribute("format")]
        void Warn(string format, params object[] args);
    
        [StringFormatMethodAttribute("format")] 
        void Error(string format, params object[] args);
        void Error(Exception ex);
    
        [StringFormatMethodAttribute("format")]
        void Error(Exception ex, string format, params object[] args);
    
        [StringFormatMethodAttribute("format")]
        void Fatal(Exception ex, string format, params object[] args);
    }
    
    public class NLogLogger : ILog
    {
        private readonly Logger _log;
    
        public NLogLogger(Type type)
        {
            _log = LogManager.GetLogger(type.FullName);
        }
    
        public void Debug(string format, params object[] args)
        {
            Log(LogLevel.Debug, format, args);
        }
    
        public void Info(string format, params object[] args)
        {
            Log(LogLevel.Info, format, args);
        }
    
        public void Warn(string format, params object[] args)
        {
            Log(LogLevel.Warn, format, args);
        }
    
        public void Error(string format, params object[] args)
        {
            Log(LogLevel.Error, format, args);
        }
    
        public void Error(Exception ex)
        {
            Log(LogLevel.Error, null, null, ex);
        }
    
        public void Error(Exception ex, string format, params object[] args)
        {
            Log(LogLevel.Error, format, args, ex);
        }
    
        public void Fatal(Exception ex, string format, params object[] args)
        {
            Log(LogLevel.Fatal, format, args, ex);
        }
    
        private void Log(LogLevel level, string format, object[] args)
        {
            _log.Log(typeof (NLogLogger), new LogEventInfo(level, _log.Name, null, format, args));
        }
    
        private void Log(LogLevel level, string format, object[] args, Exception ex)
        {
            _log.Log(typeof (NLogLogger), new LogEventInfo(level, _log.Name, null, format, args, ex));
        }
    }
    
    public class LoggingModule : Module
    {
        protected override void Load(ContainerBuilder builder)
        {
            builder
                .Register((c, p) => new NLogLogger(p.TypedAs<Type>()))
                .AsImplementedInterfaces();
        }
    
        protected override void AttachToComponentRegistration(IComponentRegistry componentRegistry, IComponentRegistration registration)
        {
            registration.Preparing +=
                (sender, args) =>
                {
                    var forType = args.Component.Activator.LimitType;
    
                    var logParameter = new ResolvedParameter(
                        (p, c) => p.ParameterType == typeof(ILog),
                        (p, c) => c.Resolve<ILog>(TypedParameter.From(forType)));
    
                    args.Parameters = args.Parameters.Union(new[] { logParameter });
                };
        }
    }
    
    0 讨论(0)
  • 2020-12-14 13:48

    For those using ILogger from Microsoft.Extensions.Logging namespace together with NLog.Extensions.Logging Nuget package.

    public class NLoggerModule : Module
    {
        private readonly NLogLoggerProvider _provider;
    
        public NLoggerModule()
        {
            _provider = new NLogLoggerProvider();
        }
    
        protected override void Load(ContainerBuilder builder)
        {
            builder.Register(CreateLogger).AsImplementedInterfaces();
        }
    
        private ILogger CreateLogger(IComponentContext c, IEnumerable<Parameter> p)
        {
            var logger = _provider.CreateLogger(p.TypedAs<Type>().FullName);
            return logger;
        }
    
        protected override void AttachToComponentRegistration(IComponentRegistry componentRegistry, IComponentRegistration registration)
        {
            registration.Preparing += Registration_Preparing;
        }
    
        private void Registration_Preparing(object sender, PreparingEventArgs args)
        {
            var forType = args.Component.Activator.LimitType;
    
            var logParameter = new ResolvedParameter(
                (p, c) => p.ParameterType == typeof(ILogger),
                (p, c) => c.Resolve<ILogger>(TypedParameter.From(forType)));
    
            args.Parameters = args.Parameters.Union(new[] { logParameter });
        }
    }
    
    0 讨论(0)
提交回复
热议问题