巧用Mono.Cecil反射加载类型和方法信息
??? 最近在做服務(wù)的細(xì)粒度治理,統(tǒng)一管理所有服務(wù)的方法、參數(shù)、返回值信息。方便后續(xù)的各個(gè)模塊之間的對(duì)接和協(xié)作。
?? 目前系統(tǒng)中所有的服務(wù),管理到接口契約粒度,即服務(wù)接口聲明和服務(wù)接口實(shí)現(xiàn)。要做服務(wù)的細(xì)粒度治理:
?? 首先需要將服務(wù)的各個(gè)方法信息全部反射出來(lái),然后再統(tǒng)一管理。
?? 大致的思路是這樣的:
???? 1. 下載所有最新的服務(wù)包(dll文件集合)
???? 2. 獲取所有的服務(wù)定義信息
???? 3. 反射加載出每個(gè)服務(wù)詳細(xì)的方法信息(方法名、參數(shù)、返回值等)
一、下載所有最新的服務(wù)包
??? 系統(tǒng)中幾百個(gè)服務(wù),幾十個(gè)服務(wù)組,每個(gè)服務(wù)都對(duì)應(yīng)一個(gè)服務(wù)包(dll文件集合),通過(guò)FTP將所有最新的服務(wù)包下載到本地,釋放出來(lái)
每個(gè)服務(wù)包一個(gè)文件夾
二、獲取所有的服務(wù)定義信息
?? 這個(gè)也很簡(jiǎn)單,從主數(shù)據(jù)庫(kù)中獲取最新的服務(wù)定義信息即可,放到本地內(nèi)存的一個(gè)集合中
三、反射加載出每個(gè)服務(wù)詳細(xì)的方法信息(方法名、參數(shù)、返回值等)
???循環(huán)遍歷每個(gè)服務(wù),Reflect每個(gè)接口信息,那么問(wèn)題來(lái)了?
? 很多服務(wù)之間是有依賴(lài)的,所以有服務(wù)組的概念,反射加載時(shí),必須指定:
AppDomain.CurrentDomain.AppendPrivatePath(servicePath);然后,反射加載各個(gè)接口和接口實(shí)現(xiàn)
1 Assembly asm = Assembly.Load(metadata.Invoke.UserDefineAssemble); 2 Type type = asm.GetType(metadata.Invoke.UserDefineClass, true, true);這樣做,通過(guò)發(fā)現(xiàn)Assembly加載不起來(lái),因?yàn)榉瓷浼虞d時(shí),很多依賴(lài)的dll找不到,或者不是最新版本(服務(wù)有多版本設(shè)計(jì))。
具體反射的dll加載順序,請(qǐng)大家參考MSDN:
https://docs.microsoft.com/en-us/dotnet/framework/deployment/how-the-runtime-locates-assemblies
如何解決這個(gè)問(wèn)題?其實(shí)很簡(jiǎn)單的一個(gè)需要,解析Dll中的 Method Table.
此時(shí),想到了ILSpy,Reflector,這些組件實(shí)現(xiàn)了Dll的反射加載,找找看看相關(guān)的SDK。
找著找著發(fā)現(xiàn)了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引用。
關(guān)鍵的幾個(gè)dll:
using Mono.Cecil;同時(shí),為了方便加載dll和處理服務(wù)組的dll,將所有服務(wù)包的dll遞歸放到一個(gè)文件夾中,同名Dll以最新修改時(shí)間為準(zhǔn)。
上述文件準(zhǔn)備工作就緒后,可以編碼了:
所有的服務(wù)的方法、參數(shù)、返回值信息全部搞定。
周?chē)?guó)慶
2017/9/29
?
轉(zhuǎn)載于:https://www.cnblogs.com/tianqing/p/7610560.html
總結(jié)
以上是生活随笔為你收集整理的巧用Mono.Cecil反射加载类型和方法信息的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: CentOS系统如何搭建离线yum源
- 下一篇: Docker部署网站之后映射域名