我有一个 .Net 项目,其中有一个程序集 (*.dll
),我必须列出所包含的类型及其成员。但是,我没有获得程序集的引用信息。
假设我得到了 A.dll
其中有一个类型:
public class TypeInA : IInterfaceInB
{
...
}
由于没有给我 B,所以当我尝试调用时,我收到 FileNotFoundException
typeof(TypeInA).GetInterfaces()
因为它找不到B.dll
。
我不需要有关 IInterfaceInB
的详细信息,只需要其命名空间限定名称。有没有办法可以在不加载 B.dll
的情况下获得它?
更多上下文
我正在关注 MetadataLoadContext
docs加载 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);
最佳答案
由 Docs 提供你也发帖了
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.
由于您没有 B.dll
,我认为当您尝试访问该程序集中的任何信息时它抛出异常是正常的。
但是,当我在 A.dll 上使用 ildasm.exe 时,我可以轻松看到实现的接口(interface)的名称。所以至少应该可以得到名字。
有一个反编译库叫dnlib
,我偶尔使用。这是一个示例代码,您可以在没有 B.dll 的情况下读取 A.dll,并且还可以获取 Types 实现的接口(interface) 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();
}
关于c# - 获取引用类型的全名而不加载其程序集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64564983/