I have a problem with MEF and using a plugins folder.
I have a main app that supports plugins via MEF. The main app does not reference the assemblies containing the .NET Task type for multithreading but one or more of the plugins do.
The plugins are located in a Plugins folder and I'm using a DirectoryCatalog.
I keep getting ReflectionTypeLoadException
being thrown by MEF on
Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.
The LoaderExceptions property contains a FileNotFoundException
"Could not load file or assembly 'System.Threading.Tasks, Version=1.5.11.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.":"System.Threading.Tasks, Version=1.5.11.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
The plugin is referencing System.Threading.Tasks
via a Microsoft NuGet package reference.
This is my helper method:
public static void Compose(IEnumerable<string> searchFolders, params object[] parts)
{
// setup composition container
var catalog = new AggregateCatalog();
// check if folders were specified
if (searchFolders != null)
{
// add search folders
foreach (var folder in searchFolders.Where(System.IO.Directory.Exists))
{
catalog.Catalogs.Add(new DirectoryCatalog(folder, "*.dll"));
}
}
catalog.Catalogs.Add(new AssemblyCatalog(typeof(Program).Assembly));
// compose and create plug ins
var composer = new CompositionContainer(catalog);
composer.ComposeParts(parts);
}
public class MEFComposer
{
[ImportMany(typeof(IRepository))]
public List<IRepository> Repositories;
[ImportMany(typeof(ILogging))]
public List<ILogging> LoggingRepositories;
[ImportMany(typeof(IPlugin))]
public List<IPlugin> Plugins;
}
This is the code I'm using to invoke MEF and load the plugins.
public void Compose()
{
// try to connect with MEF types
try
{
var parts = new MEFComposer();
MEFHelpers.Compose(new[] { Path.Combine(Application.StartupPath, "Plugins") }, parts);
RepositoryFactory.Instance.Repository = parts.Repositories.FirstOrDefault();
Logging.Repositories.AddRange(parts.LoggingRepositories);
foreach (var plugin in parts.Plugins)
{
this.applicationApi.Plugins.Add(plugin);
plugin.Connect(this.applicationApi);
}
}
catch
{
// ERR: handle error
}
}
Why is MEF not able to load the plugins even though the Microsoft.Threading.Tasks.dll
and related assembly files are present in the Plugins folder, but not the main application bin folder? And is there any way of telling MEF to search the Plugins folder for assembly dependencies?
Having a plugin model means I can't anticipate what assemblies a plugin may be referencing so I cannot include them in the main bin folder for the app, which is why I want all related plugins and plugins dependencies to be in the plugins folder.
bin
folder as one of the folders forDirectoryCatalog
. This does not necessary points to the problem but have you tried it? – Geniegenii