如何在运行时删除MEF插件?

时间:2011-03-22 18:07:42

标签: c# .net mef

我有一个基于MEF的应用程序,可以使用插件进行自定义。这个应用程序有几个导入的部分,我想在用户决定删除该插件时在运行时删除其中一些(以便能够删除包含它们的.dll)。

CompositionBatch会做我需要的,但它需要ComposablePart个实例作为RemovePart()方法的输入参数,我只有普通的对象实现了ISomething接口,或者ComposablePartDefinition实例AggregateCatalog。所以我的问题是:

  • 如何找到ComposablePart 表示导入的实例 我想摆脱的对象?
  • 或 或者:我如何获得列表 属于的ComposablePart对象 到某个.dll?

我会使用以下内容:

var parts = Container.Catalog.Parts
           .Where(p => iDontNeed(p))
           .Select(p => howDoIConvertComposablePartDefinition2ComposablePart(p));
var batch = new CompositionBatch();
parts.ToList().ForEach(part => batch.RemovePart(part));

谢谢

2 个答案:

答案 0 :(得分:28)

  

如何获取属于某个.dll的ComposablePart对象列表?

要从特定装配体中移除零件,您只需通过调用AssemblyCatalog即可删除AggregateCatalog.Catalogs.Remove。您必须设计零件以允许Recomposition

但是,这不会帮助您删除插件程序集。仍将加载程序集,并且在加载.NET程序集时无法更改或删除它。在不停止进程的情况下卸载程序集的唯一方法是卸载它加载的AppDomain。但是如果你为插件引入一个单独的AppDomain,那么你基本上必须通过远程处理等与这些插件进行通信。

停止应用程序,删除插件程序集并重新启动可能会更简单,更安全,更有效。

编辑:实际上,一种删除插件dll文件的方法,无需停止进程或卸载整个appdomain:您可以启用shadow copying app-domain指示.NET在加载程序集之前制作副本。副本将保持加载状态,但至少可以删除或替换原始文件。

答案 1 :(得分:1)

MAF可以帮助你吗?我不是专家,但据我所知,使用MAF,插件仍保留在自己的进程中,可以在运行时卸载。我猜这不会给你提供理想的表现,因为你正在沟通交叉过程,但如果这不是一个重大问题,那么值得一看。