I have a problem with MEF and using the plugins folder.
I have a main application that supports plugins through MEF. The main application does not reference assemblies containing the .NET Task type for multithreading, but one or more plugins.
The plugins are in the plugins folder and I am using DirectoryCatalog.
I keep getting ReflectionTypeLoadException thrown by MEF on
Unable to load one or more of the requested types. Check out LoaderExceptions for more information.
The LoaderExceptions property contains FileNotFoundException
"Failed to load the 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 refers to System.Threading.Tasks through a link to the Microsoft NuGet package.
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 that I use to call MEF and load 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 can't MEF load plugins even if Microsoft.Threading.Tasks.dll and its related build files are present in the Plugins folder, but not in the main bin folder of the application? And is there a way to tell MEF about the search in the Plugins folder for build dependencies?
Having a plug-in model means that I cannot foresee which assemblies a plug-in can reference, therefore I cannot include them in the main bin folder for the application, so I want all the plug-ins and plug-in dependencies associated with them to be in the plug-ins folder.