插件的“動態替換”
設想這樣一種場景:我們的服務系統提供一系列的功能服務,而以后會有更多新的功能服務增加進來,也可能出現功能服務需要被更改或移除的情況。對于這樣的服務系統,一個常見的基本的要求就是,在添加/移除/更新功能服務的時候不能停止的服務系統的運行。通常,將每一項服務封裝成一個插件Dll,可以非常容易地實現“插件熱插拔”(關于插件的基礎信息,參見這里),但是插件的“熱替換”(“動態替換”)卻成了一個問題。原因在于,當我們從服務系統中卸載插件Dll的時候,實際上服務系統仍然持有該Dll的底層引用,這時如果你嘗試刪除或覆蓋這個Dll,windows就會給出類似“該Dll正在被使用”的信息。
那么如何解決這個問題了?我覺得至少有兩種方案:
(1)使用AppDomain。在一個新的AppDomain中加載插件,然后通過卸載這個AppDomain就可以干凈地從服務系統中卸載該AppDomain中的插件Dll。這種方案的缺陷是需要管理眾多的AppDomain(因為你有眾多的功能服務),而且跨AppDomain的通信都是以Remoting的方式進行的,這將為我們的系統引入不少本不必要的麻煩。如果你有興趣也可以嘗試一下這種方案,而我更喜歡用第二種。
(2)在內存中復制插件Dll,然后加載內存中的Dll。這樣,硬盤上的Dll就可以隨意地被覆蓋或刪除了。以前我們是直接從硬盤加載插件Dll,就像這樣:
Assembly asm = Assembly.LoadFrom(addinFilePath) ; 現在,我們需要轉個彎:
//先將插件拷貝到內存緩沖
byte[] addinStream = null ;
if(FileHelper.ReadFileToBuff(addinFilePath ,out addinStream))
{
asm = Assembly.Load(addinStream) ; //加載內存中的Dll
}
這樣就解決了插件的“動態替換”的問題。
敬請了解:
ESFramework通信框架 OMCS網絡語音視頻框架 MFile語音視頻錄制組件 MCapture語音視頻采集組件 StriveEngine輕量級通信引擎 OAUS 自動升級系統

浙公網安備 33010602011771號