You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

依赖注入与静态访问器获取的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 14:52:23