如何从MEF容器中释放共享实例
我试图释放共享实例或单例值。 有谁知道如何做到这一点? 我是否需要刷新目录? 我正在学习MEF所以请帮助。
上课的例子
[Export] public class Foo { public RandomProperty {get;set;} [ImportConstructor] public Foo() {} }
您可以使用以下内容创建它:
var fooSingleton = ServiceLocator.GetInstance(typeof(Foo));
一切都很好,但理想情况下我想做这样的事情
Container.Replace(oldFoo, newFoo);
所以当我再打电话的时候
var fooSingleton = ServiceLocator.GetInstance(typeof(Foo));
fooSingleton将拥有新值。
我认为答案可能依赖于实际清理目录然后刷新它 – 但这对于这么简单的事情来说似乎有些过分。
默认情况下,在MEF中,创建导出时,将共享。 在许多其他容器中,这被称为Singleton生活方式。 这意味着释放导出将不起作用,因为容器需要挂起到其他潜在消费者的导出。
你面前有2个选项:
- 假设您完成了容器,请处置容器。 例如,当应用程序关闭时,这是合适的。
- 将零件更改为临时对象,即每次从容器中请求零件时都会创建新零件。 要在MEF中执行此操作,请将PartCreationPolicy属性添加到Export,并指定它是非共享的。 这看起来像这样:
[PartCreationPolicy (CreationPolicy.NonShared)]
。 当调用container.ReleaseExport(myExport)
时,这将导致在您的部件上调用Dispose
方法,其中myExport
是一个导出(不是导出的值),它被保留以释放。
这是一个例子:
var catalog = new AggregateCatalog(// code elided); var container = new CompositionContainer(catalog); Lazy myExport = container.GetExport (); // later on... container.ReleaseExport(myExport)
这表明您需要在可以访问MEF容器的位置执行此操作,并且您必须保留对导出的引用。
但是要小心。 更改为临时对象而不是单例将影响容器的性能,因为reflection用于创建每个新对象。
由于您使用的是Shared
创建策略,因此容器将保留对创建的部件的引用。 释放零件的方法是从容器中获取包含的导出,然后释放。
var export = container.GetExport(); container.ReleaseExport(export);
您可能需要更新您的消费类型(您的Import
的位置),以支持重组。