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

如何筛选仅实现IRepository而非IReportRepository接口的仓储类?

如何筛选仅实现IRepository接口的仓储类

要找出那些只实现IRepository<T>而没有实现任何IReportRepository<T>的仓储类,我们可以用C#的反射来完成这个任务。核心思路是遍历程序集中的类型,检查它们实现的接口是否符合条件。

具体步骤和代码实现

首先,我们需要通过反射获取目标程序集里的所有类型,然后按以下条件筛选:

  1. 是可实例化的类(非抽象、非密封,可根据你的实际情况调整)
  2. 至少实现了一个IRepository<T>泛型接口(直接或间接通过具体仓储接口)
  3. 没有实现任何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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:33:31