.net core 在azure函数的代码中获取ServiceLocator的所有权
我们有一个Azure函数v2.0,它使用一个执行日志记录的依赖项,而不是转发注入函数中的ILogger,该组件能否以某种方式获得IServiceLocator的控制权,以便我们可以执行GetService()来获得当前日志记录者的控制权 我曾尝试在启动时引导它,但这是不可能的,因为ILogger在功能应用程序的生命周期中还没有建立(请参见此处:) 在Azure函数中使用(单例)依赖项的最佳实践是什么,我们希望在其中注入ILogger 编辑:根据要求,我将提供som示例代码,以更好地说明我试图实现的目标:.net core 在azure函数的代码中获取ServiceLocator的所有权,.net-core,azure-functions,.net Core,Azure Functions,我们有一个Azure函数v2.0,它使用一个执行日志记录的依赖项,而不是转发注入函数中的ILogger,该组件能否以某种方式获得IServiceLocator的控制权,以便我们可以执行GetService()来获得当前日志记录者的控制权 我曾尝试在启动时引导它,但这是不可能的,因为ILogger在功能应用程序的生命周期中还没有建立(请参见此处:) 在Azure函数中使用(单例)依赖项的最佳实践是什么,我们希望在其中注入ILogger 编辑:根据要求,我将提供som示例代码,以更好地说明我试图实现
Startup {
public override void Configure(IFunctionsHostBuilder builder)
{
builder.Services.AddSingleton<IContentProvider, IContentProvider>();
}
}
...
public class ContentProvider : IContentProvider {
private ILogger _logger;
public ContentProvider(ILogger logger) {
_logger = logger;
}
public bool DoSomething() {
_logger.LogInformation("Doing something..."); // BOOM: _logger is null
}
}
...
public class Functions {
public StoreFunctions(
IContentProvider contentProvider
)
{
_contentProvider = contentProvider;
}
[FunctionName("MetadataStoreMessage")]
public async Task ReadMessage([ServiceBusTrigger(TopicName, SubscriptionName, Connection = "MessageBusConnection")]
string messageBody,
ILogger logger,
ExecutionContext context)
{
_contentProvider.DoSomething();
}
}
启动{
公共覆盖无效配置(IFunctionsHostBuilder)
{
builder.Services.AddSingleton();
}
}
...
公共类ContentProvider:IContentProvider{
私人ILogger_记录器;
公共内容提供者(ILogger记录器){
_记录器=记录器;
}
公共场所{
_logger.LogInformation(“正在做某事…”);//BOOM:\记录器为空
}
}
...
公共类功能{
公共存储功能(
IContentProvider内容提供者
)
{
_contentProvider=contentProvider;
}
[FunctionName(“MetadataStoreMessage”)]
公共异步任务ReadMessage([ServiceBusTrigger(TopicName,SubscriptionName,Connection=“MessageBusConnection”)]
字符串消息体,
ILogger记录器,
ExecutionContext(上下文)
{
_contentProvider.DoSomething();
}
}
编辑2:
通过将ILogger注入not null中,记录程序不会被设置为记录到另一个记录程序(Seq),我们希望所有日志都被发送到该记录程序:
builder.Services
.AddLogging(logging => logging.AddSeq(
Environment.GetEnvironmentVariable("SeqEndpoint"),
apiKey: Environment.GetEnvironmentVariable("SeqApiKey"))
);
builder.Services.AddSingleton<IContentProvider, ContentProvider>();
builder.Services
.AddLogging(logging=>logging.AddSeq(
Environment.GetEnvironmentVariable(“SeqEndpoint”),
apiKey:Environment.GetEnvironmentVariable(“SeqApiKey”))
);
builder.Services.AddSingleton();
我必须设置什么才能使AddLogging()应用于可注入ILogger 有几种方法可以注册单身汉。让我们假设一个单例
MySingleton
,它依赖于两个记录器:标准ILogger
,和MyCustomLogger
。
还假设我的单例是使用接口ISingleton
公开的。(稍后我们将展示如何在没有接口的情况下实现这一点)
public接口是ingleton{}
公共课米辛格尔顿:伊辛格尔顿
{
私人ILogger记录器;
私人ICustomLogger-customLogger;
公共MySingleton(ILogger记录器、ICustomLogger自定义记录器)
{
this.logger=记录器;
this.customLogger=customLogger;
}
}
为了进行设置,我们在Startup.Configure()
方法中添加以下行:
builder.Services.AddSingleton();
builder.Services.AddSingleton();
如果我们没有接口,我们也可以直接注册:
builder.Services.AddSingleton();
如果我想运行一些特殊代码来实例化我的singleton呢?我可以注册一个lambda
builder.Services.AddSingleton();
//builder.Services.AddSingleton();
builder.Services.AddSingleton(serviceProvider=>CreateAndInitMySingleton(serviceProvider));
CreateAndInitMySingleton的定义:
public MySingleton CreateAndInitMySingleton(IServiceProvider服务提供商)
{
ILogger logger=serviceProvider.GetService();
ICustomLogger customLogger=serviceProvider.GetService();
MySingleton MySingleton=新的MySingleton(记录器,自定义记录器);
返回迈辛格尔顿;
}
请注意,
ILogger
和ICustomLogger
在Startup.Configure
中不可用,但它们在lambda运行时可用。基于lambda的方法使服务提供者/定位器的使用变得很容易,但它给开发人员带来了更大的负担,以确保以正确的顺序进行实例化。我们通过向特定类中注入ILogger解决了这个问题。当ILogger为null时,ILogger不为null,并且可用。感谢您的回答您打算在什么时候记录一些内容?在函数中?如果您发布一些更好地演示它的示例代码,这将非常有用。是否需要在Configure方法中记录一些内容?注意,单例不一定需要在Configure方法中实例化。它只需要注册。DI将负责构建对象,并在需要的对象中注入ILogger。谢谢您的回答。我注意到以下情况:-当我尝试将ILogger注入构造函数时,它是null-当我尝试将ILogger注入构造函数时,它不是null,但是被注入的ILogger记录器没有设置为记录到其他日志接收器(Seq),即使启动中包含以下代码:builder.Services.AddLogging(logging=>logging.AddSeq(seqEndpoint,apiKey:seqApiKey));builder.Services.AddSingleton();您可以尝试一下:注入ilogerfactory
而不是ILogger
,然后通过调用loggerFactory.CreateLogger()创建ILogger
;
。例如,请参见:。此处使用serilog:。azure函数中的日志记录似乎还不完全稳定/成熟(不幸的是):(“虽然ILogger为null,但ILogger不为null”