简体   繁体   English

在不加载其程序集的情况下获取引用类型的全名

[英]Get the full name of a referenced type without loading its assembly

I have a .Net project where I'm given an assembly ( *.dll ), and I have to list out the contained types and their members.我有一个 .Net 项目,其中有一个程序集 ( *.dll ),我必须列出包含的类型及其成员。 However, I'm not given the assembly's references.但是,我没有得到程序集的参考。

Suppose I'm given A.dll which has a type in it:假设我得到了A.dll ,其中有一个类型:

public class TypeInA : IInterfaceInB
{
    ...
}

Since I'm not given B, I get a FileNotFoundException when I try to call因为我没有得到 B,所以当我尝试调用时我得到一个FileNotFoundException

typeof(TypeInA).GetInterfaces()

because it can't find B.dll .因为它找不到B.dll

I don't need the details about IInterfaceInB , just its namespace-qualified name.我不需要有关IInterfaceInB的详细信息,只需要它的命名空间限定名称。 Is there a way I can get this without having to load B.dll ?有没有办法不用加载B.dll就可以得到这个?

More context更多背景

I'm following the MetadataLoadContext docs to load A.dll and enumerate its types:我正在按照MetadataLoadContext文档加载A.dll并枚举其类型:

var runtimeAssemblies = Directory.GetFiles(RuntimeEnvironment.GetRuntimeDirectory(), "*.dll");
var paths = new List<string>(runtimeAssemblies) {path};
var resolver = new PathAssemblyResolver(paths);
using var context = new MetadataLoadContext(resolver);

var assembly = context.LoadFromAssemblyPath(path);

As provided by the Docs you posted as well正如您发布的文档所提供的那样

This collection, besides assemblies you want to inspect directly, should also include all needed dependencies.除了要直接检查的程序集之外,该集合还应包括所有需要的依赖项。 For example, to read the custom attribute located in an external assembly, you should include that assembly or an exception will be thrown.例如,要读取位于外部程序集中的自定义属性,您应该包含该程序集,否则将引发异常。

Since you do not have B.dll , I think it is normal that it throws an exception the moment you try to access any information in that assembly.由于您没有B.dll ,我认为在您尝试访问该程序集中的任何信息时抛出异常是正常的。

However, when I used ildasm.exe on A.dll, I could easily see the implemented interface(s)'s name(s).但是,当我在 A.dll 上使用 ildasm.exe 时,我可以很容易地看到实现的接口的名称。 So It should be possible at least to get the names.所以至少应该可以得到名字。

有可能的!!!

There is this decompiling library called dnlib , which I use occasionally.有一个名为dnlib反编译库,我偶尔会使用它。 Here is a sample code where you can read A.dll without having B.dll and moreover get Types' implemented interfaces FullName.这是一个示例代码,您可以在其中读取 A.dll,而无需 B.dll,而且还可以获取 Types 实现的接口 FullName。

using System;
using System.Linq;
using dnlib.DotNet;
......
......
private static void Main(string[] args) {
    // You need a module context in order to load an assembly
    var moduleContext = ModuleDef.CreateModuleContext();
    // This is the loaded module, please take note that it not loaded into your Domain
    var loadedModule = ModuleDefMD.Load(@"A.dll", moduleContext);
    var classes = loadedModule
        .GetTypes() //You want types in this assembly
         // I think you need classes, (structs too maybe?)
         // But you do not need the Module
        .Where(t=>t.IsClass && t.IsGlobalModuleType == false);

    foreach (var typeDef in classes) {
        Console.WriteLine($"{typeDef.FullName} implements:");
        foreach (var typeDefInterface in typeDef.Interfaces) {
            Console.WriteLine($"  {typeDefInterface.Interface.FullName}");
        }
    }
    Console.ReadKey();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM