Повторно использовать экземпляр ILogger с областью действия из функции Azure. - PullRequest
0 голосов
/ 05 ноября 2018

Я не уверен, что это лучший способ достичь того, чего я пытаюсь достичь, поэтому позвольте мне привести вам пример.

Я использую функции Azure без состояния со следующей подписью.

public static Task Run(Message message, ILogger logger)
{
    var controller = Main.Container.GetInstance<ConsumerController>();

    // How can I attach the passed in logger instance so the rest of
    // the services for the current flow re-use this instance?

    return controller.Execute(message);
}

Как видите, платформа функций Azure передает мне экземпляр ILogger, уже настроенного и инициализированного для этого вызова функции только .

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

И для ясности, контроллер - это всего лишь один из многих сервисов (сервисов, репозиториев, обработчиков запросов), участвующих в выполнении задача.

Любая помощь будет отличной?

1 Ответ

0 голосов
/ 05 ноября 2018

Вы можете сделать следующее:

  • Создайте реализацию Proxy (например, ProxyLogger), которая реализует ILogger, содержит свойство ILogger Logger и перенаправляет любой вызов этого свойства.
  • Зарегистрируйте этот прокси как ILogger и ProxyLogger как Lifestyle.Scoped.
  • Разрешите ProxyLogger в пределах вашей функции.
  • Установите ProxyLogger.Logger, используя функцию ILogger.
  • Разрешить корневой объект и использовать его.

Создать прокси:

public class ProxyLogger : ILogger
{
    public ILogger Logger { get; set; }

    public void Log<TState>(LogLevel l, EventId id, TState s, Exception ex,
       Func<TState,Exception,String> f) =>
       this.Logger.Log<TState>(l, id, s, ex, f);
    // Implement other functions
}

Зарегистрируйте этот прокси:

container.Register<ProxyLogger>(Lifestyle.Scoped);
container.Register<ILogger, ProxyLogger>(Lifestyle.Scoped);

Разрешите ProxyLogger в вашей функции, установите ProxyLogger.Logger, используя предоставленную функцией ILogger, и разрешите корневой объект и используйте его.

public static Task Run(Message message, ILogger logger)
{
    using (AsyncScopedLifestyle.BeginScope(Main.Container)
    {
        Main.Container.GetInstance<ProxyLogger>().Logger = logger;

        var controller = Main.Container.GetInstance<ConsumerController>();

        return controller.Execute(message);
    }
}

Однако я думаю, что эта модель приводит к очень большому количеству инфраструктурного кода. Желательно, чтобы вы хотели сохранить эту инфраструктуру до абсолютного минимума. Вместо этого вы можете попытаться сохранить свои функции Azure небольшими скромными объектами, как описано здесь . Это может не полностью решить вашу первоначальную проблему, но вам, возможно, не понадобится логер для конкретного метода. Но если, с другой стороны, вам это нужно, вы можете смешать подход Humble Object с использованием атрибута CallerMemberName в C # и подхода ProxyLogger. Вам действительно не нужно вводить Azure ILogger, чтобы сделать это за вас.

...