我有一个基于MEF的应用程序,可以使用插件进行自定义。这个应用程序有几个导入的部分,我想在用户决定删除该插件时在运行时删除其中一些(以便能够删除包含它们的.dll)。
CompositionBatch会做我需要的,但它需要ComposablePart
个实例作为RemovePart()
方法的输入参数,我只有普通的对象实现了ISomething接口,或者ComposablePartDefinition
实例AggregateCatalog
。所以我的问题是:
我会使用以下内容:
var parts = Container.Catalog.Parts
.Where(p => iDontNeed(p))
.Select(p => howDoIConvertComposablePartDefinition2ComposablePart(p));
var batch = new CompositionBatch();
parts.ToList().ForEach(part => batch.RemovePart(part));
谢谢
答案 0 :(得分:28)
如何获取属于某个.dll的ComposablePart对象列表?
要从特定装配体中移除零件,您只需通过调用AssemblyCatalog
即可删除AggregateCatalog.Catalogs.Remove
。您必须设计零件以允许Recomposition。
但是,这不会帮助您删除插件程序集。仍将加载程序集,并且在加载.NET程序集时无法更改或删除它。在不停止进程的情况下卸载程序集的唯一方法是卸载它加载的AppDomain
。但是如果你为插件引入一个单独的AppDomain
,那么你基本上必须通过远程处理等与这些插件进行通信。
停止应用程序,删除插件程序集并重新启动可能会更简单,更安全,更有效。
编辑:实际上,是一种删除插件dll文件的方法,无需停止进程或卸载整个appdomain:您可以启用shadow copying app-domain指示.NET在加载程序集之前制作副本。副本将保持加载状态,但至少可以删除或替换原始文件。
答案 1 :(得分:1)
MAF可以帮助你吗?我不是专家,但据我所知,使用MAF,插件仍保留在自己的进程中,可以在运行时卸载。我猜这不会给你提供理想的表现,因为你正在沟通交叉过程,但如果这不是一个重大问题,那么值得一看。