注意:更新了建议的改进,更接近但仍然不完全!
与此问题类似 - Passing in the type of the declaring class for NLog using Autofac - 我正在尝试将NLog实例注入我的存储库类。
接口:
public interface ILogger<T>
where T: class
{
...
}
实现:
public class NLogger<T> : ILogger<T>
where T: class
{
private readonly Logger _logger;
public NLogger()
{
_logger = LogManager.GetLogger(typeof(T).FullName);
}
public void Debug(string message)
{
_logger.Debug(message);
}
...
}
在Autofac注册为:
builder.RegisterGeneric(typeof (NLogger<>)).As(typeof (ILogger<>));
使用断点,我看到Autofac正在创建一堆ILogger / NLogger,其中包含所有各种存储库的正确类型,但生成的日志显示为callsite为“NLog.LoggerImpl.Write”。
感谢您的帮助!
使用泛型的工作解决方案:
public class NLogger<T> : ILogger<T>
where T: class
{
private readonly Logger _logger;
public NLogger()
{
_logger = LogManager.GetLogger(typeof(T).FullName);
}
public void Debug(string message)
{
_logger.Log(typeof(T), new LogEventInfo(LogLevel.Debug, _logger.Name, message));
}
答案 0 :(得分:4)
记录器包装器需要调用.Log()并传递其他信息以使callsite工作。例如:
_logger.Log(typeof (NLogger<T>), new LogEventInfo(LogLevel.Debug, _logger.Name, null, format, args));
编辑:既然你还有问题,我就是这样做的,我知道它的行为是正确的:
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 });
};
}
}
答案 1 :(得分:0)
对于那些使用ILogger
命名空间Microsoft.Extensions.Logging
和NLog.Extensions.Logging
Nuget包的人。
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 });
}
}