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

ASP.NET Core DI中程序集扫描注册接口与实现并复用实例

ASP.NET Core DI 批量注册接口与实现类复用同一实例解决方案

方案一:基于现有接口注册补充实现类工厂

保留你已完成的(1)处接口注册,在(3)处通过工厂函数从已注册的IAnalyser实例中筛选对应类型的对象,实现实例复用:

IEnumerable<Type> implementationTypes = ScanClientAssembliesForImplementationsOfIAnalyser();

foreach (var implementationType in implementationTypes)
{
    services.AddSingleton(typeof(IAnalyser), implementationType);  // (1) 保持原注册逻辑
    // (3) 注册实现类的工厂,复用接口注册的单例实例
    services.AddSingleton(implementationType, x => 
        x.GetServices<IAnalyser>().First(s => s.GetType() == implementationType));
}

逻辑说明

  • (1)处的注册会为每个implementationType创建单例实例,并作为IAnalyser的实现项加入DI容器
  • (3)处的工厂函数从容器的所有IAnalyser实例中筛选出当前类型的对象,确保解析具体实现类时拿到的是和接口注册相同的实例

方案二:先注册实现类单例再关联接口

换一种更直观的注册顺序,先把实现类本身注册为单例,再将IAnalyser接口指向该单例:

IEnumerable<Type> implementationTypes = ScanClientAssembliesForImplementationsOfIAnalyser();

foreach (var implementationType in implementationTypes)
{
    // 先注册实现类为单例
    services.AddSingleton(implementationType);
    // 再将IAnalyser接口关联到该单例
    services.AddSingleton(typeof(IAnalyser), x => x.GetRequiredService(implementationType));
}

逻辑说明

  • 先确保每个实现类本身是单例实例,再让IAnalyser接口的服务指向这个已存在的单例
  • 不管是解析IEnumerable<IAnalyser>还是具体的实现类(如FooAnalyser),拿到的都是同一个对象

验证实例一致性

可以用以下代码验证是否复用了同一实例:

var analysers = serviceProvider.GetRequiredService<IEnumerable<IAnalyser>>();
var fooAnalyser = serviceProvider.GetRequiredService<FooAnalyser>();

// 断言实例引用相同,验证成功则无异常
Debug.Assert(analysers.Any(a => ReferenceEquals(a, fooAnalyser)));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 17:55:08