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

