重用 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
来为你做这件事。
我不确定实现我想要完成的目标的最佳方法是什么,所以让我举个例子。
我正在使用具有以下签名的无状态 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
来为你做这件事。