[英]ReflectionTypeLoadException thrown when calling Assembly.GetTypes()
[英]Assembly.GetTypes() - ReflectionTypeLoadException
我們為我們的應用程序實現了一個插件框架,並使用Assembly.Loadfrom加載插件程序集。 然后我們使用GetTypes()並進一步檢查每個插件文件的類型以獲得支持的接口。
用戶提供了插件的路徑,我們循環瀏覽文件夾中的每個文件,看看它(插件)是否支持我們的插件界面。 如果是,我們創建一個實例,如果不是,我們移動到下一個文件。
我們從一個代碼庫(appA_1和appA_2)構建兩個版本的軟件。
當插件由與插件文件同時構建的應用程序加載時,加載插件很有效。 但是,如果我們構建appA_2並指向appA_1的插件文件夾,則在調用GetTypes()時會出現異常。
我們代碼的基本版本是;
var pluginAssembly = Assembly.LoadFrom(FileName);
foreach (var pluginType in pluginAssembly.GetTypes())
{
我們得到一個“ReflectionTypeLoadException”異常。
這是令人擔憂的,因為我們希望我們的應用程序能夠加載由任何人構建的任何插件的類型。 我們缺少什么?
編輯:在遍歷LoaderExceptions之后,我們發現有一個文件libPublic.dll會生成System.IO.FileNotFoundException異常。 奇怪的是,該文件駐留在應用程序目錄中,插件被引用到項目文件中。
編輯2:在異常日志中,我們發現以下“比較程序集名稱導致不匹配:修訂號”
一些東西:
確保插件目錄中沒有重復的程序集(即您已經從app目錄中加載到主應用程序中的程序集。)否則,當您加載插件時,它可能會加載同一程序集的附加副本。 這可以帶來有趣的例外,例如:
對象('MyObject'類型)不是'MyObject'類型。
如果在實例化類型時遇到異常,則可能需要處理AppDomain.AssemblyResolve
:
private void App_Startup(object sender, StartupEventArgs e) { // Since we'll be dynamically loading assemblies at runtime, // we need to add an appropriate resolution path // Otherwise weird things like failing to instantiate TypeConverters will happen AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve; } private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) { var domain = (AppDomain) sender; foreach (var assembly in domain.GetAssemblies()) { if (assembly.FullName == args.Name) { return assembly; } } return null; }
我意識到告訴CLR有點奇怪,為了解決一個程序集,找到我們用來解析的名字的程序集,但我看到沒有它的奇怪事情發生了。 例如,我可以從插件程序TypeDescriptor.GetConverter
實例化類型,但是如果我嘗試使用TypeDescriptor.GetConverter
,它將找不到類的TypeConverter
,即使它可以在類上看到Converter
屬性。
查看您的編輯,這可能不是導致您當前異常的原因,盡管您在使用插件時可能會遇到這些問題。
感謝這篇文章,我可以解決我在UITypeEditor
中獲得的ReflectionTypeLoadException
。 它是自定義類庫的設計器程序集(在設計時使用的winforms智能標記),可掃描某些類型。
/// <summary>
/// Get the types defined in the RootComponent.
/// </summary>
private List<Type> getAssemblyTypes(IServiceProvider provider)
{
var types = new List<Type>();
try
{
IDesignerHost host = (IDesignerHost)provider.GetService(typeof(IDesignerHost));
ITypeResolutionService resolution = (ITypeResolutionService)provider.GetService(typeof(ITypeResolutionService));
AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
{
foreach (var assembly in ((AppDomain)sender).GetAssemblies())
{
if (assembly.FullName == args.Name)
{
return assembly;
}
}
return null;
};
Type rootComponentType = resolution.GetType(host.RootComponentClassName, false);
types = rootComponentType.Assembly.GetTypes().ToList();
}
catch
{
}
return types;
}
您收到的程序集版本不匹配。 由於您的插件引用了此libPublic.dll
,因此您必須仔細對其進行版本控制,特別是不要碰撞其版本/構建/等。 每次編譯時的數字。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.