控制台应用程序尝试使用来自特殊"插件"的MEF加载插件。夹。 另一方面,应用程序的二进制文件夹包含" legacy"插件版本" PluginAdd.dll"。 控制台应用程序失败,错误:
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
下一代码加载的插件:
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);
}
}
应用程序的配置文件包含插件文件夹的路径:
<probing privatePath="..\..\..\@PluginBinaries"/>
UPD1 添加了完整的异常堆栈跟踪
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 loading wrong directory through DirectoryCatalog中描述的相同问题,但未找到确切答案
答案 0 :(得分:2)
找到解决方法: 而不是
var pluginAssemblyCatalog = new AssemblyCatalog(@"..\..\..\@PluginBinaries\PluginAdd.dll");
可以使用
var pluginAssemblyCatalog = new AssemblyCatalog(Assembly.LoadFrom(@"..\..\..\@PluginBinaries\PluginAdd.dll"));
在这种情况下,MEF从专用文件加载插件,并且不会从&#34;二进制加载#34;文件夹中。
答案 1 :(得分:2)
Load上下文通常比LoadFrom上下文更可取。因此,当MEF从文件加载程序集时,它将首先获取程序集名称,并尝试对其执行Assembly.Load以在Load上下文中加载它。只有在此失败时才会在LoadFrom上下文中加载程序集。
因此,加载插件的旧版本的原因是因为它是加载上下文中可用的版本,MEF更喜欢这个版本。
最好从应用程序的二进制文件夹中删除旧版本的插件。我不知道为什么会这样,所以我不知道这是否适合你。