【问题标题】:How to get all types in a referenced assembly?如何获取引用程序集中的所有类型?
【发布时间】:2011-01-15 13:33:29
【问题描述】:

无论出于何种原因,我似乎都无法获得引用程序集中的类型列表。不仅如此,我什至似乎无法访问这个引用的程序集。

我试过AppDomain.CurrentDomain.GetAssemblies(),但它只返回已经加载到内存中的程序集。

我尝试了Assembly.GetExecutingAssembly().GetReferencedAssemblies(),但这只是返回 mscorlib。

我错过了什么?

【问题讨论】:

  • 您是在尝试检查项目引用的程序集,还是位于文件系统某处的程序集?
  • 我怀疑 CLR 的实现将无法从所有程序集中获取所有类型,因为它们必须在一个重要的时间进行即时编译,但我真的不是专家关于这一点,所以你应该只使用我的评论作为进一步探索的提示。
  • @yodaj007 引用的程序集
  • @itowlson 我的代码是一个全新的控制台项目,我在其中引用了一个我想检查的程序集。就是这样。

标签: c# .net reflection assemblies reference


【解决方案1】:

请注意,Assembly.GetReferencedAssemblies 仅包含特定程序集,前提是您在程序集中实际使用了该程序集中的类型(或者您使用的类型取决于该程序集中的类型)。仅仅在 Visual Studio 的引用列表中包含一个程序集是不够的。也许这解释了输出与您期望的差异?我注意到,如果您希望能够使用反射获得 Visual Studio 中引用列表中的所有程序集,那是不可能的;程序集的元数据不包括有关给定程序集不依赖的程序集的任何信息。

也就是说,一旦您检索到所有引用程序集的列表,如下所示应该可以让您枚举这些程序集中的所有类型:

foreach (var assemblyName in Assembly.GetExecutingAssembly().GetReferencedAssemblies()) {
    Assembly assembly = Assembly.Load(assemblyName);
    foreach (var type in assembly.GetTypes()) {
        Console.WriteLine(type.Name);
    }
}

如果您需要 Visual Studio 中引用的程序集,则必须解析 csproj 文件。为此,请查看包含 Reference 元素的 ItemGroup 元素。

最后,如果您知道程序集所在的位置,您可以使用 Assembly.LoadFile 加载它,然后基本上按照上述步骤枚举该加载的程序集中的类型。

【讨论】:

  • 在我的情况下,如果我从不使用它,即使我在项目中有引用,也不会包含该程序集!
【解决方案2】:

我还遇到了一种情况,即我必须获取 Visual Studio 中引用列表中的所有程序集。

我使用以下工作来完成它。

var path = AppContext.BaseDirectory;  // returns bin/debug path
var directory = new DirectoryInfo(path);

if (directory.Exists)
{
    var dllFiles = directory.GetFiles("*.dll");  // get only assembly files from debug path
}

【讨论】:

  • 这似乎是一个合理的解决方案
【解决方案3】:

GetReferencedAssemblies 方法基本上优化了程序集的发现过程,跳过了那些在主程序集中没有显式引用的程序集。

假设您有一个项目 B 和一个引用项目 B 的项目 C。 现在您创建一个新项目 A,它引用了 C(而不是 B)

当您调用 Assembly.Load("C path").GetReferenceAssemblies 时,如果您从未引用过作为 C 程序集一部分的类、枚举、接口...,它将只返回 B。

作为一种变通解决方案,您可以创建 C 中存在的类的虚拟实例。

Assembly.C.Class1 dummyInstance = new Assemply.C.Class1();

就个人而言,我使用此解决方案以防您需要在 Core 项目中分离所有接口,并在 Core.Proj1 中使用 Core 中使用的接口标记您的类,以便稍后在主程序集中发现。请记住,一旦加载多个程序集,反射就会对性能产生影响,因此不要以在目录上发现并加载所有程序集以获得所需类型的解决方案结束。因此,从那时起,您可以继续使用@jason 建议的代码

foreach(var ....)
  Assembly assembly = Assembly.Load(assemblyName);
    foreach (var type in assembly.GetTypes()) {
        Console.WriteLine(type.Name);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多