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

如何在构建IServiceProvider后添加服务并保证单例实例唯一?

解决.NET DI容器分阶段添加服务时单例重复创建的问题

问题原因

你遇到的问题核心在于:每次调用BuildServiceProvider()都会生成一个完全独立的服务容器实例,前后两个容器相互隔离。第一次创建的ClassA单例仅存在于第一个容器中,第二个容器无法识别它,因此在需要IClassA时会重新创建新实例,最终导致输出两次"Hello!!!"。


解决方案

方案1:先完成所有服务注册再构建容器(推荐)

这是最贴合.NET DI设计理念的方式,尽量避免分阶段构建容器。先把所有需要注册的服务添加到IServiceCollection,再一次性构建ServiceProvider。

IServiceCollection serviceCollection = new ServiceCollection();
// 第一阶段注册服务
serviceCollection.TryAddSingleton<IClassA, ClassA>();
// 第二阶段添加新服务
serviceCollection.TryAddSingleton<ClassB>();

// 仅构建一次容器
ServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();
serviceProvider.GetRequiredService<IClassA>();
serviceProvider.GetRequiredService<ClassB>();

输出只会有一次"Hello!!!",单例仅被创建一次。

方案2:手动复用已创建的单例实例

如果确实需要分阶段构建容器,可以先获取第一个容器中已创建的单例实例,在第二次注册服务时直接将该实例注册为单例,让第二个容器复用它。

IServiceCollection serviceCollection = new ServiceCollection();
serviceCollection.TryAddSingleton<IClassA, ClassA>();
ServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();
// 获取已创建的单例实例
IClassA existingClassA = serviceProvider.GetRequiredService<IClassA>();

// 新增服务时,手动注册已有的实例
serviceCollection.TryAddSingleton<IClassA>(existingClassA);
serviceCollection.TryAddSingleton<ClassB>();
// 重新构建容器
serviceProvider = serviceCollection.BuildServiceProvider();
serviceProvider.GetRequiredService<ClassB>();

此方案下输出同样只会有一次"Hello!!!",第二个容器直接使用第一次创建的ClassA实例。


补充说明

.NET原生DI的ServiceProvider是不可变的,一旦构建完成就无法修改内部的服务注册逻辑。分阶段构建容器本质是创建多个独立容器,这也是单例重复创建的根本原因。如果你的场景需要频繁动态添加服务,可以考虑使用第三方DI容器(如Autofac),它们支持更灵活的动态注册,但原生DI更推荐提前完成所有服务注册。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 12:15:43