Azure Functions V3:无法让 ILogger 使用 DI

Azure Functions V3: Unable to get ILogger working with DI

我们有一个 Azure Function v3,想通过构造函数将 ILogger<MyFunction> logger 注入我们的函数 类。我们正在努力让它与 Serilog 作为默认记录器一起工作。

我尝试了如下所示的不同方法,但出现了不同的错误。

Startup.cs:

public class Startup : FunctionsStartup
{
    public override void Configure(IFunctionsHostBuilder builder)
    {
        builder.Services.AddSingleton<ILoggerFactory, LoggerFactory>();
        builder.Services.AddSingleton<ILoggerProvider>(sp =>
        {
            var logger = new LoggerConfiguration().WriteTo.Elasticsearch(
                new ElasticsearchSinkOptions(...)
                .CreateLogger();
            return new SerilogLoggerProvider(logger, dispose: true);
        });
    }
}

但是,我收到以下错误:

Method Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton: type argument 'Microsoft.Extensions.Logging.LoggerFactory' violates the constraint of type parameter 'TImplementation'. Value cannot be null. (Parameter 'provider')

如果我尝试像下面这样添加工厂: builder.Services.AddSingleton<ILoggerFactory>(sp => new LoggerFactory());

错误是:

Microsoft.Azure.WebJobs.Script.WebHost: Registered factory delegate returns service Microsoft.Extensions.Logging.LoggerFactory is not assignable to container. Value cannot be null. (Parameter 'provider')

在添加 IFactoryLogger 时尝试将记录器一次性添加到工厂中导致以下错误:

Method not found: 'Void Microsoft.Extensions.Logging.LoggerFactory..ctor(System.Collections.Generic.IEnumerable`1<Microsoft.Extensions.Logging.ILoggerProvider>)'. Value cannot be null. (Parameter 'provider')

我也试过在不声明工厂的情况下添加默认日志记录:

builder.Services.Add(ServiceDescriptor.Describe(typeof(ILogger<>), typeof(Logger<>), ServiceLifetime.Scoped));

错误是:

Microsoft.Extensions.Logging.Abstractions: Value cannot be null. (Parameter 'factory').

我是不是漏掉了一些重要的东西?

下面是在Azure Functions V3中添加Serilog的方法:

  • 创建一个 Serilog 记录器实例,其中包含控制台和文件接收器的所有配置。
  • builder.Services.AddLogging 方法中注册此记录器。

相关代码:

// Startup.cs - Registering a third party logging provider
var logger = new LoggerConfiguration()
                .WriteTo.Console()
                .WriteTo.File("log.txt", rollingInterval: RollingInterval.Day)
                .CreateLogger();
builder.Services.AddLogging(lb => lb.AddSerilog(logger));

完成Startup.cs:

// Startup.cs
using AzureFunctionDependencyInjection.Configurations;
using AzureFunctionDependencyInjection.Services;
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Serilog;
[assembly: FunctionsStartup(typeof(AzureFunctionDependencyInjection.Startup))]
namespace AzureFunctionDependencyInjection
{
    public class Startup : FunctionsStartup
    {
        public override void Configure(IFunctionsHostBuilder builder)
        {
            // Registering Configurations (IOptions pattern)
            builder
                .Services
                .AddOptions<MessageResponderConfiguration>()
                .Configure<IConfiguration>((messageResponderSettings, configuration) =>
                {
                    configuration
                    .GetSection("MessageResponder")
                    .Bind(messageResponderSettings);
                });
// Registering Serilog provider
            var logger = new LoggerConfiguration()
                .WriteTo.Console()
                .WriteTo.File("log.txt", rollingInterval: RollingInterval.Day)
                .CreateLogger();
            builder.Services.AddLogging(lb => lb.AddSerilog(logger));
// Registering services
            builder
                .Services
                .AddSingleton<IMessageResponderService, MessageResponderService>();
        }
    }
}

查看这篇详细而精彩的文章:Dependency Injection in Azure Functions V3