AppDomain加載與釋放dll

原文:AppDomain加載與釋放dll

幾年前寫過同名隨筆,但今天應不大適用了。但還有幾個朋友留言關注,我重新發布相關代碼。

首先我們的目的就是運行期間更新dll,並應用dll。這個過程需要應用 AppDomain來解決,辦法就是創建新的AppDomain加載dll,並在dll更新後創建新的AppDomain來加載新的dll。

好了,我們有兩個目錄需要完成。

第一個目標:運行時能更新dll。

1.創建AppDomain時設置ShadowCopyFiles

AppDomainSetup _setup = new AppDomainSetup();
_setup.ShadowCopyFiles
= "true";
_setup.LoaderOptimization
= LoaderOptimization.SingleDomain;
AppDomain _curDomain
= AppDomain.CreateDomain("TestDomain", null, _setup);

 2.當我們的主程序需要引用動態加載dll中的某個對象的實例時,該實例必須創建爲代理類。代理類的意思是類需要繼承自MarshalByRefObject。此外一般會使用另一個公共類庫定義基類或接口來使用這個代理類。好了,先看怎麼樣在前面創建的程序域中創建代理類的實例

複製代碼
System.Runtime.Remoting.ObjectHandle objHandle = pJobDomain.CreateInstanceFrom(strDllFilePath, strClassName);
object objBuild = objHandle.Unwrap();

if (objBuild == null)
throw new Exception("buildWorker -- 創建對象失敗");
else
ido
= (IDo)objBuild;//IDo是一個接口
複製代碼

 好了,如果strDllFilePath=“ClassLibrary.dll”,那麼運行目錄的ClassLibrary.dll文件被加載後,我們還是可以隨便更新他的。但更新後,程序域不重新創建的話,使用上面的方法再次創建代理實例,我們的程序依然看不到新的dll的運行效果的,因爲我們加載時設置了ShadowCopyFiles="true"。當然你可能會說設置爲"false"行不行呢?你可以試試,但我要說的是,如果這樣的話,我們第一個目標都完成不了。

第二個目標:應用新的dll。

其實很簡單,UnLoad後再創建一次,使用新的AppDomain創建代理類 ,程序就能看到新dll的效果。好,我定義了一個方法保證每運行一次都會創建一個新的程序域

複製代碼
AppDomain _curDomain;
private void load()
{
if (_curDomain != null)//已創建了程序域
{
AppDomain.Unload(_curDomain);
//先關閉再打開。
_curDomain = null;
}
AppDomainSetup _setup
= new AppDomainSetup();
_setup.ShadowCopyFiles
= "true";
_setup.LoaderOptimization
= LoaderOptimization.SingleDomain;
_curDomain
= AppDomain.CreateDomain("TestDomain", null, _setup);
}
複製代碼

 提供一個kevin-y的測試的源代碼 給大家下載

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章