[英]Get the full name of a referenced type without loading its assembly
我有一个 .Net 项目,其中有一个程序集 ( *.dll
),我必须列出包含的类型及其成员。 但是,我没有得到程序集的参考。
假设我得到了A.dll
,其中有一个类型:
public class TypeInA : IInterfaceInB
{
...
}
因为我没有得到 B,所以当我尝试调用时我得到一个FileNotFoundException
typeof(TypeInA).GetInterfaces()
因为它找不到B.dll
。
我不需要有关IInterfaceInB
的详细信息,只需要它的命名空间限定名称。 有没有办法不用加载B.dll
就可以得到这个?
我正在按照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);
正如您发布的文档所提供的那样
除了要直接检查的程序集之外,该集合还应包括所有需要的依赖项。 例如,要读取位于外部程序集中的自定义属性,您应该包含该程序集,否则将引发异常。
由于您没有B.dll
,我认为在您尝试访问该程序集中的任何信息时抛出异常是正常的。
但是,当我在 A.dll 上使用 ildasm.exe 时,我可以很容易地看到实现的接口的名称。 所以至少应该可以得到名字。
有一个名为dnlib
反编译库,我偶尔会使用它。 这是一个示例代码,您可以在其中读取 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.