注射用NLOG Autofac的RegisterGeneric [英] Injecting NLog with Autofac's RegisterGeneric
问题描述
请注意:更新与改进建议,更贴近,但仍然不太有
这个问题相似 - 的在使用NLOG autofac 声明类的类型传递 - 我想注入NLOG情况下进入我的仓库类。
接口:
公共接口ILogger< T>
,其中T:类
{
:
}
实施
公共类NLogger< T> :ILogger< T>
,其中T:类
{
私人只读记录仪_logger;
公共NLogger()
{
_logger = LogManager.GetLogger(typeof运算(T).FullName);
}
公共无效调试(字符串消息)
{
_logger.Debug(消息);
}
:
}
与Autofac注册为:
builder.RegisterGeneric(typeof运算(NLogger<>)),为(typeof运算(ILogger<> ));
使用断点,我看到Autofac是创造了一堆ILogger / NLogger与正确的类型所有我的各种信息库中,但由此产生的日志显示了调用点是NLog.LoggerImpl.Write。
感谢您的帮助!
泛型工作液:
公共类NLogger< ; T> :ILogger< T>
,其中T:类
{
私人只读记录仪_logger;
公共NLogger()
{
_logger = LogManager.GetLogger(typeof运算(T).FullName);
}
公共无效调试(字符串消息)
{
_logger.Log(typeof运算(T),新LogEventInfo(LogLevel.Debug,_logger.Name,消息));
}
记录仪的包装需要调用。日志(),并通过为调用点工作的其他信息。例如:
<预类=郎-CS prettyprint-覆盖>
_logger.Log(typeof运算(NLogger< T>),新LogEventInfo(LogLevel的的.debug,_logger.Name,空,格式,参数));
编辑:既然你仍然有问题,这里就是我如何做到这一点,我知道它的表现正确的:
<预类=郎-CS prettyprint-覆盖>
公共接口ILog的
{
[StringFormatMethodAttribute(格式)]
无效调试(字符串格式,params对象[]参数);
[StringFormatMethodAttribute(格式)]
无效信息(字符串格式,params对象[]参数);
[StringFormatMethodAttribute(格式)]
无效警告(字符串格式,params对象[]参数);
[StringFormatMethodAttribute(格式)]
无效错误(字符串格式,params对象[]参数);
无效错误(异常前);
[StringFormatMethodAttribute(格式)]
无效错误(异常前,字符串格式,params对象[]参数);
[StringFormatMethodAttribute(格式)]
无效致命(异常前,字符串格式,params对象[]参数);
}
公共类NLogLogger:ILog的
{
私人只读记录仪_log;
公共NLogLogger(type类型)
{
_log = LogManager.GetLogger(type.FullName);
}
公共无效调试(字符串格式,params对象[]参数)
{
日志(LogLevel.Debug,格式,参数);
}
公共无效信息(字符串格式,params对象[]参数)
{
日志(LogLevel.Info,格式,参数);
}
公共无效警告(字符串格式,params对象[]参数)
{
日志(LogLevel.Warn,格式,参数);
}
公共无效的错误(字符串格式,params对象[]参数)
{
日志(LogLevel.Error,格式,参数);
}
公共无效错误(异常前)
{
日志(LogLevel.Error,NULL,NULL,前);
}
公共无效错误(异常前,字符串格式,params对象[]参数)
{
日志(LogLevel.Error,格式,ARGS,恩) ;
}
公共无效致命(异常前,字符串格式,params对象[]参数)
{
日志(LogLevel.Fatal,格式,ARGS,恩) ;
}
私人无效日志(LogLevel的水平,字符串格式,对象[]参数)
{
_log.Log(typeof运算(NLogLogger),新LogEventInfo(水平,_log.Name,空,格式,参数));
}
私人无效日志(LogLevel的水平,字符串格式,对象[] ARGS,异常前)
{
_log.Log(typeof运算(NLogLogger),新LogEventInfo(水平,_log.Name,空,格式,ARGS,除息));
}
}
公共类日志:模块
{
保护覆盖无效负载(ContainerBuilder建设者)
{
建设者
.Register((C,p)=>新建NLogLogger(p.TypedAs<类型和GT;()))
.AsImplementedInterfaces();
}
保护覆盖无效AttachToComponentRegistration(IComponentRegistry componentRegistry,IComponentRegistration注册)
{
registration.Preparing + =
(发件人,参数)=>
{
VAR forType = args.Component.Activator.LimitType;
变种logParameter =新ResolvedParameter(
(P,C)=> p.ParameterType == typeof运算(ILog的),
(P,C)=℃。解决&所述; ILog的>(TypedParameter.From(forType)));
args.Parameters = args.Parameters.Union(新[] {logParameter});
};
}
}
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 Autofac - I am trying to inject NLog instances into my repository classes.
Interface:
public interface ILogger<T>
where T: class
{
...
}
Implementation:
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);
}
...
}
Registered with Autofac as:
builder.RegisterGeneric(typeof (NLogger<>)).As(typeof (ILogger<>));
Using breakpoints, I see that Autofac is creating a bunch of ILogger/NLogger's with the correct types for all of my various repositories, but the resulting logs show up with callsite being "NLog.LoggerImpl.Write".
Thanks for any help!
Working solution with generics:
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));
}
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 });
};
}
}
这篇关于注射用NLOG Autofac的RegisterGeneric的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!