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

Már*_*ton 17 .net c# mef

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

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

  • 如何找到表示我想要删除的导入对象的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));
Run Code Online (Sandbox Code Playgroud)

谢谢

Wim*_*nen 29

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

要从特定装配中移除零件,您可以AssemblyCatalog通过调用将其删除AggregateCatalog.Catalogs.Remove.您必须设计零件才能进行重构.

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

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

编辑:实际上,有要删除的插件的dll文件,而不停止进程或卸载应用程序域整体的方式:您可以启用阴影复制的AppDomain中指示.NET加载在大会上进行复印.副本将保持加载状态,但至少可以删除或替换原始文件.

  • @Josh G:我看不出使用反射编写自己的插件系统将如何解决任何问题。所描述的卸载问题不仅限于 MEF,这就是 .NET 的工作方式。 (2认同)