尝试使用 MEF 加载插件时出错
Error when try load plugin using MEF
控制台应用程序尝试使用来自特殊 "plugins" 文件夹的 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 加载问题):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 中描述的相同问题,但未找到确切答案
找到解决方法:
而不是
var pluginAssemblyCatalog = new AssemblyCatalog(@"..\..\..\@PluginBinaries\PluginAdd.dll");
可以使用
var pluginAssemblyCatalog = new AssemblyCatalog(Assembly.LoadFrom(@"..\..\..\@PluginBinaries\PluginAdd.dll"));
在这种情况下,MEF 从专用文件加载插件,而不是从 "binary" 文件夹加载。
Load 上下文通常优于 LoadFrom 上下文。因此,当 MEF 从文件加载程序集时,它将首先获取程序集名称,然后尝试对其执行 Assembly.Load 以将其加载到 Load 上下文中。仅当此操作失败时,它才会在 LoadFrom 上下文中加载程序集。
所以加载旧版插件的原因是因为这是 MEF 更喜欢的加载上下文中可用的版本。
最好从应用程序的二进制文件夹中删除插件的旧版本。我不知道它为什么在那里,所以我不知道这是否适合你。
控制台应用程序尝试使用来自特殊 "plugins" 文件夹的 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 加载问题):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 中描述的相同问题,但未找到确切答案
找到解决方法: 而不是
var pluginAssemblyCatalog = new AssemblyCatalog(@"..\..\..\@PluginBinaries\PluginAdd.dll");
可以使用
var pluginAssemblyCatalog = new AssemblyCatalog(Assembly.LoadFrom(@"..\..\..\@PluginBinaries\PluginAdd.dll"));
在这种情况下,MEF 从专用文件加载插件,而不是从 "binary" 文件夹加载。
Load 上下文通常优于 LoadFrom 上下文。因此,当 MEF 从文件加载程序集时,它将首先获取程序集名称,然后尝试对其执行 Assembly.Load 以将其加载到 Load 上下文中。仅当此操作失败时,它才会在 LoadFrom 上下文中加载程序集。
所以加载旧版插件的原因是因为这是 MEF 更喜欢的加载上下文中可用的版本。
最好从应用程序的二进制文件夹中删除插件的旧版本。我不知道它为什么在那里,所以我不知道这是否适合你。