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

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

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

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

我会用以下内容:

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

谢谢

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

要从特定程序集中删除部件,可以通过调用AggregateCatalog.Catalogs.Remove删除该AssemblyCatalog 。 您必须设计零件以允许重构 。

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

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

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

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