MEF框架学习之旅(九)部件生命周期及组装通知
由于部件承载于组合容器中,因此其生命周期可能比普通对象更复杂。 部件可实现两个重要的生命周期相关接口:IDisposable 和 IPartImportsSatisfiedNotification。
需要在关闭时执行工作的部件和需要释放资源的部件应照常为 .NET Framework 对象实现 IDisposable。 但是,由于容器创建并维护对部件的引用,因此只有拥有部件的容器才应对其调用 Dispose 方法。 容器本身实现 IDisposable,并且作为 Dispose 中其清理的一部分,它将对拥有的所有部件调用 Dispose。 因此,当不再需要组合容器及其拥有的任何部件时,您应始终释放该组合容器。
对于生存期很长的组合容器,创建策略为“非共享”的部件的内存消耗可能会成为问题。 这些非共享部件可以多次创建,并且在容器本身被释放之前将不会得到释放。 为了应对这种情况,容器提供了 ReleaseExport 方法。 如果对非共享导出调用此方法,将会从组合容器中移除该导出并将其释放。 仅由移除的导出使用的部件以及树中更深层的诸如此类部件将也会被移除并得到释放。 通过这种方式,不必释放组合窗口本身即可回收资源。
IPartImportsSatisfiedNotification 包含一个名为 OnImportsSatisfied 的方法。 当组合已完成并且部件的导入可供使用时,组合窗口将对实现接口的任何部件调用此方法。 部件是组合引擎创建,用于满足其他部件的导入。 在设置好部件的导入之前,您无法执行任何依赖于部件构造函数中的导入值或对这些值进行操作的初始化,除非已通过使用 ImportingConstructor 特性将这些指定为必备。 此方法通常为首选方法,但在某些情况下,构造函数注入可能不可用。 在这些情况下,可以在 OnImportsSatisfied 中执行初始化,并且部件应实现IPartImportsSatisfiedNotification。
部件组装通知,就是当某个组件引用的部件都能满足导入,在返回已经组装完成的组件之前,先通知该组件。
在一些情形下当MEF为你的类实例完成导入过程时你的类被通知对你很重要。如果是这样,项目要实现[System.ComponentModel.Composition.IPartImportsSatisfiedNotification] 接口。这个接口只有一个单独的方法:OnImportsSatisfied,当所有导入可以被满足和已经满足时,它会被调用。
请看简单的示例:
代码段
class Program { private static CompositionContainer container; static void Main(string[] args) { var catalog = new AssemblyCatalog(typeof(Program).Assembly); container = new CompositionContainer(catalog); var studentManager = container.GetExportedValue<MyComponent>(); Console.ReadLine(); } } [Export] class MyComponent : IPartImportsSatisfiedNotification { public void OnImportsSatisfied() { Console.WriteLine("OK!~"); } }
由于【MyComponent】满足了组装条件,所以该通知一定能得到执行。
相关阅读: