2013-05-30 57 views
0

這可能看起來像是重複的,但它不是,它實際上是一個不同的問題!Assembly.Load(byte [])只加載一次

這種情況是這樣的:我有一個web應用程序,它遍歷所有動態加載到系統中的dll,以從中訪問方法並獲取數據。這些dll由用戶從網站添加。

僞代碼將是這樣的:

pulic void GetNews(){ 
    foreach(var i in ListOfDllPaths){ 
     Assembly dll = Assembly.Load(File.ReadAllBytes(i)); 
     SomeInterface if = CreateInstance(dll); //This methods does all the validation and such 
     if.DoMethod(); 
    } 
} 

現在的問題是,在每次調用GetNews()相同的dll文件都重新加載,加載有多次相同的dll。 我可以使用Assembly.LoadFrom或LoadFile來避免這個問題,但是之後我會鎖定我不想要的文件,因爲我希望能夠刪除它。

另一種選擇是使用新的應用程序域來加載它們,調用方法並卸載它們,但是接下來我還必須加載該域中的接口DLL,我真的不知道它的路徑在網絡應用程序中。更不用說將數據從一個應用程序域移動到另一個應用程序域是一件痛苦的事情,也很難完成。

三分之一的選擇是使用影子副本,但我不能刪除影子副本相同的結果。

選項?基本上我需要的是,加載DLL,使用它,卸載它,繼續前進。

+0

也許我在這裏誤解了這個問題,但如果你想確保你只是加載一個dll,你不能只保留一個你已經加載的文件名列表,並且每次檢查列表以確保你只加載新的? – joshuahealy

+0

我編輯了你的標題。請參閱:「[應該在其標題中包含」標籤「](http://meta.stackexchange.com/questions/19190/)」,其中的共識是「不,他們不應該」。 –

+1

如果您需要使用單獨的應用程序域卸載它,那麼這是您唯一的選擇。 – Yaur

回答

3

如果你需要真正的卸載它,你沒有選擇,只能使用一個單獨的應用程序域(見How to unload an assembly from the primary AppDomain?例如)

如果你只需要加載每個組件一次,但不關心卸載舊的你需要管理跟蹤哪些程序集自己加載。任何簡單的方法都是在加載之前對每個文件進行哈希處理。類似於:

Dictonary<string,bool> loadedAssemblies = new Dictonary<string,bool>(); 

using(SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider()) 
{ 
    var hash = Convert.ToBase64String(sha1.ComputeHash(byteArray)); 
    if(loadedAssemblies.ContainsKey(hash)) continue; 
    loadedAssemblies[hash] = true; 
    Assembly dll = Assembly.Load(File.ReadAllBytes(i)); 
    SomeInterface if = CreateInstance(dll); //This methods does all the validation and such 
    if.DoMethod(); 
} 

如果您想要版本項目另一種方法是將一些元數據添加到您的界面。

+0

如果該DLL已經加載(我發現它在哈希)我怎麼會從它獲得程序集?我應該存儲程序集引用嗎? – user1777914