使用Autofac的RegisterGeneric注入NLog
注意:更新了建议的改进,更接近但仍然不完全!
与此问题类似 – 使用Autofac传递NLog的声明类的类型 – 我试图将NLog实例注入我的存储库类。
接口:
public interface ILogger where T: class { ... }
执行:
public class NLogger : ILogger 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”。
谢谢你的帮助!
使用generics的工作解决方案:
public class NLogger : ILogger 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)); }
记录器包装器需要调用.Log()并传递呼叫站点的其他信息才能工作。 例如:
_logger.Log(typeof (NLogger), 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())) .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(TypedParameter.From(forType))); args.Parameters = args.Parameters.Union(new[] { logParameter }); }; } }
对于那些使用来自Microsoft.Extensions.Logging
命名空间的ILogger
以及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 p) { var logger = _provider.CreateLogger(p.TypedAs().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(TypedParameter.From(forType))); args.Parameters = args.Parameters.Union(new[] { logParameter }); } }