c# - MEF 对象生命周期

标签 c# mef

我有一个名为 Foo 的类:

using System;
using System.ComponentModel.Composition;

namespace MefTest
{
    [Export]
    internal class Foo 
    {
        public Foo()
        {
            Console.WriteLine("created foo");
        }

        ~Foo()
        {
            Console.WriteLine("Dead");
        }            
    }
}

它是这样创建的:

using System;
using System.ComponentModel.Composition.Hosting;
using System.Reflection;

namespace MefTest
{
    internal class Program
    {
        public static void Main()
        {
            var catalog = new AggregateCatalog();
            catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
            var container = new CompositionContainer(catalog);

            //EDIT: my problem, this returns Lazy<Foo> not Foo. Since I didn't call foo1.Value it was never actually created
            var foo1 = container.GetExport<Foo>(); 

            container.ReleaseExport(foo1);

            foo1 = null;

            GC.Collect();

            Console.Read();
        }
    }
}

但它似乎永远不会被处理掉。我尝试向它添加一个 IDisposible 接口(interface),但没有任何运气。

我如何确保正确清理它?我认为 ReleaseExport 会执行此操作,但从未调用过析构函数,因此它似乎从未被清理过。

我读过 http://mef.codeplex.com/wikipage?title=Parts%20Lifetime但我似乎看不出上面代码的问题。

最佳答案

您遇到的问题是 Foo 是共享导出。如果您希望它按原样处理,您可以在其上实现 IDisposable,然后在容器上调用 Dispose

另一种选择是将 Foo 标记为非共享,这将导致 ReleaseExport 对其调用 Dispose 方法。

[Export]
[PartCreationPolicy(CreationPolicy.NonShared)]
internal class Foo 
{
    public Foo()
    {
        Console.WriteLine("created foo");
    }

    ~Foo()
    {
        Console.WriteLine("Dead");
    }            
}

以上内容在您提供的链接的“范围内操作和资源的早期回收”部分中得到了很好的解释。请记住,如果您不提供 PartCreationPolicy 属性,则默认情况下会共享导出。

关于c# - MEF 对象生命周期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24442341/

相关文章:

c# - C# 中的参数标签

.net - 使用 MEF 注册实例

c# - 在我的构建输出中包含 Nuget 依赖项?

c# - 使用 MEF 加载多个插件实例

c# - 重置使用 MEF 加载的控件

c# - CS3016 - 在使用 Prism + MEF ExportModule 时我们如何解决这个问题?

c# - 在 C# 中拆分一个 6 位整数

c# - WPF MVVM : Update label depending on Textbox input (2nd Attempt)

c# - 如何用一个入口点对一个类进行单元测试?

c# - 默认情况下,plinq 会对 Dictionary<string, string> 使用范围分区还是 block 分区?以及如何强制对方?