我需要解释一下才能解决问题。
我有3个项目:
项目1可以看到项目2和3。
项目2可以看到项目3。
项目3是一个dll,其他是应用程序。
我必须设计一个包含很多子类的类。子类都有一个在基类中声明为抽象的方法,因此它们都必须使用它。 它们需要在所有项目中分布,因为methode中的代码直接与项目交互。
抽象基类在项目3中,子类在2和1中。 我有问题:
这是我写的方法:
public static IEnumerable<Type> GetSubClasses(Type typ)
{
IEnumerable<Type> subclasses =
from type in Assembly.GetAssembly(typ).GetTypes()
where type.IsSubclassOf(typ) && !type.IsAbstract
select type;
return subclasses;
}
我正在尝试获取该类型的所有子类,但是当我这样做时,我只从当前项目中获取子类。例如,如果我尝试从project1获取它们,我就不会从项目2中获取子类。
我该怎么做?我知道我可以从项目2获得程序集引用但它没有GetAssembly(Type t)方法,借助于我得到所有子类。 如果它是相同的,我就必须在那里做同样的事情。
我的第二个问题是,是否有更简单的方法?它有点......“大”在许多项目中有这些类,也许有一个解决方案将它们合二为一。 就像我说的那样,他们都需要的方法代码需要直接与他们所在的项目进行交互。
答案 0 :(得分:1)
问题是你在呼叫Assembly.GetTypes()
。这只为您提供了该特定程序集中的类。如果所有三个程序集都有Assembly
个对象,则可以执行类似
assem1.GetTypes()
.Concat(assem2.GetTypes())
.Concat(assem3.GetTypes())
所以问题是如何获得三个Assembly
对象。从项目1开始,您可以说
var assem1 = typeof(SomeClassInProj1).Assembly;
var assem2 = typeof(SomeClassInProj2).Assembly;
var assem3 = typeof(SomeClassInProj3).Assembly;
在您无法“看到”其他装配的项目中,您需要加载它们。请参阅Assembly.Load
的文档。
答案 1 :(得分:0)
您必须加载可能包含您要查找的类型的所有程序集,并像循环中一样查找类型。
我已经做了类似的事情,从当前应用程序bin文件夹中获取从一些基类继承的程序集中的所有类的列表:
// load all files from current dir which ends with `.dll`
var q = from s in Directory.GetFiles(Directory.GetCurrentDirectory(), "*.dll")
select s;
var types = q.Select(s => getTypes(s, myBaseType))
.SelectMany(typeList => typeList).ToList();
函数getTypes:
IEnumerable<Type> getTypes(string filePath, Type baseType) {
Assembly a = Assembly.LoadFrom(filePath);
return a.GetTypes().Where(t => t.IsSubclassOf(baseType) && !t.IsAbstract);
}
当您的文件夹中的dll不是.net程序集时,您必须处理BadImageFormatException
之类的一些例外。
另一种方法可能是配置要检查的程序集列表。
答案 2 :(得分:0)
任何基类或接口都不应该知道或关心其继承者或implmenters。任何交互都应限于被覆盖的抽象或虚拟成员。
同样,导出公共类型的程序集并非旨在了解有关导入程序的任何信息。使用“Early Binding”执行此操作将创建循环引用。
您可以完全反映加载到应用程序域中的所有程序集,并查看哪种继承自某种类型但是,您打算如何处理此信息?可能有一种更简单,更快捷的方法来实现这一目标。