DotNet開發(fā)之反射技術(shù)詳解—動態(tài)庫的加載
反射是一種強大的工具,它允許程序在運行時獲取關(guān)于類型、成員和程序集的信息,并動態(tài)地創(chuàng)建、調(diào)用和修改代碼。今天,我們將深入探討反射的其他用法,以幫助您更好地利用這一技術(shù)。
一、Assembly.Load(),Assembly.LoadFrom(),Assembly.LoadFile()的區(qū)別
1.Assembly.Load
- Assembly.Load(string assemblyString):通過程序集的完全限定名稱(包括版本號、公鑰令牌等)或者簡單名稱來加載程序集。例如:Assembly.Load("MyAssembly, Versinotallow=1.0.0.0, Culture=neutral, PublicKeyToken=null")或Assembly.Load("MyAssembly")。
- Assembly.Load(byte[] rawAssembly):從字節(jié)數(shù)組中加載程序集。這對于從網(wǎng)絡(luò)或其他非傳統(tǒng)來源加載程序集很有用。
示例用法:
// 根據(jù)程序集名稱加載程序集
Assembly assembly = Assembly.Load("MyAssembly");
// 從字節(jié)數(shù)組加載程序集
byte[] assemblyBytes = File.ReadAllBytes("MyAssembly.dll");
Assembly assembly = Assembly.Load(assemblyBytes);
2.Assembly.LoadFrom
- Assembly.LoadFrom(string assemblyFile):從指定路徑加載程序集文件。
- Assembly.LoadFrom(string assemblyFile, Evidence securityEvidence):基于安全證據(jù)加載程序集文件。
示例用法:
// 從文件路徑加載程序集
Assembly assembly = Assembly.LoadFrom("C:\\MyAssemblies\\MyAssembly.dll");
// 基于安全證據(jù)加載程序集
Evidence evidence = new Evidence();
Assembly assembly = Assembly.LoadFrom("C:\\MyAssemblies\\MyAssembly.dll", evidence);
3.Assembly.LoadFile
- Assembly.LoadFile(string path):從指定路徑加載程序集文件。與LoadFrom不同,它會創(chuàng)建一個新的加載上下文,程序集將在該上下文中加載并解析。
示例用法:
// 從文件路徑加載程序集
Assembly assembly = Assembly.LoadFile("C:\\MyAssemblies\\MyAssembly.dll");
二、加載程序集的異常情況
需要注意的是,在使用這些方法加載程序集時,你需要處理可能出現(xiàn)的異常情況。以下可能會拋出以下幾種異常:
1.FileNotFoundException:
- 當指定的程序集文件無法找到時,會拋出此異常。
- 可能的原因包括:文件路徑錯誤、文件不存在或不可訪問等。
2.FileLoadException:
- 當無法加載指定的程序集文件時,會拋出此異常。
- 可能的原因包括:無效的程序集文件、程序集版本不兼容、程序集依賴項無法解析等。
3.BadImageFormatException:
- 當嘗試加載無效的程序集文件格式時,會拋出此異常。
- 可能的原因包括:程序集文件不是有效的CLR程序集、程序集文件被損壞或篡改等。
4.SecurityException:
- 當沒有足夠權(quán)限來加載程序集時,會拋出此異常。
- 可能的原因包括:缺少適當?shù)陌踩珯?quán)限、程序集未經(jīng)數(shù)字簽名等。
5.ReflectionTypeLoadException:
- 當加載程序集時出現(xiàn)類型加載異常時,會拋出此異常。
- 可能的原因包括:程序集中某個類型的依賴項無法解析、類型初始化失敗等。
6.UnauthorizedAccessException:
- 當沒有足夠的權(quán)限訪問程序集文件時,會拋出此異常。
- 可能的原因包括:訪問權(quán)限限制、文件被占用或鎖定等。
這些異常通常會在使用Assembly.Load()方法加載程序集時的各種錯誤情況下拋出。為了確保程序的穩(wěn)定性和可靠性,建議在使用Assembly.Load()方法時使用適當?shù)漠惓L幚頇C制來捕獲和處理這些異常。此外,當使用這些方法加載程序集時,還要注意程序集的版本和依賴關(guān)系,確保加載的程序集符合預(yù)期,并且不會引發(fā)版本沖突或依賴項缺失的問題。
三、DLL加載規(guī)則
我相信很多使用反射技術(shù)或者不使用反射技術(shù),加載程序集的時候,都曾經(jīng)遇到過BadImageFormatException的問題。在加載DLL(動態(tài)鏈接庫)時,系統(tǒng)會按照一定的路徑規(guī)則進行搜索。以下是通常情況下的DLL加載路徑規(guī)則:
應(yīng)用程序目錄:系統(tǒng)首先會搜索執(zhí)行當前代碼的應(yīng)用程序目錄。這是最常見的搜索位置,通常會將DLL文件放置在應(yīng)用程序的根目錄或相關(guān)子目錄中。
系統(tǒng)目錄:如果在應(yīng)用程序目錄中未找到DLL文件,則系統(tǒng)會搜索系統(tǒng)目錄。系統(tǒng)目錄通常是指 %SystemRoot%\System32(在大多數(shù)情況下為 C:\Windows\System32)。請注意,32位應(yīng)用程序在64位操作系統(tǒng)上可能會搜索 %SystemRoot%\SysWOW64 目錄。
Windows目錄:如果在系統(tǒng)目錄中未找到DLL文件,則系統(tǒng)會搜索Windows目錄。Windows目錄通常是指 %SystemRoot%\(在大多數(shù)情況下為 C:\Windows)。
當前工作目錄:如果在以上路徑中未找到DLL文件,則系統(tǒng)會搜索當前工作目錄。當前工作目錄是指應(yīng)用程序正在運行的目錄。
環(huán)境變量指定的路徑:系統(tǒng)還會搜索在系統(tǒng)環(huán)境變量 PATH 中指定的路徑。PATH 變量包含一系列目錄路徑,用于指示系統(tǒng)在其中搜索可執(zhí)行文件和DLL文件。
請注意,搜索DLL的順序是按照上述規(guī)則從前往后進行的,一旦找到匹配的DLL文件,搜索過程就會停止。此外,還可以使用以下方法來影響DLL的加載路徑:
- 使用絕對路徑:指定DLL的完整路徑,確保系統(tǒng)可以直接訪問該路徑下的DLL文件。
- 使用相對路徑:指定相對于應(yīng)用程序或當前工作目錄的相對路徑。在這種情況下,需要確保指定的相對路徑是正確的。