How to wire up AutoFac to Common.Logging?

僤鯓⒐⒋嵵緔 提交于 2019-12-24 15:22:00

问题


I have a class like so:

public class LoggedFoo
{
    private readonly ILog _logger;

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

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

One of the business requirements is that logs are being generated for certain functions, so naturally I want to mock out the ILog to verify.

However, Common.Logging library supports type-based loggers, along the lines of:

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

...or:

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

The problem is, we are using AutoFac for dependency injection, and I cannot figure out how to instantiate an ILog based upon the class that is being instantiated for injection.

How do I write this? I am using the latest Nuget version of AutoFac.


回答1:


I can think on 2 ways to achieve it:(well sorry the hour is 1:50 am in my country...)

  1. Change your ILog to ILog<T> and then register it as an Open Generic.

  2. Use Dynamic-Providers which allows you to resolve with a context.

Autofac's website has an example which seems to be the exact thing you were looking for.

Resolve the dependency with a context:

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)),
    });
}

Attach to:

protected override void AttachToComponentRegistration(IComponentRegistry componentRegistry, IComponentRegistration registration)
{
    // Handle constructor parameters.
    registration.Preparing += OnComponentPreparing;

    // Handle properties.
    registration.Activated += (sender, e) => InjectLoggerProperties(e.Instance);
}



回答2:


So recently I decided the best way to do this was not to inject the ILog interface, but rather the ILogManager interface, like so:

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

By doing this, I cut out a lot of the headscratching necessary to figure out which logger needed to be referenced. I defined my ILogManager class once with an SingleInstance lifetime and never looked back.



来源:https://stackoverflow.com/questions/31974924/how-to-wire-up-autofac-to-common-logging

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!