MEF:GetExportedValue和SatisfyImports之间的区别 [英] MEF: difference between GetExportedValue and SatisfyImports

查看:569
本文介绍了MEF:GetExportedValue和SatisfyImports之间的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正在使用MEF(.NET 4,目前不能使用4.5)在MVVM应用程序。 一切都很正常,直到我们需要动态创建的模型,例如可编辑的表行。 我不想碰到内存泄漏,我发现这篇文章 http://pglazkov.blogspot.ch/2011/04/mvvm-with-mef-viewmodelfactory.html ,我发现,我想明白了意外的行为。 这是添加到Shell.Items观察的集合中的项目:

We're using MEF (.NET 4, can't use 4.5 at the moment) in a MVVM application. Everything was fine until we needed to create models on the fly, for instance editable rows of a table. I didn't want to run into memory leaks, I found this article http://pglazkov.blogspot.ch/2011/04/mvvm-with-mef-viewmodelfactory.html and I discovered an unexpected behavior that I would like to understand. This is an Item added to the Shell.Items observable collection:

[PartCreationPolicy(CreationPolicy.NonShared)]
[Export]
public class Item : INotifyPropertyChanged, IDisposable
{
    [Import]
    private Lazy<Shell> shell;

    /// <summary>
    /// Initializes a new instance of the <see cref="Item"/> class.
    /// </summary>
    public Item()
    {
        this.Time = DateTime.Now;
    }

    ~Item()
    {
        this.Dispose(false);
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public Shell Shell
    {
        get
        {
            return this.shell.Value;
        }
    }

    public DateTime Time { get; private set; }

    public void Initialize()
    {
        this.Shell.ItemsCount++;
    }

    public void Dispose()
    {
        this.Dispose(true);
    }

    private void Dispose(bool disposing)
    {
        if (disposing)
        {
            this.Shell.ItemsCount--;
        }
    }

    [..]
}

这是工厂:

[PartCreationPolicy(CreationPolicy.Shared)]
[Export]
public class ChildContainerItemFactory : ItemFactory
{
    public override Item Create()
    {
        var container = ServiceLocator.Current.GetInstance<CompositionContainer>();
        using (var childContainer = CreateTemporaryDisposableContainer(container))
        {
            var item = childContainer.GetExportedValue<Item>();
            item.Initialize();
            return item;
        }
    }

    [..]
}

如果我用这个code,该项目是与子容器处置了一起。 如果我将其更改为:

If I use this code, the Item is disposed together with the child container. If I change it to:

public override Item Create()
    {
        var container = ServiceLocator.Current.GetInstance<CompositionContainer>();
        using (var childContainer = CreateTemporaryDisposableContainer(container))
        {
            var item = new Item();
            childContainer.SatisfyImportsOnce(item);
            item.Initialize();
            return item;
        }
    }

该项目已不再与容器处置。 我想知道,如果它是危险的使用GetExportedValue方法(我用的应用程序的其他部分的方法),并且是避免内存泄漏与视图模型用短寿命的最佳做法。

The item is not disposed anymore with the container. I would like to understand if it is dangerous to use the GetExportedValue method (I use that method in other parts of the application) and which is the best practice to avoid memory leaks with for view models with a short lifetime.

pciated任何帮助AP $ P $

Any help appreciated

推荐答案

据我所知(从实验和观察MEF的的来源$ C ​​$ C ):

As far as I know (from experimenting and looking at MEF's source code):

  1. 当容器被设置,所有导出目录的部分是一次性的也被布置。导出目录的部分是那些无论是装饰着ExportAttribute或指定为使用<一个出口href="http://msdn.microsoft.com/en-us/library/system.componentmodel.composition.registration.registrationbuilder.aspx"相对=nofollow> RegistrationBuilder (MEF2)。这些部件在容器创建和它们的寿命依赖于容器本身的寿命。
  2. 在另一方面,对象手动创建,由使用或者<一href="http://msdn.microsoft.com/en-us/library/system.componentmodel.composition.attributedmodelservices.satisfyimportsonce.aspx"相对=nofollow> CompositionContainer.SatisfyImportsOnce 或<一href="http://msdn.microsoft.com/en-us/library/system.componentmodel.composition.attributedmodelservices.composeparts.aspx"相对=nofollow> 的将不被设置CompositionContainer.ComposeParts。它们的寿命是不依赖于容器的寿命。
  1. When a container is disposed, all exported catalog parts that are disposable are also disposed. The exported catalog parts are the ones either decorated with the ExportAttribute or specified as exports using the RegistrationBuilder (MEF2). These parts are created by the container and their lifetime is dependent on the lifetime of the container itself.
  2. On the other hand, objects manually created and composed using either CompositionContainer.SatisfyImportsOnce or CompositionContainer.ComposeParts will not be disposed. Their lifetime is not dependent on the lifetime of the container.

现在GetExportedValue和SatisfyImports之间的差异是不一样的。 GetExportedValue返回全部出口中注册的容器部分。这包括由容器(在1中提到的出口目录部分),加上使用CompositionContainer.ComposeParts注册的​​部分创建的部分。 SatisfyImports将注入可用,但不会注册的对象,即使它的类被标记为导出类型(见1)出口任何进口。此外,SatisfyImports将禁用重构,但这是题外话

Now the difference between GetExportedValue and SatisfyImports is not the same. GetExportedValue returns all exported parts that are registered with the container. This includes the parts created by the container (the exported catalog parts mentioned in 1.) plus the parts registered using CompositionContainer.ComposeParts. SatisfyImports will inject any imports that are available but will not register the object as an export even if its class is marked as an exported type (see 1.). Additionally, SatisfyImports will disable recomposition, but this is off topic.

MEF对文件codePLEX提供有价值的信息零件寿命

MEF's documentation on CodePlex provides valuable info on Parts Lifetime.

这篇关于MEF:GetExportedValue和SatisfyImports之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆