.NET 6中如何从Startup的ConfigureServices传递日志到静态扩展方法
解决.NET 6中Serilog无法注入ILogger的问题
问题描述
运行代码时出现以下错误:
无法解析类型为'Microsoft.Extensions.Logging.ILogger`1[xxx]'的服务,尝试激活'xxx.Startup'时失败。
问题原因
原代码中UseSerilog()的调用时机过晚,导致Serilog日志服务在Startup构造函数执行阶段尚未完成注册,依赖注入容器无法解析ILogger<Startup>实例。
解决方案
方案1:提前初始化Serilog并关联主机配置
调整Program.cs代码,先完成Serilog的初始化,再构建主机:
using Serilog; public class Program { public static void Main(string[] args) { // 先基于主机配置初始化Serilog var hostConfig = Host.CreateDefaultBuilder(args).Build().Configuration; Log.Logger = new LoggerConfiguration() .ReadFrom.Configuration(hostConfig) .CreateLogger(); try { Host.CreateDefaultBuilder(args) .UseSerilog() // 使用已配置好的Serilog实例 .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); }) .Build() .Run(); } finally { Log.CloseAndFlush(); } } }
方案2:不在Startup构造函数中注入日志,改用服务提供者获取
如果不想调整Serilog初始化流程,可以修改Startup.cs,在ConfigureServices中通过服务提供者获取日志实例:
using Microsoft.Extensions.Logging; public class Startup { public IConfiguration Configuration; private ILogger<Startup> _logger; // 移除构造函数中的ILogger注入 public Startup(IConfiguration configuration) { Configuration = configuration; } public void ConfigureServices(IServiceCollection serviceCollection) { // 从服务容器获取日志实例 _logger = serviceCollection.BuildServiceProvider().GetRequiredService<ILogger<Startup>>(); ExtensionMethod(_logger); } public void Configure(IApplicationBuilder app) { staticextensionmethod(_logger); } }
注意:此方式不推荐,提前构建服务提供者可能导致服务生命周期管理问题。
方案3:改用.NET 6推荐的顶级语句写法(无Startup类)
.NET 6简化了主机构建流程,无需单独的Startup类,可直接在Program.cs中完成所有配置,避免构造函数注入问题:
using Serilog; var builder = WebApplication.CreateBuilder(args); // 配置Serilog关联主机配置 builder.Host.UseSerilog((context, config) => { config.ReadFrom.Configuration(context.Configuration); }); // 获取日志实例使用 var logger = builder.Services.BuildServiceProvider().GetRequiredService<ILogger<Program>>(); logger.LogInformation("日志服务已初始化"); // 添加业务服务 builder.Services.AddControllers(); var app = builder.Build(); // 配置中间件 app.UseHttpsRedirection(); app.UseAuthorization(); app.MapControllers(); app.Run();
内容的提问来源于stack exchange,提问作者Jen
相关产品推荐
相关产品推荐

