c# – 如何使用AutoFac解析正确的记录器类型?

前端之家收集整理的这篇文章主要介绍了c# – 如何使用AutoFac解析正确的记录器类型?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在更新使用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>();

猜你在找的C#相关文章