How to release a shared instance from a MEF container

白昼怎懂夜的黑 提交于 2019-12-22 06:16:25

问题


I am trying to release a shared instance or singleton value. Does anyone know how to do this? Do I have to refresh the catalog? I'm learning MEF so please help.

Example of class

[Export]
public class Foo
{
  public RandomProperty {get;set;}

  [ImportConstructor]
  public Foo() {}
}

You can create it with something like this:

var fooSingleton = ServiceLocator.GetInstance(typeof(Foo));

All fine and good, but ideally I would like to do something like this

Container.Replace(oldFoo, newFoo);

So when I call it again

var fooSingleton = ServiceLocator.GetInstance(typeof(Foo));

fooSingleton will have the new value.

I think the answer probably relies in actually clearing out the catalog and then refreshing it - but this seem overkill for such a simple thing.


回答1:


By default in MEF, when you create an Export, is is shared. In many other containers, this is referred to as the Singleton lifestyle. This means that releasing the export will do nothing, since the container needs to hang on to the export for other potential consumers.

You really have 2 options in front of you:

  1. Dispose the container, assuming that you are done with it. This is appropriate when the application is shutting down for example.
  2. Change your parts to be transient objects, that is a new part is created each time you request one from the container. To do this in MEF, add a PartCreationPolicy attribute to the Export and specify it is to be non-shared. This would look like this: [PartCreationPolicy (CreationPolicy.NonShared)]. This will cause the Dispose method to be called on your parts when container.ReleaseExport(myExport) is called where myExport is an export (not an exported value) that is kept around to releasing purposes.

Here is an example:

var catalog = new AggregateCatalog(// code elided);
var container = new CompositionContainer(catalog);

Lazy<IMyExportInterface> myExport = container.GetExport<IMyExportInterface>();
// later on...
container.ReleaseExport(myExport)

This shows that you need to do this where you have access to the MEF container, and where you have kept a reference to the export.

Caution, however. Changing to transient objects instead of singletons will affect the performance of the container as reflection is used to create each new object.




回答2:


Because you are using a Shared creation policy, the container will keep a reference to the part created. What you can do to release the part is grab the containing export from the container, and release.

var export = container.GetExport<Foo>();
container.ReleaseExport(export);

You'll likely need to update your consuming type (where your Imports are), to support recomposition.



来源:https://stackoverflow.com/questions/5433444/how-to-release-a-shared-instance-from-a-mef-container

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!