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

如何在Microsoft.Extensions.DependencyInjection中将多服务注册为单实例

如何让实现多接口的服务在DI中共享单实例

当你分别通过AddSingleton<Interface1, Service>和AddSingleton<Interface2, Service>注册服务时,ASP.NET Core DI容器会把这两个注册视为独立的单例条目,因此会创建两个不同的Service实例——每个接口对应一个实例,这就是你看到i1 == i2返回false的原因。

下面是两种无需手动构造实例、同时保留DI自动管理依赖优势的解决方案:

方法一:先注册服务本身为单例,再映射接口

先将Service本身注册为单例,让DI自动处理它的依赖注入,再把每个接口都映射到这个已创建的单例:

var services = new ServiceCollection();

// 注册服务的依赖项
services.AddSingleton<Dependency1>();
services.AddSingleton<Dependency2>();

// 第一步:把Service本身注册为单例,DI会自动解析构造函数里的依赖
services.AddSingleton<Service>();

// 第二步:让每个接口都指向容器里的同一个Service单例
services.AddSingleton<Interface1>(sp => sp.GetRequiredService<Service>());
services.AddSingleton<Interface2>(sp => sp.GetRequiredService<Service>());

var provider = services.BuildServiceProvider();
var i1 = provider.GetService<Interface1>();
var i2 = provider.GetService<Interface2>();

Console.WriteLine(i1 == i2); // 输出 True

核心逻辑

  • 注册Service为单例时,DI容器会自动初始化它并注入Dependency1、Dependency2,完全不需要手动调用构造函数。
  • 接口注册时用的工厂函数,会直接从容器里拿已经存在的Service单例,确保所有接口请求都指向同一个实例。

方法二:简化的接口关联写法

和方法一逻辑完全一致,只是写法更紧凑:

var services = new ServiceCollection();

services.AddSingleton<Dependency1>();
services.AddSingleton<Dependency2>();

services.AddSingleton<Service>();

// 直接将接口与容器中的Service单例绑定
services.AddSingleton<Interface1>(provider => provider.GetRequiredService<Service>());
services.AddSingleton<Interface2>(provider => provider.GetRequiredService<Service>());

原注册方式生成多实例的原因

AddSingleton<TInterface, TImplementation>()的规则是:为每个TInterface单独维护一个TImplementation的单例。所以你为Interface1和Interface2分别注册时,容器会分别初始化两个独立的Service实例,自然不会是同一个引用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 21:04:55