重用 Azure Function 中的范围 ILogger 实例

Re-use scoped ILogger instance from Azure Function

我不确定实现我想要完成的目标的最佳方法是什么,所以让我举个例子。

我正在使用具有以下签名的无状态 Azure Functions。

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 实例,该实例已针对 this 函数调用进行了配置和初始化 only .

我通读了文档,我想我需要一个新的范围,但我不确定。我只希望在 async 执行此 one 方法调用期间使用此 ILogger 实例。每个函数调用都会使用它们自己的。

需要说明的是,控制器只是可能许多服务中的一个 (服务、存储库、请求处理程序)参与任务的执行。

有什么帮助会更好吗?

您可以执行以下操作:

  • 创建一个实现 ILogger 的代理(例如 ProxyLogger)实现,包含 ILogger Logger 属性,并将任何调用转发给 属性。
  • 将该代理注册为 ILogger 并将 ProxyLogger 注册为 Lifestyle.Scoped
  • 在您的函数中解析 ProxyLogger
  • 使用函数提供的ILogger设置ProxyLogger.Logger
  • 解析根对象并使用它。

创建代理:

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,使用函数提供的 ILogger 设置 ProxyLogger.Logger,解析根对象并使用它。

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 Functions 保持小的不起眼的对象,如 here. That might not completely solve your initial problem, but you might not need to have a method specific logger anyway. But if, on the other hand, you need that, you might be able to mix that Humble Object approach with the use of C#'s CallerMemberName 属性和 ProxyLogger 方法所述。你真的不需要注入 Azure ILogger 来为你做这件事。