2009-01-19 83 views
5

問題陳述:實現一個允許覆蓋相關程序集的插件系統(避免文件鎖定)。在.Net中,特定程序集可能不會被卸載,只有整個AppDomain可能被卸載。如何在不使用AppDomains的情況下實現.net插件?

我發佈這個,因爲當我試圖解決問題時,每個解決方案都提到使用多個AppDomains。即使在項目開始時構建,多個AppDomain也很難正確實施。

另外,AppDomain對我無效,因爲我需要跨域傳輸Type作爲Speech Server worfklow的InvokeWorkflow活動的設置。不幸的是,跨域發送類型會導致程序集被注入本地AppDomain。

此外,這與IIS有關。 IIS具有Shadow Copy設置,允許執行的程序集在加載到內存時被覆蓋。問題是(至少在XP下,沒有在生產2003服務器上測試),當你以編程方式加載程序集時,陰影副本不起作用(因爲你正在加載DLL而不是IIS)。

回答

8
  1. 檢查程序集是否已經加載(以避免由於一次又一次加載相同程序集而導致內存泄漏)。
  2. 如果未加載,請將程序集讀入字節數組。這將防止鎖定文件。
  3. 供應字節數組作爲arguement到Assembly.Load

以下代碼假定你知道一個組件的全名。

Assembly assembly = null; 

foreach(Assembly loadedAssembly in AppDomain.CurrentDomain.GetAssemblies()) 
    if (loadedAssembly.FullName == "foobar, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null") 
     assembly = loadedAssembly; 

if(assembly == null) 
{ 
    byte[] studybin = System.IO.File.ReadAllBytes(@"C:\pathToAssembly\foobar.dll"); 
    assembly = Assembly.Load(studybin);     
} 

需要注意的是,如果你想在目錄中查找特定的組件,你可以運行「System.Reflection.AssemblyName.GetAssemblyName(路徑);」查看FullName是否符合您的要求。 'GetAssemblyName(path)'不會將程序集註入到當前的AppDomain中。

另請注意,此解決方案不適用於只能很少重新啓動且應用程序更改頻率較高的應用程序。每次加載程序集時,應用程序的內存佔用量都會增加。沒有辦法卸載程序集,因此縮小內存使用率的唯一選擇是重新啓動應用程序。但是,這種限制通常比使用多個應用程序域的大性能,內存和代碼複雜性開銷更可取。如果您想使用Type s,這個限制也是不可避免的。

+0

我想這意味着你仍然必須重新啓動使用新的插件一旦被替換磁盤上的應用程序?我曾經有過這樣的印象:即使你重新加載了組件,一旦類型被加載,它也不能被改變。 – 2009-01-20 01:49:04

2

如果你想分離你的加載項,你必須......

  1. 創建擴展 MarshallByRefObject將 與加載項交互型(讓我們稱之爲 它FOOMASTER)
  2. 創建一個新的appdomain(讓我們叫它 addinLand)
  3. 請致電 addinLand。CreateInstanceAndUnwrap到 在 addinLand創建FOOMASTER的實例,並獲得在 當前應用程序域
  4. 告訴FOOMASTER代理加載您的加載項

現在您的加載項加載在addinLand,你可以與他們互動您的主要AppDomain通過您的FOOMASTER代理。當你的插件崩潰時,他們不會取消你的應用程序。

它是一個有趣的,有點混亂的過程。我原本以爲這個想法是加載你的插件,然後將它們作爲透明代理放到當前的應用程序域中,但最好的設計是將插件作爲簡單的對象與更復雜的類型交互(FOOMASTER) MarshallByRefObject,加載到addinLand應用程序域中,以及與其交互的透明代理。

CLR Via C#的第21章和第22章對理解過程非常有幫助。

2

如果您對使用插件架構構建系統的嚴肅方法感興趣,您可能需要查看現在屬於.NET Framework的MAF(託管加載項框架),即系統。 AddIn命名空間。

它將幫助您管理插件隔離和版本控制,甚至與合同的向後兼容性。

儘管這裏有一些學習曲線,所以這可能不是你正在尋找的東西。

http://msdn.microsoft.com/en-us/library/bb384200.aspx

相關問題