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

.NET Core 3.1中Scoped Service注入后属性为空问题排查

问题分析与解决方案

问题现象

在.NET Core 3.1环境下,IMyService是Scoped服务,MyController构造函数注入该服务后将其MyProperty设置为"Hello";ISecondaryService是Transient服务,其构造函数同样注入IMyService,但ISecondaryService中的IMyService实例的MyProperty为空。

核心原因:依赖解析顺序导致赋值时机滞后

当请求触发MyController创建时,DI容器的解析流程如下:

  1. 容器优先解析控制器构造函数的第一个参数ISecondaryService:
    • 实例化SecondaryService时,需要注入IMyService的Scoped实例(记为实例A),此时实例A的MyProperty为默认null,SecondaryService构造函数执行时拿到的就是这个未赋值的实例。
  2. 容器接着解析控制器的第二个参数IMyService:
    • 由于是Scoped作用域,返回同一个实例A。
  3. 进入MyController构造函数体后,才将实例A的MyProperty设置为"Hello"。

如果你的代码是在SecondaryService的构造函数中直接访问MyProperty,此时赋值操作还未执行,所以得到空值;但如果是在控制器的Action方法中调用SecondaryService的方法访问MyProperty,此时已经完成赋值,应该能拿到正确的"Hello"。

解决方案

方案1:提前初始化IMyService属性

将MyProperty的赋值逻辑提前到IMyService实例创建阶段,确保任何依赖它的服务拿到的都是已赋值的实例:

// Startup.cs中修改服务注册
services.AddScoped<IMyService, MyService>(sp => 
{
    var myService = new MyService();
    myService.MyProperty = "Hello";
    return myService;
});

方案2:延迟访问MyProperty

避免在SecondaryService的构造函数中访问MyProperty,改为在实际业务方法中访问,确保此时控制器已完成赋值:

public class SecondaryService : ISecondaryService
{
    private readonly IMyService _myService;

    public SecondaryService(IMyService myService)
    {
        _myService = myService;
        // 不要在此处访问_myService.MyProperty
    }

    public void DoBusinessLogic()
    {
        // 在此处访问MyProperty,此时已被控制器赋值
        var propertyValue = _myService.MyProperty; // 结果为"Hello"
    }
}

方案3:自定义初始化逻辑(可选)

让IMyService实现自定义初始化接口,在DI容器解析后触发初始化,确保属性提前赋值:

// 自定义初始化接口
public interface IServiceInitializer
{
    void Initialize();
}

public class MyService : IMyService, IServiceInitializer
{
    public string MyProperty { get; set; }

    public void Initialize()
    {
        MyProperty = "Hello";
    }
}

// Startup.cs中注册服务并添加初始化逻辑
services.AddScoped<IMyService, MyService>();
services.AddScoped<IServiceInitializer>(sp => (IServiceInitializer)sp.GetRequiredService<IMyService>());

// 控制器构造函数中触发初始化
public MyController(ISecondaryService secondaryService, IServiceInitializer initializer)
{
    initializer.Initialize();
}

内容的提问来源于stack exchange,提问作者Paul

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 01:55:20