2014-09-10 13 views
1

目前,我正在開發一個.NET愛好項目,該項目涉及與彼此組合的對象的複雜系統。但是,我遇到了一個小問題,我無法在.NET中找到支持在運行時替換代碼的機制,並且能夠處理先前加載的舊代碼。這意味着動態地替換模塊/對象,並且幾乎立即向用戶顯示更改,例如,當他重新啓動一個過程時,而不是整個程序。.NET中的模塊化系統可以在運行時進行更改

我已經考慮過爲每個會話單獨設置AppDomain並將必要的程序集加載到其中的可能性,但這看起來有點太昂貴。我還應該提到,每個會話都從一個常見的程序集基礎中受益,例如,連接到數據庫,這意味着將這些類加載到每個會話中。來自單獨的AppDomain來回編組數據還表示額外開銷(可以在數據通過網絡發送到客戶端應用程序時使用,代碼爲管理會話的主要AppDomain中包含的代碼)。

是否有一個框架或方法來取代/卸載特定部分的代碼?它如何在現實世界的應用程序中完成?有沒有解決方法?或者我選擇了一套錯誤的工具?

回答

3

您需要某種具有良好定義的接口的插件系統。然後在運行時二進制文件(您的插件* .dll)中加載並從中創建對象,然後在其上執行方法。 當您創建一個系統時,您的插件中的對象必須通過您的IPluginManager創建,您在運行時替換代碼沒有問題。:)

或者

你有這樣的事情有哪些,將根據需要編譯(在內存中)*的.cs文件的文件夾,並創建你想從他們使用,並呼籲他們的方法的對象。 這與上面的基本相同,沒有在運行時編譯。

從那裏你可以做出進一步的改進。

編輯: 像你寫的唯一的問題,而不使用AppDomain是一旦加載的程序集不能被卸載。但這不是一個真正的問題。

0

你可以看看MEF。它代表:託管擴展框架
這是另一篇關於它的文章MEF on codeproject

它用於在運行時編寫它們來加載dll。這是通常用於plugins或其他任何你放入文件夾並期望它運行的東西。

下面是一些教程的鏈接,以及:Where can I learn about MEF?

+0

我認爲'MEF'是一個選項,但我必須再次自己做'AppDomain'管理。 – ax1mx2 2014-09-10 14:18:00

1

我不認爲你需要單獨的AppDomain:您可以動態地在當前的AppDomain中加載程序集。並且每個程序集可能應該實現一些定義的接口(取決於您的使用情況)。例如,您可以使用FileSystemWatcher類來根據需要加載/卸載程序集。

http://msdn.microsoft.com/en-us/library/25y1ya39(v=vs.110).aspx

+2

儘管如此,您無法從AppDomain卸載程序集;這就是爲什麼需要單獨的AppDomain,如果你想卸載任何東西(在這一點你卸載整個AppDomain)。 – 2014-09-10 12:08:08

+0

你說得對。有必要卸載整個AppDomain以「卸載」一個程序集。 – DvS 2014-09-10 13:49:39

0

是的,你說得對,這是不可能簡單地卸載的組件(只應用程序域)。但我認爲ASP.Net vNext的其中一項功能是隻具有內存中程序集的功能,並且只需更改驅動器上的源代碼即可自動編譯和加載。因此,必須存在一個機制來卸載以前的版本。

我認爲他們是通過簡單地創建一個AppDomain來重新加載所有程序集以避免任何跨域通信。但是我不知道,也許如果你想深入瞭解他們如何在ASP.NET中做這些事情的機制,你可能會找到一個好的解決方案。有關vNext熱門話題的更多信息,您也可以在Scotts Blog找到。

0

嗯,我發現了2個適用於我的解決方案,我想分享一下。第一個是使用CollectibleAssembly並定義類型。這當然有點棘手,並且對這種類型的動態裝配施加了許多限制。 另一種選擇是使用腳本語言,如IronPythonIronRuby。新的Roslyn編譯器的一個很棒的功能還在於它還提供了腳本API,而以前在.NET框架中沒有。更重要的是,Roslyn腳本語言看起來非常像它們的成熟等價物(C#或VB)。我還發現了它的一個小小的example

相關問題