解決反射時ReflectionTypeLoadException異常


在GIS開發程序中,為了增加擴展性,往往采用插件式開發模式,自然用到了反射技術。如果反射使用的dll控制不好,很容易引發反射異常,查找原因十分不方便,可以使用PrettyBin或Costura等組件實現對類庫的管理。

問題描述

使用主程序Main.exe反射調用A.dll文件時,出現"未處理 System.Reflection.ReflectionTypeLoadException Message="無法加載一個或多個請求的類型。有關更多信息,請檢索LoaderExceptions屬性。",代碼如下:

var assembly = Assembly.LoadFile(filePath);
var types= assembly.GetTypes(); //引發ReflectionTypeLoadException異常

進一步查看LoaderExceptions異常,發現是因為缺少B.dll或它的某一個依賴項。

未能加載文件或程序集"B, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"或它的某一個依賴項。系統找不到指定的文件。

A.dll確實引用了B.dll,但仔細核對和檢查了所有dll文件都在A.dll所在目錄,沒有發現缺失的情況。

這種錯誤一般只有兩種原因:一是dll文件不能被調用主程序找到二是dll文件能找到,但版本不對。實際上,B.dll和A.dll雖然是在相同目錄,但與Main.exe不同,使用Main.exe反射調用其他算子時,它只會在Main.exe所在目錄 去找B.dll,當然找不到,所以報錯。

解決方案

方法一: AssemblyResolve事件

一種解決方法是注冊當前域(AppDomain.CurrentDomain)的AssemblyResolve事件,即當反射調用A.dll文件時,它找不到B.dll,就會觸發此事件,在這個事件中手動找路徑。這種方法的缺點時,需要手動指定路徑,不方便修改。

方法二: privatePath配置

為了動態修改目錄,可直接在AppConfig配置中指定dll所在的目錄,如下:

<configuration>
…..
	<runtime>
		<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
			<probing privatePath="目錄1; 目錄2" />
		</assemblyBinding>
	</runtime>
</configuration>

當程序在exe所在的目錄找不到dll時,它會依次在目錄1、目錄2中找,如果還找不到就報錯!

當然也可以用代碼來實現,自動添加軟件目錄下所有文件夾作為privatePath的值。

參考連接

關於跨程序集的反射 - torome - 博客園 (cnblogs.com)

AppDomain.CurrentDomain.AssemblyResolve - mCat - 博客園 (cnblogs.com)

c# 用代碼來設置程序的PrivatePath_夏仲達的博客-CSDN博客_privatepath


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM