如何批量注入继承自特定泛型接口的所有类?(C#)
正确实现批量注入继承自ICrud的服务类
问题核心在于你之前判断类是否实现ICrud<T>的逻辑有误:直接用GetInterfaces().Contains(typeof(ICrud<>))无法匹配,因为typeof(ICrud<>)是开放泛型类型,而类实际实现的是ICrud<Test>这类封闭泛型类型,二者不能直接相等。
完整解决方案代码
以下是修正后的扩展方法,会自动绑定类与其直接实现的上层接口(如ITestService),而非底层的ICrud<T>:
using System.Reflection; using Microsoft.Extensions.DependencyInjection; public static class ServiceCollectionExtensions { // 批量注入指定程序集中所有继承自ICrud<T>的服务类 public static void AddCrudServices(this IServiceCollection services, Assembly assembly) { // 筛选程序集中非抽象、非泛型的可实例化类 var serviceClasses = assembly.GetExportedTypes() .Where(t => t.IsClass && !t.IsAbstract && !t.IsGenericType); foreach (var classType in serviceClasses) { // 找出该类实现的所有接口中,根源是ICrud<>的接口 var relevantInterfaces = classType.GetInterfaces() .Where(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(ICrud<>)) // 关联到类直接实现的上层接口(如ITestService) .SelectMany(i => classType.GetInterfaces().Where(di => di.IsAssignableFrom(i) || di.GetInterfaces().Contains(i))) .Distinct(); // 去重避免重复注入 foreach (var interfaceType in relevantInterfaces) { // 绑定接口与实现类,生命周期可按需修改为Scoped/Singleton services.AddTransient(interfaceType, classType); } } } // 重载:直接使用ICrud<>所在的程序集 public static void AddCrudServices(this IServiceCollection services) { AddCrudServices(services, typeof(ICrud<>).Assembly); } }
关键逻辑说明
- 正确匹配ICrud
实现 :通过i.IsGenericType && i.GetGenericTypeDefinition() == typeof(ICrud<>)判断接口是否是ICrud<>的具体泛型实现。 - 绑定直接业务接口:优先绑定
ITestService这类业务接口,而非ICrud<Test>,保证依赖注入时能直接注入业务接口。 - 去重处理:避免同一接口被多次注册。
使用方式
在Program.cs或Startup类中调用:
// 注入ICrud<>所在程序集中的所有Crud服务 builder.Services.AddCrudServices(); // 或者指定特定程序集 // builder.Services.AddCrudServices(typeof(TestService).Assembly);
内容的提问来源于stack exchange,提问作者CBC_NS
相关产品推荐
相关产品推荐

