【问题标题】:How to wire up AutoFac to Common.Logging?如何将 AutoFac 连接到 Common.Logging?
【发布时间】:2016-04-15 11:17:01
【问题描述】:

我有这样的课:

public class LoggedFoo
{
    private readonly ILog _logger;

    public LoggedFoo(ILog logger)
    {
        this._logger = logger;
    }

    public DoStuff()
    {
        this._logger.Info(i => i("Doing stuff..."));
    }
}

业务需求之一是某些功能正在生成日志,所以自然要模拟出ILog来验证。

但是,Common.Logging 库支持基于类型的记录器,如下所示:

var logger = LogManager.GetLogger<LoggedFoo>();

...或:

var logger = LogManager.GetLogger(typeof(LoggedFoo));

问题是,我们使用 AutoFac 进行依赖注入,我不知道如何根据要为注入而实例化的类来实例化 ILog

我该怎么写?我正在使用最新的 Nuget 版本的 AutoFac。

【问题讨论】:

    标签: c# unit-testing dependency-injection mocking autofac


    【解决方案1】:

    我可以想出两种方法来实现它:(很抱歉,我的国家的时间是凌晨 1:50...)

    1. 将您的ILog 更改为ILog&lt;T&gt;,然后将其注册为Open Generic

    2. 使用Dynamic-Providers,它允许您使用上下文进行解析。

    Autofac 的网站上有一个 example,这似乎正是您要找的东西。

    使用上下文解决依赖关系:

    private static void OnComponentPreparing(object sender, PreparingEventArgs e)
    {
        var t = e.Component.Target.Activator.LimitType;
        e.Parameters = e.Parameters.Union(
        new[]
        {
          new ResolvedParameter((p, i) => p.ParameterType == typeof(ILog), 
                                (p, i) => LogManager.GetLogger(t)),
        });
    }
    

    附加到:

    protected override void AttachToComponentRegistration(IComponentRegistry componentRegistry, IComponentRegistration registration)
    {
        // Handle constructor parameters.
        registration.Preparing += OnComponentPreparing;
    
        // Handle properties.
        registration.Activated += (sender, e) => InjectLoggerProperties(e.Instance);
    }
    

    【讨论】:

    • 这些方法都去哪儿了?
    【解决方案2】:

    所以最近我决定最好的方法不是注入ILog 接口,而是注入ILogManager 接口,如下所示:

    public class Foo
    {
        private readonly ILog _logger;
        public Foo(ILogManager logManager)
        {
            _logger = logManager.GetLogger<Foo>();
        }
    }
    

    通过这样做,我省去了很多必要的麻烦,以确定需要引用哪个记录器。我用SingleInstance 的生命周期定义了一次ILogManager 类,并且从未回头。

    【讨论】:

    • 您是如何获得 ILogManager 的实例的?
    • 在我的 IoC 连线中,我只是执行以下操作:builder.RegisterType&lt;LogManager&gt;().SingleInstance().As&lt;ILogManager&gt;();
    • 啊,关于RegisterType的TIL。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2018-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-06
    • 2021-12-27
    • 2012-02-06
    相关资源
    最近更新 更多