如何在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
相关产品推荐
相关产品推荐

