2009-09-25 69 views
98

我正在查看msdn文檔,並且在加載程序集時,我仍然對使用LoadFileLoadFrom究竟有什麼區別有些困惑。有人可以提供一個例子或比喻來更好地描述它。 MSDN文檔讓我更困惑。此外,ReflectionOnlyLoadFromLoadFrom相同,只是它僅在反射模式下加載程序集。與.NET程序集LoadFile和LoadFrom之間的區別?

由於我的.NET的經驗是不是最大的,這裏有關於使用的LoadFile MSDN文檔一些問題:這是什麼由LoadFile檢查具有相同身份組件意味着

1),但位於不同路徑?什麼是身份(例子)?

2)它聲明LoadFile不會將文件加載到'LoadFrom Context'中,也不會使用加載路徑來解析依賴關係。這是什麼意思,有人可以提供一個例子嗎?

3)最後,它聲明LoadFile在這個有限的場景中很有用,因爲LoadFrom無法加載具有相同身份但路徑不同的程序集;它只會加載第一個這樣的程序集,這再次引起我同樣的問題,程序集標識是什麼?

+6

嚴肅地說,我也有時認爲,MS應該聘請更好的作家或其他東西,因爲句子並不總是易於理解...... – Tarik 2012-03-31 17:14:31

+7

另請參見[*非文件*](http://www.codinghorror.com/blog/2005/ 11/avoid-undocumentation.html) – 2013-04-26 14:33:30

+0

@ColonelPanic MS可以說所有事情都被記錄下來......但是有了zeroooo的幫助。 – Legends 2017-01-08 15:28:42

回答

80

這是否清除它?

// path1 and path2 point to different copies of the same assembly on disk: 

Assembly assembly1 = Assembly.LoadFrom(path1); 
Assembly assembly2 = Assembly.LoadFrom(path2); 

// These both point to the assembly from path1, so this is true 
Console.WriteLine(assembly1.CodeBase == assembly2.CodeBase); 

assembly1 = Assembly.LoadFile(path1); 
assembly2 = Assembly.LoadFile(path2); 

// These point to different assemblies now, so this is false 
Console.WriteLine(assembly1.CodeBase == assembly2.CodeBase); 

編輯:爲您解答您的問題修訂所提出的問題,你一定要讀Suzanne Cook on Assembly Identity

有很多規則來控制程序集的加載方式,其中一些規則與他們如何解決依賴關係有關 - 如果AssemblyA依賴於AssemblyB,.NET應該在哪裏找到AssemblyB?在全局程序集緩存中,找到AssemblyA的相同目錄還是其他地方?此外,如果它找到該裝配體的多個副本,應該如何選擇使用哪一個?

LoadFrom有一套規則,而LoadFile有另一套規則。很難想象使用LoadFile的許多理由,但是如果您需要在同一個程序集的不同副本上使用反射,它就在您的身邊。

+1

CodeBase與身份相同嗎? – Xaisoft 2009-09-25 15:20:49

+0

不,我只是在此處使用CodeBase作爲程序集的任意屬性來說明第二個Assembly實例指向'錯誤'文件(在第一個示例中)。我正在更新我的答案和更多細節。 – 2009-09-25 15:24:39

+0

它清除了一點,但是當使用LoadFrom時,path1和path2如何指向磁盤上相同程序集的不同副本,並且在使用LoadFile時,path1和path2指向不同的程序集。什麼是path1和path2會是什麼樣的例子?謝謝你的耐心。 – Xaisoft 2009-09-25 15:27:25

50

Suzanne Cook's blog

的LoadFile與LoadFrom

要小心 - 這些都是不一樣的 的事情。

LoadFrom()經過融合,並且可以在不同的路徑被重定向到另一個 組件但 同一身份如果一個已經 在LoadFrom上下文加載。

LoadFile()根本不通過Fusion進行綁定 - 加載器僅提前 ,並正好加載* 調用者請求的內容。它不使用 上下文或Load或LoadFrom 上下文。

所以,LoadFrom()通常給你你要求的 ,但不一定。 LoadFile()適用於那些真正想要的東西, 。 (*但是,在V2開始,政策將 被應用到LoadFrom()和 的LoadFile(),這樣的LoadFile()不會 一定是什麼是 要求。此外,在開始V2,如果 裝配與它的身份是在 GAC,GAC的副本將被用於 改用ReflectionOnlyLoadFrom() 加載正是你想要的。 - 但是, 注意,組件加載這樣 不能執行)

LoadFile()有一個catch。由於 不使用綁定上下文,因此其 依賴項不會自動在其目錄中找到 。如果它們不是在加載上下文中可用的 ,則 必須訂閱 AssemblyResolve事件才能將 綁定到它們。

請參閱here

另請參閱Choosing a Binding Context文章在同一個博客上。

+0

謝謝,我將檢查博客,我更新了有關msdn文檔的一些問題。 – Xaisoft 2009-09-25 15:19:46

+0

@ Xaisoft - Suzanne Cook的博客再次以組裝身份的答案來拯救。請參閱http://blogs.msdn.com/suzcook/archive/2003/07/21/57232.aspx。它基本上是一個「程序集顯示名稱」,如下所示:「System,Version = 1.0.3300.0,Culture = neutral,PublicKeyToken = b77a5c561934e089」因此包含程序集的實際名稱,其版本號以及其他標識信息(如公鑰等)。 – CraigTP 2009-09-25 15:28:32

+0

好奇,是Suzanne Cook的反思導師:) – Xaisoft 2009-09-25 15:29:58

5

一個差,我注意到的是:

Assembly.LoadFile - 在不同的應用程序域具有有限的用戶權限(diffrence principel)加載組件。像血管凝固/凝固等手術無法進行。

Assembly.LoadFrom - 在具有相同用戶權限(相同原則)的同一AppDomain中加載程序集。

2

注意:如果一個程序集使用8.3路徑加載,然後從非8.3路徑加載,它們將被視爲不同的程序集,即使它們是相同的物理DLL。

32

經過大量的頭部搔抓,我今天下午發現自己的差異。

我想在運行時加載一個DLL,並且DLL住在另一個目錄中。該DLL有自己的依賴關係(DLL),它們也存在於同一個目錄中。

LoadFile():加載了特定的DLL,但沒有加載依賴關係。因此,當第一次調用是從DLL內部向其他DLL中的一個調用時,它會拋出FileNotFoundException異常。

LoadFrom():加載了我指定的DLL以及所有位於該目錄中的依賴關係。

+3

這正是我的問題!當我創建一個在我剛剛用'.LoadFile'加載的程序集引用的程序集中定義的對象的新實例時,我正在獲取'FileNotFoundException'。把它改成'.LoadFrom'似乎解決了這個問題,但我不知道爲什麼!謝謝 – Connell 2013-06-25 11:57:55

+1

謝謝,我遇到了同樣的問題。 – 2016-11-25 04:32:07

0

在我的情況下,我只需刪除位於@C:\Windows\Microsoft.NET\Framework\[asp version]\Temporary ASP.NET Files的ASP應用程序緩存。它在網站首次運行時重建。一定要先停止IIS。

希望這可以幫助像我這樣的人。

-1

根據文檔:

的LoadFile(字符串):加載給定的文件路徑的組件文件的內容。

LoadFrom(String):根據文件名或路徑加載程序集。