Injecting NLog with Autofac's RegisterGeneric

て烟熏妆下的殇ゞ 提交于 2019-11-28 22:03:13

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 });
            };
    }
}

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 });
    }
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!