依赖注入与静态访问器获取的LoggerHelper单例实例不一致问题
问题原因分析
核心问题在于:你手动创建的临时ServiceProvider和ASP.NET Core运行时使用的主容器不是同一个实例。
当你在Startup代码中调用services.BuildServiceProvider()时,会生成一个独立的临时容器——这个容器里的LoggerHelper单例,和后续应用启动时框架创建的主容器中的LoggerHelper是完全不同的对象:
- 你在临时容器中获取并设置
LogId="55"的实例,仅属于这个临时容器,存入静态访问器后,和主容器的实例没有任何关联。 - ASP.NET Core运行时启动时会重新构建主ServiceProvider,此时会重新创建
LoggerHelper的单例实例(主容器与临时容器相互独立),所以依赖注入到LoggingService中的是全新实例,LogId自然为null。
修复方案
方案1:从主容器获取实例初始化(推荐)
在Program.cs中,应用构建完成后从主ServiceProvider获取实例并设置属性,确保操作的是运行时实际使用的单例:
var builder = WebApplication.CreateBuilder(args); // 注册服务 builder.Services.AddSingleton<ISingletonLoggerHelper, LoggerHelper>(); builder.Services.AddScoped<LoggingService>(); var app = builder.Build(); // 从主容器获取实例并初始化 var loggerHelper = app.Services.GetRequiredService<ISingletonLoggerHelper>() as LoggerHelper; LoggerHelperAccessor.loggerHelper = loggerHelper; loggerHelper.LogId = "55"; // 其他中间件配置... app.Run();
方案2:避免静态访问器,直接依赖注入传递
如果业务场景允许,去掉静态访问器,所有需要LoggerHelper的地方都通过构造函数注入ISingletonLoggerHelper,这样整个应用中获取的都是主容器的同一个单例实例。
方案3:在构造函数中初始化固定值
如果LogId是固定值,可直接在LoggerHelper的构造函数中赋值:
public class LoggerHelper : ISingletonLoggerHelper { public string LogId { get; set; } public LoggerHelper() { LogId = "55"; } }
内容的提问来源于stack exchange,提问作者Hamza AlAjlouni
相关产品推荐
相关产品推荐

