2014-03-29 26 views
3

当我创建一个对象并将其添加到容器后,我完成了它,我如何确保它正确处理?MEF和对象处置

阅读http://msdn.microsoft.com/en-us/library/ee155691(v=vs.110).aspx

对于长期组合容器,由零件 与非共享的创建策略内存消耗可以成为一个问题。这些非共享部分可以创建多次,并且不会被 处理,直到容器本身被处置。为了解决这个问题, 容器提供了ReleaseExport方法。在非共享导出上调用此方法 会将该导出从组合 容器中移除并处理它。仅在删除的 导出中使用的零件(等等)也会被删除并处理。通过这种方式,在 的情况下,资源可以被回收而不需要处置容器本身的组成 。

因此,举例来说,如果我使用类似Caliburn.micro与MEF和我创建一个新的ViewModel,当ViewModel被关闭,如果我加入容器上的ReleaseExport调用这是否清理参考,所以它不再占用记忆? (这是正确办法做到这一点?)

也并呼吁ReleaseExport在未来创造型的另一个目的是阻止我,还是该目录仍然包含项目,我可以重新创建它时,我希望?

回答

4

MEF允许两种类型的出口 - 共享和非共享。

共享出口都像单身 - 每个消费者都共享同一个实例。这些共享实例由MEF直接管理。在MEF容器上调用Dispose()时,它会按照与导入相反的顺序自动释放这些对象。

非共享资源比较复杂。由于存在多个实例,因此MEF不保证正确的发布顺序。在这种情况下,您应遵循与调用Dispose()所用的相同的指导原则来确定何时释放导入的对象。

每个非共享的MEF导入对象应该有一个所有者负责其生命周期 - 通常是首先导入它的父对象。一旦父对象确保没有人使用这个导入的对象,它会调用它的ReleaseExport。典型模式是在所有者对象的Dispose()中释放导入的对象。

class OwnerClass : IDisposable 
{ 
    [Import(RequiredCreationPolicy=CreationPolicy.NonShared)] 
    private ConsumedClass myInstance; 

    [Import(RequiredCreationPolicy=CreationPolicy.Shared)] 
    private CompositionContainer container; 

    // Do stuff 

    public void Dispose() 
    { 
     container.ReleaseExport(myInstance); 
    { 
} 

调用ReleaseExport从容器中释放该特定实例。该定义仍然在目录中。所以你应该仍然可以创建更多的实例。这里有一个很好的讨论:

https://mef.codeplex.com/discussions/228535

ReleaseExport的工作是清理一个特定的出口,它的 依赖从容器中早期,这意味着 容器本身,这将清理处置之前和处置的所有对象由容器构造的 。现在调用ReleaseExport将做 不同的事情取决于具体的出口,例如对于一个 共享导出它实际上什么也不做,但对于非共享导出 它将释放它并且走它的依赖关系图发布它们,但是 它会停止并且对共享 导出的任何依赖项不做任何操作。