.net core 在azure函数的代码中获取ServiceLocator的所有权

.net core 在azure函数的代码中获取ServiceLocator的所有权,.net-core,azure-functions,.net Core,Azure Functions,我们有一个Azure函数v2.0,它使用一个执行日志记录的依赖项,而不是转发注入函数中的ILogger,该组件能否以某种方式获得IServiceLocator的控制权,以便我们可以执行GetService()来获得当前日志记录者的控制权 我曾尝试在启动时引导它,但这是不可能的,因为ILogger在功能应用程序的生命周期中还没有建立(请参见此处:) 在Azure函数中使用(单例)依赖项的最佳实践是什么,我们希望在其中注入ILogger 编辑:根据要求,我将提供som示例代码,以更好地说明我试图实现

我们有一个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”