c#encapsulation:从其他项目中获取类型

时间:2012-11-08 08:53:22

标签: c# types encapsulation .net-assembly projects

我需要解释一下才能解决问题。

我有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)方法,借助于我得到所有子类。 如果它是相同的,我就必须在那里做同样的事情。

我的第二个问题是,是否有更简单的方法?它有点......“大”在许多项目中有这些类,也许有一个解决方案将它们合二为一。 就像我说的那样,他们都需要的方法代码需要直接与他们所在的项目进行交互。

3 个答案:

答案 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”执行此操作将创建循环引用。

您可以完全反映加载到应用程序域中的所有程序集,并查看哪种继承自某种类型但是,您打算如何处理此信息?可能有一种更简单,更快捷的方法来实现这一目标。