如何将 AutoFac 连接到 Common.Logging?

How to wire up AutoFac to Common.Logging?

我有一个 class 像这样:

public class LoggedFoo
{
    private readonly ILog _logger;

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

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

其中一个业务需求就是某些功能正在生成日志,所以自然要mock出ILog来验证。

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

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

...或者:

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

问题是,我们正在使用 AutoFac 进行依赖项注入,我不知道如何根据正在为注入实例化的 class 实例化一个 ILog

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

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

  1. 将您的 ILog 更改为 ILog<T>,然后将其注册为 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);
}

所以最近我决定最好的方法不是注入 ILog 接口,而是注入 ILogManager 接口,就像这样:

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

通过这样做,我省去了很多需要弄清楚需要引用哪个记录器的麻烦。我用 SingleInstance 生命定义了我的 ILogManager class 一次,再也没有回头。