如何检查MEF CompositionContainer是否未维护对非共享部分的引用?

时间:2013-10-15 14:14:13

标签: .net-4.5 mef

我在WPF应用程序中使用MEF。我使用MEF为我的视图创建视图模型对象,并且通过确保MEF CompositionContainer不保留对我的视图模型对象的引用来对避免内存泄漏感兴趣。

我知道this question及其答案。我谨慎地避免使用IDisposable,因为it doesn't "play nicely" with WPF

出于调试目的,我想编写一些声明某个对象尚未添加到CompositionContainer 的代码。这将确保我没有对视图模型类进行微妙的更改,这意味着它现在没有被正确释放。

以下是一些示例代码。我该如何实施AssertNotInContainer?请注意,在此示例中,正确处置exportLifetimeContext将是微不足道的。但是,在我更复杂的场景中,我希望能够依赖垃圾收集器而不是IDisposable,因为it is hard to determine the lifetime of WPF objects and their associated view models(由DataContext附加)。

namespace Demo
{
    using System;
    using System.ComponentModel.Composition;
    using System.ComponentModel.Composition.Hosting;
    using System.Diagnostics;

    class Program
    {
        static void Main(string[] args)
        {
            CompositionContainer container = new CompositionContainer(new ApplicationCatalog());

            MyOwnerClass demo = container.GetExport<MyOwnerClass>().Value;

            // Not going to dispose this...
            ExportLifetimeContext<MyLittleClass> exportLifetimeContext = demo.Factory.CreateExport();

            // Note that I don't dispose of exportLifetimeContext, since I know that if MyLittleClass obeys
            // the proper rules, it won't be added to the container anyway, and exportLifetimeContext.Dispose()
            // will do nothing anyway.
            MyLittleClass part = exportLifetimeContext.Value;

            // I wan't this to assert that part is not referenced in container.
            container.AssertNotInContainer(part);

            // This is a hacky way that I can confirm that MyLittleClass isn't referenced by the container.
            // This causes "Finalized." to be sent to the console.
            GC.Collect();

            Console.ReadLine();
        }
    }

    [Export]
    public class MyOwnerClass
    {
        [Import]
        public ExportFactory<MyLittleClass> Factory { get; set; }
    }

    [Export]
    [PartCreationPolicy(CreationPolicy.NonShared)]
    public class MyLittleClass
    {
        ~MyLittleClass()
        {
            Console.WriteLine("Finalized.");
        }
    }

    public static class MefHelper
    {
        [Conditional("DEBUG")]
        public static void AssertNotInContainer(this CompositionContainer container, object part)
        {
            // What code should I write here?
            bool isInContainer = false /* ??? */;

            if (isInContainer)
            {
                throw new InvalidOperationException(
                    "Part does not meet rules for not being added to CompositionContainer.  You have a leak!");
            }
        }
    }
}

MEF部件生命周期

MEF文档包含一个有用但过时的page explaining the lifetime of objects created by MEF。它说:

  

我们相信.Net垃圾收集器是最好的依靠正确清理。但是,我们还需要提供具有确定性行为的容器。因此,除非满足下列条件之一,否则容器将不会保留对其创建的零件的引用:

     
      
  • 该部件标记为共享
  •   
  • 该部分实现了IDisposable
  •   
  • 配置一个或多个导入以允许重新组合
  •   

0 个答案:

没有答案