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

 躲避世界2502862687 发布于 2023-02-07 14:12

我正在更新使用AutoFac的遗留项目,我想将NLog与简单记录外观(SLF)一起使用

我在过去和Ninject一起使用它,它很容易设置,我只需要做类似的事情:

kernel.Bind().ToMethod(x => LoggerFactory.GetLogger(x.Request.Target.Member.ReflectedType));

输出将是这样的:

NLogNinjectSlf.Services.MyService 2013-12-30 15:21:10.5782 DEBUG日志来自注入的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().As();

containerBuilder.Register(x =>
{
    // TODO: Get the correct type
    return LoggerFactory.GetLogger(x.GetType());
}).As();

顺便说一句:我在SLF4Net后面使用NLog并不是真正需要解决主要问题的......

1 个回答
  • 非常感谢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>();
    

    2023-02-07 14:15 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有