如何筛选仅实现IRepository而非IReportRepository接口的仓储类?
如何筛选仅实现IRepository接口的仓储类
要找出那些只实现IRepository<T>而没有实现任何IReportRepository<T>的仓储类,我们可以用C#的反射来完成这个任务。核心思路是遍历程序集中的类型,检查它们实现的接口是否符合条件。
具体步骤和代码实现
首先,我们需要通过反射获取目标程序集里的所有类型,然后按以下条件筛选:
- 是可实例化的类(非抽象、非密封,可根据你的实际情况调整)
- 至少实现了一个
IRepository<T>泛型接口(直接或间接通过具体仓储接口) - 没有实现任何
IReportRepository<T>泛型接口(直接或间接)
这里是完整的代码示例,结合你给出的仓储结构:
using System; using System.Collections.Generic; using System.Linq; using System.Reflection; // 你的基础接口定义 public interface IRepository<T> { } public interface IReportRepository<T> { } // 示例中的仓储接口与实现类 public interface IBuildingRepository : IRepository<Building>, IReportRepository<BuildingReport> { } internal class BuildingRepository : IBuildingRepository { } public interface IAppointmentRepository : IRepository<Appointment> { } internal class AppointmentRepository : IAppointmentRepository { } // 实体类 public class Building { } public class BuildingReport { } public class Appointment { } class Program { static void Main(string[] args) { var targetRepositories = GetNonReportRepositories(); foreach (var repoType in targetRepositories) { Console.WriteLine($"仅实现IRepository的仓储类:{repoType.Name}"); } } static List<Type> GetNonReportRepositories() { // 获取包含仓储类的程序集,这里用当前执行程序集,你可以替换为指定程序集 var assembly = Assembly.GetExecutingAssembly(); return assembly.GetTypes() .Where(t => t.IsClass && !t.IsAbstract && !t.IsSealed && // 如果你的仓储类是密封的,可移除这个条件 !t.IsGenericType) // 排除泛型仓储类(如果存在) .Where(t => // 检查是否实现了IRepository<T>的任意泛型实例 t.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IRepository<>)) && // 检查是否没有实现任何IReportRepository<T>的泛型实例 !t.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IReportRepository<>))) .ToList(); } }
代码说明
- 程序集获取:
Assembly.GetExecutingAssembly()获取当前运行的程序集,如果你的仓储类在其他程序集,替换为Assembly.Load("YourAssemblyName")或者Assembly.GetAssembly(typeof(AppointmentRepository))来定位目标程序集。 - 接口检查:
GetInterfaces()会返回类实现的所有接口(包括间接继承的),所以即使你的仓储类实现的是IAppointmentRepository(它继承自IRepository<Appointment>),也能被检测到;而BuildingRepository因为间接实现了IReportRepository<BuildingReport>,会被第二个条件排除。 - 灵活性调整:如果你的仓储类有抽象基类、密封类或者泛型仓储,你可以调整
Where里的条件来适配。
边界情况处理
- 如果有类直接实现
IRepository<T>而不是通过具体的仓储接口,比如class DirectRepo : IRepository<Order>,这段代码也能正确筛选出来。 - 如果某个类同时实现了多个仓储接口,其中一个包含
IReportRepository,那么这个类会被排除(因为它满足了“实现了IReportRepository”的条件)。 - 如果你的
IReportRepository不是泛型接口,只需要移除IsGenericType的判断,直接比较接口类型是否等于typeof(IReportRepository)即可。
内容的提问来源于stack exchange,提问作者SventoryMang
相关产品推荐
相关产品推荐

