Как подключить AutoFac к Common.Logging?

У меня есть такой класс:

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.

2 ответа

Решение

Я могу думать о двух способах достижения этого:(извините, в моей стране час 1:50...)

  1. Измени свой ILog в ILog<T> а затем зарегистрируйте его как открытый универсальный.

  2. Используйте Dynamic-Providers, который позволяет разрешать с контекстом.

AutofacНа сайте есть пример, который, кажется, является именно тем, что вы искали.

Разрешите зависимость с контекстом:

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

Делая это, я вырезал много царапин, необходимых, чтобы выяснить, на какой регистратор нужно ссылаться. Я определил мой ILogManager класс один раз с SingleInstance всю жизнь и никогда не оглядывался назад.

Другие вопросы по тегам