巧用Mono.Cecil反射加载类型和方法信息
??? 最近在做服務的細粒度治理,統一管理所有服務的方法、參數、返回值信息。方便后續的各個模塊之間的對接和協作。
?? 目前系統中所有的服務,管理到接口契約粒度,即服務接口聲明和服務接口實現。要做服務的細粒度治理:
?? 首先需要將服務的各個方法信息全部反射出來,然后再統一管理。
?? 大致的思路是這樣的:
???? 1. 下載所有最新的服務包(dll文件集合)
???? 2. 獲取所有的服務定義信息
???? 3. 反射加載出每個服務詳細的方法信息(方法名、參數、返回值等)
一、下載所有最新的服務包
??? 系統中幾百個服務,幾十個服務組,每個服務都對應一個服務包(dll文件集合),通過FTP將所有最新的服務包下載到本地,釋放出來
每個服務包一個文件夾
二、獲取所有的服務定義信息
?? 這個也很簡單,從主數據庫中獲取最新的服務定義信息即可,放到本地內存的一個集合中
三、反射加載出每個服務詳細的方法信息(方法名、參數、返回值等)
???循環遍歷每個服務,Reflect每個接口信息,那么問題來了?
? 很多服務之間是有依賴的,所以有服務組的概念,反射加載時,必須指定:
AppDomain.CurrentDomain.AppendPrivatePath(servicePath);然后,反射加載各個接口和接口實現
1 Assembly asm = Assembly.Load(metadata.Invoke.UserDefineAssemble); 2 Type type = asm.GetType(metadata.Invoke.UserDefineClass, true, true);這樣做,通過發現Assembly加載不起來,因為反射加載時,很多依賴的dll找不到,或者不是最新版本(服務有多版本設計)。
具體反射的dll加載順序,請大家參考MSDN:
https://docs.microsoft.com/en-us/dotnet/framework/deployment/how-the-runtime-locates-assemblies
如何解決這個問題?其實很簡單的一個需要,解析Dll中的 Method Table.
此時,想到了ILSpy,Reflector,這些組件實現了Dll的反射加載,找找看看相關的SDK。
找著找著發現了Mono.Cecil.
http://www.mono-project.com/docs/tools+libraries/libraries/Mono.Cecil/
Cecil is a library written by Jb Evain to generate and inspect programs and libraries in the ECMA CIL format.
With Cecil, you can load existing managed assemblies, browse all the contained types, modify them on the fly and save back to the disk the modified assembly.
直接Nuget引用。
關鍵的幾個dll:
using Mono.Cecil;同時,為了方便加載dll和處理服務組的dll,將所有服務包的dll遞歸放到一個文件夾中,同名Dll以最新修改時間為準。
上述文件準備工作就緒后,可以編碼了:
所有的服務的方法、參數、返回值信息全部搞定。
周國慶
2017/9/29
?
轉載于:https://www.cnblogs.com/tianqing/p/7610560.html
總結
以上是生活随笔為你收集整理的巧用Mono.Cecil反射加载类型和方法信息的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CentOS系统如何搭建离线yum源
- 下一篇: Docker部署网站之后映射域名