我正在更新使用AutoFac的遗留项目,我想将NLog与简单记录外观(SLF)一起使用
我在过去和Ninject一起使用它,它很容易设置,我只需要做类似的事情:
kernel.Bind<ILogger>().ToMethod(x => LoggerFactory.GetLogger(x.Request.Target.Member.ReflectedType));
输出将是这样的:
NLogNinjectSlf.Services.MyService 2013-12-30 15:21:10.5782 DEBUG Log from injected Logger
小菜一碟
但现在我必须使用AutoFac,我不知道如何获得需要记录器的Target类型
例如,如果我有以下接口/类:
public interface IMyService { void DoSomething(); } public class MyService : IMyService { private readonly ILogger _logger; public MyService(ILogger logger) { _logger = logger; } public void DoSomething() { _logger.Debug("Log from injected Logger"); } }
我希望能够获取MyService类的类型,将其用作记录器的名称
在AutoFac中,这是我到目前为止所尝试的:
var containerBuilder = new ContainerBuilder(); containerBuilder.RegisterType<MyService>().As<IMyService>(); containerBuilder.Register(x => { // TODO: Get the correct type return LoggerFactory.GetLogger(x.GetType()); }).As<ILogger>();
顺便说一句:我在SLF4Net后面使用NLog并不是真正需要解决主要问题的……
解决方法
谢谢
nemesv对我帮助很大
这是我最终使用的代码
BTW.您可以根据需要删除注入属性的代码,然后在所有类中使用DI来注入可提高性能的ILogger
public class LoggingModule : Module { protected override void AttachToComponentRegistration(IComponentRegistry componentRegistry,IComponentRegistration registration) { registration.Preparing += OnComponentPreparing; registration.Activated += (sender,e) => InjectLoggerProperties(e.Instance); } private static void InjectLoggerProperties(object instance) { var instanceType = instance.GetType(); // Get all the injectable properties to set. // If you wanted to ensure the properties were only UNSET properties,// here's where you'd do it. var properties = instanceType .GetProperties(BindingFlags.Public | BindingFlags.Instance) .Where(p => p.PropertyType == typeof(ILogger) && p.CanWrite && p.GetIndexParameters().Length == 0); // Set the properties located. foreach (var propToSet in properties) { propToSet.SetValue(instance,LoggerFactory.GetLogger(instanceType),null); } } private void OnComponentPreparing(object sender,PreparingEventArgs e) { var t = e.Component.Activator.LimitType; e.Parameters = e.Parameters.Union( new[] { new ResolvedParameter((p,i) => p.ParameterType == typeof (ILogger),(p,i) => LoggerFactory.GetLogger(t)) }); } }
然后注册模块:
containerBuilder.RegisterModule<LoggingModule>();