重用Azure Function中的作用域ILogger实例

时间:2018-11-05 17:54:10

标签: c# dependency-injection simple-injector

我不确定要实现自己想要达到的目标的最佳方法是什么,所以让我给你举个例子。

我正在使用具有以下签名的无状态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实例。

我仔细阅读了文档,我认为这里需要一个新的范围,但不确定。我只希望在此一个方法调用的 async 执行期间使用此ILogger实例。每个函数调用将使用自己的函数。

请注意,控制器只是许多服务中涉及的许多服务(服务,存储库,请求处理程序)之一。执行任务。

有什么帮助吗?

1 个答案:

答案 0 :(得分:1)

您可以执行以下操作:

  • 创建一个代理(例如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);
    }
}

但是,我确实认为该模型会导致大量基础结构代码。最好您希望将此基础结构保持在最低限度。相反,您可以尝试按照here的说明将Azure Functions保持为小型Humble对象。那可能无法完全解决您的最初问题,但是无论如何您可能不需要特定于方法的记录器。但是,另一方面,如果您需要这样做,则可以使用C#的CallerMemberName属性和ProxyLogger方法来混合使用Humble Object方法。您确实不需要Azure注入ILogger来为您完成此操作。