Error when try load plugin using MEF
控制台应用程序尝试使用MEF从特殊的"插件"文件夹中加载插件。
另一方面,应用程序的二进制文件夹包含插件" PluginAdd.dll"的"旧版"版本。
控制台应用程序失败,并出现以下错误:
1 2 3 4 5 6 7 8 | Unhandled Exception: System.Reflection.ReflectionTypeLoadException: Unable to lo ad one or more of the requested types. Retrieve the LoaderExceptions property fo r more information. at System.Reflection.RuntimeModule.GetTypes(RuntimeModule module) at System.Reflection.RuntimeModule.GetTypes() at System.Reflection.Assembly.GetTypes() at System.ComponentModel.Composition.Hosting.AssemblyCatalog.get_InnerCatalog () |
如何仅从专用文件夹(而不是二进制文件夹)解决MEF加载插件的问题和请求?
样本加载到git(项目MEF-loading-issue):https://github.com/constructor-igor/TechSugar/trunk/MEF/MEF
下一个代码加载的插件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | public class Client { [ImportMany] public Lazy<ICommandPlugin, IDictionary<string, object>>[] CommandPlugins { get; set; } public void LoadPlugins() { var aggregateCatalog = new AggregateCatalog(); var pluginAssemblyCatalog = new AssemblyCatalog(@"..\..\..\@PluginBinaries\PluginAdd.dll"); aggregateCatalog.Catalogs.Add(pluginAssemblyCatalog); var container = new CompositionContainer(aggregateCatalog); container.ComposeParts(this); } } |
应用程序的配置文件包含插件文件夹的路径:
1 | <probing privatePath="..\..\..\@PluginBinaries"/> |
UPD1添加了完整的异常堆栈跟踪
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | Unhandled Exception: System.Reflection.ReflectionTypeLoadException: Unable to lo ad one or more of the requested types. Retrieve the LoaderExceptions property fo r more information. at System.Reflection.RuntimeModule.GetTypes(RuntimeModule module) at System.Reflection.RuntimeModule.GetTypes() at System.Reflection.Assembly.GetTypes() at System.ComponentModel.Composition.Hosting.AssemblyCatalog.get_InnerCatalog () at System.ComponentModel.Composition.Hosting.AssemblyCatalog.GetExports(Impor tDefinition definition) at System.ComponentModel.Composition.Hosting.AggregateCatalog.GetExports(Impo rtDefinition definition) at System.ComponentModel.Composition.Hosting.CatalogExportProvider.InternalGe tExportsCore(ImportDefinition definition, AtomicComposition atomicComposition) at System.ComponentModel.Composition.Hosting.CatalogExportProvider.InnerCatal ogExportProvider.GetExportsCore(ImportDefinition definition, AtomicComposition a tomicComposition) at System.ComponentModel.Composition.Hosting.ExportProvider.TryGetExportsCore (ImportDefinition definition, AtomicComposition atomicComposition, IEnumerable`1 & exports) at System.ComponentModel.Composition.Hosting.CatalogExportProvider.GetExports Core(ImportDefinition definition, AtomicComposition atomicComposition) at System.ComponentModel.Composition.Hosting.ExportProvider.TryGetExportsCore (ImportDefinition definition, AtomicComposition atomicComposition, IEnumerable`1 & exports) at System.ComponentModel.Composition.Hosting.ExportProvider.GetExports(Import Definition definition, AtomicComposition atomicComposition) at System.ComponentModel.Composition.Hosting.AggregateExportProvider.GetExpor tsCore(ImportDefinition definition, AtomicComposition atomicComposition) at System.ComponentModel.Composition.Hosting.ExportProvider.TryGetExportsCore (ImportDefinition definition, AtomicComposition atomicComposition, IEnumerable`1 & exports) at System.ComponentModel.Composition.Hosting.CompositionContainer.GetExportsC ore(ImportDefinition definition, AtomicComposition atomicComposition) at System.ComponentModel.Composition.Hosting.ExportProvider.TryGetExportsCore (ImportDefinition definition, AtomicComposition atomicComposition, IEnumerable`1 & exports) at System.ComponentModel.Composition.Hosting.ExportProvider.GetExports(Import Definition definition, AtomicComposition atomicComposition) at System.ComponentModel.Composition.Hosting.ImportEngine.TryGetExports(Expor tProvider provider, ComposablePart part, ImportDefinition definition, AtomicComp osition atomicComposition) at System.ComponentModel.Composition.Hosting.ImportEngine.TrySatisfyImportSub set(PartManager partManager, IEnumerable`1 imports, AtomicComposition atomicComp osition) at System.ComponentModel.Composition.Hosting.ImportEngine.TrySatisfyImportsSt ateMachine(PartManager partManager, ComposablePart part) at System.ComponentModel.Composition.Hosting.ImportEngine.TrySatisfyImports(P artManager partManager, ComposablePart part, Boolean shouldTrackImports) at System.ComponentModel.Composition.Hosting.ImportEngine.SatisfyImports(Comp osablePart part) at System.ComponentModel.Composition.Hosting.ComposablePartExportProvider.<>c __DisplayClass2.<Compose>b__0() at System.ComponentModel.Composition.Hosting.CompositionServices.TryInvoke(Ac tion action) at System.ComponentModel.Composition.Hosting.ComposablePartExportProvider.Com pose(CompositionBatch batch) at System.ComponentModel.Composition.Hosting.CompositionContainer.Compose(Com positionBatch batch) at System.ComponentModel.Composition.AttributedModelServices.ComposeParts(Com positionContainer container, Object[] attributedParts) at MEF_loading_issue.Client.LoadPlugins() in d:\My\MyProjects\@TechSugar\Tech Sugar.Samples\trunk\MEF\MEF\MEF-loading-issue\Program.cs:line 40 at MEF_loading_issue.Program.Main() in d:\My\MyProjects\@TechSugar\TechSugar. Samples\trunk\MEF\MEF\MEF-loading-issue\Program.cs:line 19 |
UPD2添加了带有异常消息的屏幕
UPD3与CompositionContainer中描述的相同问题通过DirectoryCatalog加载了错误的目录,但未找到确切答案
通常,Load上下文优于LoadFrom上下文。 因此,当MEF从文件中加载程序集时,它将首先获取程序集名称,然后尝试对其执行Assembly.Load,以将其加载到Load上下文中。 仅当失败时,它才会在LoadFrom上下文中加载程序集。
因此,加载旧版插件的原因是因为这是MEF首选的Load上下文中可用的版本。
最好从应用程序的二进制文件夹中删除旧版本的插件。 我不知道为什么会在那里,所以我不知道这是否适合您。
找到了解决方法:
代替
1 |
可以使用
1 | var pluginAssemblyCatalog = new AssemblyCatalog(Assembly.LoadFrom(@"..\..\..\@PluginBinaries\PluginAdd.dll")); |
在这种情况下,MEF从专用文件加载插件,而不从"二进制"文件夹加载。