简体   繁体   English

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

[英]Error when try load plugin using MEF

Console application tries to load plugins using MEF from special "plugins" folder. 控制台应用程序尝试使用MEF从特殊的“插件”文件夹中加载插件。 On the other hand, binary folder of application contains "legacy" version of plugin "PluginAdd.dll". 另一方面,应用程序的二进制文件夹包含插件“ PluginAdd.dll”的“旧版”版本。 Console application fails with error: 控制台应用程序失败,并出现以下错误:

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
()

How can I solve the issue and request from MEF load plugin only from dedicated folder (and not from binary folder)? 如何仅从专用文件夹(而不是二进制文件夹)解决MEF加载插件的问题和请求?

Sample loaded to git (project MEF-loading-issue ): https://github.com/constructor-igor/TechSugar/trunk/MEF/MEF 样本加载到git(项目MEF-loading-issue ): https : //github.com/constructor-igor/TechSugar/trunk/MEF/MEF

Plugins loaded by next code: 下一个代码加载的插件:

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);
    }
}

Config file of application contains path to plugin folder: 应用程序的配置文件包含插件文件夹的路径:

<probing privatePath="..\..\..\@PluginBinaries"/>

UPD1 added full exception stack trace 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 added screen with exception message UPD2添加了带有异常消息的屏幕 在此处输入图片说明

UPD3 same issue described in CompositionContainer loading wrong directory through DirectoryCatalog , but not found exact answer UPD3CompositionContainer中描述的相同问题( 通过DirectoryCatalog加载错误的目录) ,但未找到确切答案

Found a workaround : instead of 找到了解决方法 :而不是

var pluginAssemblyCatalog = new AssemblyCatalog(@"..\..\..\@PluginBinaries\PluginAdd.dll");

can be used 可以使用

var pluginAssemblyCatalog = new AssemblyCatalog(Assembly.LoadFrom(@"..\..\..\@PluginBinaries\PluginAdd.dll"));

In the case, MEF loads plugin from dedicated file and doesn't load from "binary" folder. 在这种情况下,MEF从专用文件加载插件,而不从“二进制”文件夹加载。

The Load context is generally preferable to the LoadFrom context. 通常,Load上下文优于LoadFrom上下文。 So when MEF goes to load an assembly from a file, it will first get the assembly name, and try doing an Assembly.Load on it to load it in the Load context. 因此,当MEF从文件中加载程序集时,它将首先获取程序集名称,然后尝试对其执行Assembly.Load,以将其加载到Load上下文中。 Only if this fails will it load the assembly in the LoadFrom context. 仅当失败时,它才会在LoadFrom上下文中加载程序集。

So the reason the legacy version of the plugin is being loaded is because that's the version that's available in the Load context, which MEF prefers. 因此,加载旧版插件的原因是因为这是MEF首选的Load上下文中可用的版本。

It might be better to simply remove the legacy version of the plugin from your app's binary folder. 最好从应用程序的二进制文件夹中删除旧版本的插件。 I don't know why it's there so I don't know if that's an option for you. 我不知道为什么会在那里,所以我不知道这是否适合您。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM