MVVM アプリケーションで MEF (.NET 4、現時点では 4.5 を使用できません) を使用しています。たとえばテーブルの編集可能な行など、その場でモデルを作成する必要があるまでは、すべて問題ありませんでした。私はメモリ リークに遭遇したくなかったので、この記事http://pglazkov.blogspot.ch/2011/04/mvvm-with-mef-viewmodelfactory.htmlを見つけ、理解したい予期しない動作を発見しました。 . これは、Shell.Items オブザーバブル コレクションに追加されたアイテムです。
[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;
}
}
[..]
}
このコードを使用すると、Item は子コンテナーと共に破棄されます。それを次のように変更すると:
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 メソッドを使用するのが危険かどうか (私はアプリケーションの他の部分でそのメソッドを使用しています)、および有効期間が短いビュー モデルでメモリ リークを回避するためのベスト プラクティスはどれかを理解したいと思います。
どんな助けでも大歓迎