使用MEF尝试加载插件时出错

时间:2015-03-03 16:08:12

标签: c# mef

控制台应用程序尝试使用来自特殊"插件"的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 添加了包含异常消息的屏幕 enter image description here

UPD3 CompositionContainer loading wrong directory through DirectoryCatalog中描述的相同问题,但未找到确切答案

2 个答案:

答案 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更喜欢这个版本。

最好从应用程序的二进制文件夹中删除旧版本的插件。我不知道为什么会这样,所以我不知道这是否适合你。