ASP.NET Core(.NET 8)中Serilog无法注入Microsoft.Extensions.Logging.ILogger<T>
你遇到的ILogger<T>注入为null的问题,核心原因大概率是目标类未注册到依赖注入容器,或者Serilog的集成配置存在细微问题,以下是具体排查和解决步骤:
1. 优先检查目标类的DI注册状态
如果需要注入ILogger<T>的业务类没有通过AddScoped/AddTransient/AddSingleton注册到DI容器,DI系统无法解析该类的依赖,自然会导致ILogger<T>为null。
比如你的业务类MyService:
public class MyService { private readonly ILogger<MyService> _logger; public MyService(ILogger<MyService> logger) { _logger = logger; } }
必须在CreateBuilder方法中添加注册:
private static WebApplicationBuilder CreateBuilder(string[] args, MEL.ILogger? logger = null) { var builder = WebApplication.CreateBuilder(args); // 先配置Serilog builder.Host.UseSerilog((context, provider, config) => { config .Enrich.FromLogContext() .WriteTo.Debug(formatProvider: CultureInfo.InvariantCulture) .WriteTo.Console(formatProvider: CultureInfo.InvariantCulture) .ReadFrom.Configuration(builder.Configuration); }); // 注册业务类到DI容器 builder.Services.AddScoped<MyService>(); return builder; }
2. 确认Serilog.AspNetCore包的安装
确保项目已安装Serilog.AspNetCore NuGet包(而非仅Serilog核心包),该包包含了与Microsoft.Extensions.Logging的整合逻辑,会自动注册ILogger<T>的实现。
3. 检查日志配置的调用顺序
builder.Host.UseSerilog需要在其他服务注册前调用(至少在依赖日志的服务注册前),确保后续服务使用的是Serilog的日志系统。你的现有代码中调用顺序是正确的,但需要避免在UseSerilog之后调用builder.Logging.AddXXX等覆盖日志配置的代码。
4. 临时日志器的不影响性
你实现的临时日志器中,using var factory = new SerilogLoggerFactory(Log.Logger);会自动释放工厂,但返回的ILogger仅用于启动阶段日志,不会影响主应用DI容器中的日志服务注册,这部分代码没有问题。
验证方法
可以在管道中添加一个测试端点,验证ILogger<T>的注入状态:
private static void ConfigureHttpPipeline(WebApplication app) { app.MapGet("/test-logger", (ILogger<Program> logger) => { if (logger == null) return "ILogger<T> is null"; logger.LogInformation("ILogger<T> works normally"); return "ILogger<T> injection success"; }); }
访问该端点,如果返回成功,则说明DI中ILogger<T>注册正常,问题出在你的业务类未注册到DI;如果仍返回null,建议重新安装Serilog.AspNetCore包并清理项目后重新构建。
内容的提问来源于stack exchange,提问作者TaffarelJr

