我在使用MEF和一个插件文件夹时遇到了问题。
我的主要应用程序支持通过MEF使用插件。主应用程序不引用包含.NET任务类型的程序集以进行多线程处理,但其中一个或多个插件会引用它们。
插件位于Plugins文件夹中,我正在使用DirectoryCatalog。
我一直收到由MEF抛出的ReflectionTypeLoadException。
无法加载一个或多个请求的类型。检索LoaderExceptions属性以获取更多信息。
LoaderExceptions属性包含FileNotFoundException。
“无法加载文件或程序集'System.Threading.Tasks,Version=1.5.11.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a'或其某个依赖项。系统找不到指定的文件。”:“System.Threading.Tasks,Version=1.5.11.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a”
该插件通过Microsoft NuGet包引用引用System.Threading.Tasks。
这是我的辅助方法:
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;
}
这是我正在使用的代码来调用MEF并加载插件。
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
}
}
尽管Microsoft.Threading.Tasks.dll
及其相关程序集文件存在于插件文件夹中,但主应用程序的二进制文件夹中没有,为什么MEF无法加载这些插件?是否有办法告诉MEF在Plugins文件夹中搜索程序集依赖项?
使用插件模型意味着我无法预测插件可能引用哪些程序集,因此我无法将它们包含在应用程序的主二进制文件夹中,这就是为什么我希望所有相关的插件和插件依赖项都在plugins文件夹中的原因。