Console application tries to load plugins using MEF from special "plugins" folder. On the other hand, binary folder of application contains "legacy" version of plugin "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)?
Sample loaded to git (project 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
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
UPD3 same issue described in CompositionContainer loading wrong directory through DirectoryCatalog, but not found exact answer
The Load context is generally preferable to the LoadFrom context. 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. Only if this fails will it load the assembly in the LoadFrom context.
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.
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.