从给定程序集中获取所有引用的程序集(使用 Roslyn 或通过反射)

问题描述 投票:0回答:1

我正在使用 Roslyn 对解决方案进行一些代码分析,解决方案中的一些项目引用了第 3 方程序集。

有没有办法通过 Roslyn 或反射来检索引用的程序集列表?

例如我有解决方案 = {ProjA, ProjB, ProjC} 和 ProjC 引用第 3 方程序集 = {3rdX, 3rdY} => 我想获得 3rdX 和 3rdY 程序集。

3rdX、3rdY 程序集不是解决方案的一部分:例如,它们可以是 Nuget 加载的第 3 方程序集。

c# reflection roslyn solution csproj
1个回答
0
投票

您可以使用反射来做到这一点:

using AssemblyNameDictionary = System.Collections.Generic.HashSet<System.Reflection.AssemblyName>;
using Assembly = System.Reflection.Assembly;
using AssemblyName = System.Reflection.AssemblyName;

//... 

class ReflectionDemo {

    static void GetReferencedAssemblies(Assembly current, AssemblyNameDictionary container) {
        AssemblyName[] references = current.GetReferencedAssemblies();
        foreach(var name in references) {
            container.Add(name);
            Assembly referencedAssembly = Assembly.Load(name);
            GetReferencedAssemblies(referencedAssembly, container);
        } //loop
    } //GetReferencedAssemblies

    static AssemblyName[] GetReferencedAssemblies(Assembly assembly) {
        AssemblyNameDictionary container = new();
        GetReferencedAssemblies(assembly, container);
        AssemblyName[] result = new AssemblyName[container.Count];
        container.CopyTo(result);
        return result;
    } //GetReferencedAssemblies

    // let's test it for, for example,
    // the entry assembly of the running application:
    static void Demo() {
        var result = GetReferencedAssemblies(Assembly.GetEntryAssembly());
        // inspect result and see that you got all you want
        // ...
    }

} //class ReflectionDemo

我使用了

HashSet
来避免程序集名称重复。这个方法给出了
System.Reflection.AssemblyName
的数组。

要获取

System.Reflection.Assembly
的实例并从名称中深入了解它,您必须使用
System.Reflection.Assembly.Load(System.Reflection.AssemblyName)
加载程序集,如上所示。但在这种情况下,程序集已经加载,因此,在这种情况下,您可能更愿意修改代码以获取
System.Reflection.Assembly
的实例:

using AssemblyDictionary = System.Collections.Generic.HashSet<System.Reflection.Assembly>;

// ...

class ReflectionDemo {

    static void GetReferencedAssemblies(Assembly current, AssemblyDictionary container) {
        AssemblyName[] references = current.GetReferencedAssemblies();
        foreach(var name in references) {
            Assembly referencedAssembly = Assembly.Load(name);
            container.Add(referencedAssembly);
            GetReferencedAssemblies(referencedAssembly, container);
        } //loop
    } //GetReferencedAssemblies

    static Assembly[] GetReferencedAssemblies(Assembly assembly) {
        AssemblyDictionary container = new();
        GetReferencedAssemblies(assembly, container);
        Assembly[] result = new Assembly[container.Count];
        container.CopyTo(result);
        return result;
    } //GetReferencedAssemblies

    static void Demo() {
        var result = GetReferencedAssemblies(Assembly.GetEntryAssembly());
        //...
    }

} //class ReflectionDemo
© www.soinside.com 2019 - 2024. All rights reserved.