.NET 6独立进程Azure Function中ILogger注入报错解决
解决.NET 6独立进程Azure Function中ILogger依赖注入错误问题
错误信息
System.InvalidOperationException: 尝试激活'ABC'时无法解析类型'Microsoft.Extensions.Logging.LoggerFactory'的服务
问题根源
- 服务类(ABC、Service)的构造函数依赖了具体的
LoggerFactory类而非ILoggerFactory接口,DI容器无法正确解析具体类型的依赖。 - .NET 6独立进程Azure Functions中,
ConfigureFunctionsWorkerDefaults()已默认配置完整的日志服务,手动注册LoggerFactory和Logger<>会导致DI容器冲突,反而无法正确解析服务。
解决方案
步骤1:修改服务类的日志注入方式
推荐直接注入泛型ILogger<T>,无需手动通过LoggerFactory创建Logger,更符合DI最佳实践:
修改ABC类
namespace MyFunction.Services { public class ABC : IABC { private readonly IService _serv; private readonly ILogger<ABC> _log; // 直接注入ILogger<ABC> public ABC(IService serv, ILogger<ABC> log) { _serv = serv; _log = log; } public async Task SyncDataAsync(EventData[] messages, PartitionContext context) { // 直接使用_log记录日志 _log.LogInformation("开始同步数据"); var xyz = await _serv.getDetails(); // 其他业务逻辑 } } }
修改Service类
namespace ClassLibrary1 { public class Service : IService { private readonly ILogger<Service> _log; // 直接注入ILogger<Service> public Service(ILogger<Service> log) { _log = log; } public async Task getDetails() { _log.LogInformation("获取详情"); // 业务逻辑 } } }
(可选)若坚持使用ILoggerFactory,修改构造函数参数为接口
如果不想直接用泛型ILogger,也可以将构造函数中的LoggerFactory改为ILoggerFactory接口:
// ABC类构造函数示例 public ABC(IService serv, ILoggerFactory loggerFactory) { _serv = serv; _log = loggerFactory.CreateLogger<ABC>(); }
步骤2:清理Program.cs中的冗余日志配置
移除手动注册LoggerFactory和Logger<>的代码,保留默认配置即可:
var host = new HostBuilder() .ConfigureFunctionsWorkerDefaults() .ConfigureServices(services => { services.AddApplicationInsightsTelemetryWorkerService(); services.ConfigureFunctionsApplicationInsights(); services.AddScoped<IABC, ABC>(); services.AddScoped<IService, Service>(); // 移除以下两行冗余代码 // services.AddSingleton<ILoggerFactory, LoggerFactory>(); // services.AddSingleton(typeof(ILogger<>), typeof(Logger<>)); }) .Build(); host.Run();
步骤3:(可选优化)简化MyFunctionProcessor类的日志注入
同样可以将MyFunctionProcessor的日志注入改为泛型ILogger,简化代码:
namespace MyFunction { public class MyFunctionProcessor { private readonly ILogger<MyFunctionProcessor> _log; private readonly IABC _iABC; // 直接注入ILogger<MyFunctionProcessor> public MyFunctionProcessor(ILogger<MyFunctionProcessor> log, IABC iABC) { _log = log; _iABC = iABC; } [Function(nameof(MyFunctionProcessor))] public async Task Run([EventHubTrigger("%EventHubName%", Connection = "ServiceBusConnectionString")] EventData[] events, PartitionContext partitionContext) { Guid correlationId = Guid.NewGuid(); _log.LogInformation("CorrelationId: {CorrelationId} ABC Processor Function has been started", correlationId); try { await _iABC.SyncDataAsync(events, partitionContext); } catch (Exception ex) { _log.LogError(ex, "CorrelationId: {CorrelationId} Exception while processing the event", correlationId); } } } }
说明
- .NET 6独立进程Azure Functions基于通用主机构建,
ConfigureFunctionsWorkerDefaults()已集成日志服务配置,包括LoggerFactory和Logger<>的注册,无需手动重复配置。 - 使用泛型
ILogger<T>可自动获取带有类名的日志类别,便于日志排查,同时符合依赖注入的面向接口原则。
内容的提问来源于stack exchange,提问作者prasanthi
相关产品推荐
相关产品推荐

