Мне нравится MVVM Light's Messenger и его гибкость, однако у меня возникают утечки памяти, когда я забываю явно отменить регистрацию получателей (в Silverlight 4).
Причина в объяснил здесь , но меня это устраивает, так как я считаю хорошей практикой явную отмену регистрации получателей в любом случае, а не полагаться на использование Messenger слабых ссылок. Проблема в том, что легче сказать, чем сделать.
ViewModels просты: вы обычно полностью контролируете их жизненный цикл и можете просто Cleanup ()
их, когда они больше не нужны.
Представления , с другой стороны, сложнее, поскольку они создаются и уничтожаются с помощью DataTemplates. Например, вы можете представить себе ItemsControl
с MyView
как DataTemplate, привязанный к ObservableCollection
. Элементы управления MyView
создаются / собираются механизмом привязки, и у вас нет хорошего способа вручную вызвать для них Cleanup ().
У меня есть решение, но я хотел бы знать, подходит ли оно узор или есть лучшие альтернативы. Идея состоит в том, чтобы отправить конкретное сообщение из ViewModel, чтобы сообщить связанным View (-ам), что нужно удалить:
public class MyViewModel : ViewModelBase
{
...
public override void Cleanup()
{
// unregisters its own messages, so that we risk no leak
Messenger.Default.Unregister<...>(this);
// sends a message telling that this ViewModel is being cleaned
Messenger.Default.Send(new ViewModelDisposingMessage(this));
base.Cleanup();
}
}
public class MyView : UserControl, ICleanup
{
public MyView()
{
// registers to messages it actually needs
Messenger.Default.Register<...>(this, DoSomething);
// registers to the ViewModelDisposing message
Messenger.Default.Register(this, m =>
{
if (m.SenderViewModel == this.DataContext)
this.Cleanup();
});
}
public void Cleanup()
{
Messenger.Default.Unregister<...>(this);
Messenger.Default.Unregister(this);
}
}
Итак, когда вы вызываете Cleanup () на viewModel, все представления, которые используют его как DataContext, будут выполнять свою локальную Cleanup () тоже.
Что ты думаешь? Я упустил что-то очевидное?