[英]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.