System.IO.FileNotFoundException: 未能加載文件或程序集“SQLServerDAL”或它的某一個依賴項錯誤總結

關於這個錯誤,網上的版本很多,但是幾乎沒有幾個是能從根本上解決本問題的。沒有幾篇博客是從反射的方法上考慮而是直接推出解決辦法。但是其中有很多解決辦法是不對的。從而導致我花費了大量的時間去嘗試該錯誤的解決。最終我還是找到了一片良心文章,作者很是細心,文章寫的很仔細。幫助我解決反射問題的同時讓我明白了反射方法的實際運行機理。在此感謝此作者。下面是該作者文章鏈接,希望對大家有所幫助。
https://www.cnblogs.com/cheng2015/p/5415624.html
當我看完這篇文章之後我認爲我對反射已經沒有什麼好寫的了,但是爲了加強我的記憶,以及補充一些細微之處,我打算該文章摘抄一下。
首相我們需要導入System.Reflection命名空間
然後是我們的反射語句,注意反射的返回值一般是object類型的值所以我們一般會在反射前設置強轉類型。

1、反射其他程序集中的類,或者其他項目中的類

反射語句分爲兩部分:
第一部分加載程序集 Assembly assembly = Assembly.LoadFile(“程序集路徑,不能是相對路徑”); // 加載程序集(EXE 或 DLL)
第二部分創建類的實例
object obj = assembly.CreateInstance(“類的完全限定名(即包括命名空間)”); // 創建類的實例

2、獲得當前項目中的類(和當前項目引用的程序集中的類)

可以爲
Assembly assembly = Assembly.GetExecutingAssembly(); // 獲取當前程序集
object obj = assembly.CreateInstance(“類的完全限定名(即包括命名空間)”); // 創建類的實例,返回爲 object 類型,需要強制類型轉換

下面講解一下反射中常用的三個方法

關於.NET中的反射,常用的有三個方法:

Assembly.Load()
Assembly.LoadFrom()
Assembly.LoadFile()

下面說說這三個方法的區別和一些細節問題

1.Assembly.Load()

簡介:
load()中接一個string類型或者AssemblyName類型作爲參數買這個參數實際上是需要加載的程序集的強名稱(名稱,版本,語言,公鑰標記)如
在這裏插入圖片描述
對於弱名命名的程序集。則只會有程序集名稱,而不會有版本,語言和公鑰標記。如DAL

細節
CLR內部普遍使用了Load()方法來加載程序集,在Load()方法的內部,CLR首先會應用這個程序集的版本綁定重定向策略,接着在GAC中查找目標程序集。如果GAC中沒有找到,則會在應用程序目錄和子目錄中尋找(應用配置文件的codebase所指定的位置)。
如果希望加載弱命名程序集,Load()方法就不會去GAC中查找。
當Load()找到目標程序集時,就會加載它,並返回一個相應Assembly對象的引用。
當沒有找到程序集時,會拋出System.IO.FileNotFoundException異常。

LoadFrom方法中強名稱中公鑰的獲取
首先打開要獲取公鑰程序集的屬性,然後選中標籤選項,勾選爲程序集簽名,新建。輸入文件名,密碼。
在這裏插入圖片描述
然後點開程序集中的Assemblyinfo.cs文件
在這裏插入圖片描述
在改文件中加入以下語句
在這裏插入圖片描述
snk文件一般在程序集文件中,打開即可看到。
然後對程序進行加載
這樣你的目標程序集就會成爲一個有強名稱的程序集。
然後打開開發人員命令提示符在開始中搜索
輸入sn
然後輸入sn -T 後加程序集.dll文件的絕對路徑。該文件一般在程序集文件的bin文件——>debug文件中。
即可得到公鑰標記

2. Assembly.LoadFrom()

簡介
LoadFrom()方法可以從指定文件中加載程序集,通過查找程序集的AssemblyRef元數據表,得知所有引用和需要的程序集,然後在內部調用Load()方法進行加載。
細節
LoadFrom()首先會打開程序集文件,通過GetAssemblyName方法得到程序集名稱,然後關閉文件,最後將得到的AssemblyName對象傳入Load()方法中
隨後,Load()方法會再次打開這個文件進行加載。所以,LoadFrom()加載一個程序集時,會多次打開文件,造成了效率低下的現象(與Load相比)。
由於內部調用了Load(),所以LoadFrom()方法還是會應用版本綁定重定向策略,也會在GAC和各個指定位置中進行查找。
LoadFrom()會直接返回Load()的結果——一個Assembly對象的引用。
如果目標程序集已經加載過,LoadFrom()不會重新進行加載。
LoadFrom支持從一個URL加載程序集(如"http://www.abc.com/test.dll"),這個程序集會被下載到用戶緩存文件夾中。
從URL加載程序集時,如果計算機未聯網,LoadFrom會拋出一個異常。如果IE被設置爲“脫機工作”,則不會拋出異常,轉而從緩存中尋找已下載的文件。

3. Assembly.LoadFile()

簡介
LoadFile()從一個指定文件中加載程序集,它和LoadFrom()的不同之處在於LoadFile()不會加載目標程序集所引用和依賴的其他程序集。您需要自己控制並顯示加載所有依賴的程序集
細節
LoadFile()不會解析任何依賴
LoadFile()可以多次加載同一程序集
顯式加載依賴程序集的方法是,註冊AppDomain的AssemblyResolve事件

區別:

LoadFile 方法用來來加載和檢查具有相同標識但位於不同路徑中的程序集.但不會加載程序的依賴項。
LoadFrom 不能用於加載標識相同但路徑不同的程序集。
能用loadFrom的時候儘量使用load

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