代码之家  ›  专栏  ›  技术社区  ›  AngryHacker

如何获取引用程序集中的所有类型?

  •  33
  • AngryHacker  · 技术社区  · 14 年前

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

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

    我试过了 Assembly.GetExecutingAssembly().GetReferencedAssemblies() 但这只会返回mscorlib。

    我错过了什么?

    3 回复  |  直到 6 年前
        1
  •  57
  •   jason    14 年前

    注意 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 文件。为此,请查看 ItemGroup 元素包含 Reference 元素。

    最后,如果知道程序集的位置,可以使用 Assembly.LoadFile 然后本质上像上面一样继续枚举该加载的程序集中的类型。

        2
  •  0
  •   Deepak Ageeru    6 年前

    我还遇到了这样一种情况:我必须获取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
  •  0
  •   Zinov    6 年前

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

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

    当你打电话 Assembly.Load("C path").GetReferenceAssemblies 如果您从未引用类、枚举、接口…那是C组件的一部分。

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

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

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

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