关于C#:尝试使用MEF加载插件时出错

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添加了带有异常消息的屏幕
enter image description here

UPD3与CompositionContainer中描述的相同问题通过DirectoryCatalog加载了错误的目录,但未找到确切答案


通常,Load上下文优于LoadFrom上下文。 因此,当MEF从文件中加载程序集时,它将首先获取程序集名称,然后尝试对其执行Assembly.Load,以将其加载到Load上下文中。 仅当失败时,它才会在LoadFrom上下文中加载程序集。

因此,加载旧版插件的原因是因为这是MEF首选的Load上下文中可用的版本。

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


找到了解决方法:
代替

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

可以使用

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

在这种情况下,MEF从专用文件加载插件,而不从"二进制"文件夹加载。