我的API中有两种类型的存储库类:
同时拥有IRepository和IReportRepository的人:
internal class BuildingRepository : IBuildingRepository
public interface IBuildingRepository : IRepository<Building>, IReportRepository<BuildingReport>
那些只有IRepository的人:
internal class AppointmentRepository : IAppointmentRepository
public interface IAppointmentRepository : IRepository<Appointment>
如何返回仅实现IRepository而非IReportRepository的所有存储库。我认为会是这样的:
var repoInterfaceType = typeof(IRepository<>);
var reportRepo = typeof(IReportRepository<>);
var repoTypes = asm.GetTypes().Where(x =>
!x.IsInterface && !x.IsAbstract && x.IsClass &&
!x.IsGenericType && x.GetInterfaces().Any(y =>
y.IsGenericType &&
repoInterfaceType.IsAssignableFrom(y.GetGenericTypeDefinition()) &&
!reportRepo.IsAssignableFrom(y.GetGenericTypeDefinition()))).ToList();
但它仍然让我回归。我错过了什么?
答案 0 :(得分:1)
您的xs ++ [0]
部分必须分成两个查询。因为,.Any(y =>
y.IsGenericType &&
repoInterfaceType.IsAssignableFrom(y.GetGenericTypeDefinition()) &&
!reportRepo.IsAssignableFrom(y.GetGenericTypeDefinition()))
类是BuildingRepository
的实现。此接口可从IRepository<Building>
分配,不能从IRepository<>
接口分配。在这种情况下,您的IReport<>
条件会返回true。
您的Linq可以修改为:
Any
答案 1 :(得分:1)
您可以使用GetInterface(string):
大大缩短代码var results = asm.GetTypes()
.Where
(
t => t.GetInterface("IRepository`1") != null
&& t.GetInterface("IReportRepository`1") == null
);
此LINQ将遍历所有类型并尝试检索两个感兴趣的接口。如果找不到该接口,则只返回null,所以我们只需要检查正确的接口是否为空而另一个是否为
。如果你想知道我在哪里获得字符串&#34; IReportRepository`1&#34;,这就是mangled name,这是CLR在内部使用的字符串(你可以从堆栈识别它)转储)。如果您对使用字符串文字感到不舒服,可以在运行时从类型的Name属性中获取它,例如
var mangledName = typeof(IReportRepository<>).Name;