MVVM Light: como cancelar o registro do Messenger

Adoro o Messenger do MVVM Light e sua flexibilidade, no entanto, estou com vazamentos de memória quando esqueço de cancelar o registro explícito dos destinatários (no Silverlight 4

A causa é explicadaAqu, mas estou bem com isso, pois acredito que é uma boa prática cancelar o registro explícito dos destinatários de qualquer maneira, em vez de confiar no uso de referências fracas do Mensageiro. O problema é que é mais fácil falar do que faze

ViewModels são fáceis: você geralmente tem controle total sobre o ciclo de vida e pode simplesmenteCleanup() quando não forem mais necessário

Views, por outro lado, são mais complicados porque são instanciados e destruídos via DataTemplates. Por ex. você pode pensar em umItemsControl comMyView como DataTemplate, vinculado a umObservableCollection<MyViewModel>. OMyViews controles @ são criados / coletados pelo mecanismo de ligação e você não tem uma boa maneira de chamar manualmente Cleanup (

Tenho uma solução em mente, mas gostaria de saber se é um padrão decente ou se existem alternativas melhores. A idéia é enviar uma mensagem específica do ViewModel para informar ao (s) View (s) associado (s) a descartar:

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<ViewModelDisposingMessage>(this, m =>
             {
                 if (m.SenderViewModel == this.DataContext)
                     this.Cleanup();
             });
    }

    public void Cleanup()
    {
        Messenger.Default.Unregister<...>(this);
        Messenger.Default.Unregister<ViewModelDisposingMessage>(this);
    }
}

Então, quando você chama Cleanup () em um viewModel, todos os modos de exibição que o usam como DataContext também executam seu Cleanup () loca

O que você acha? Estou perdendo algo óbvio?

questionAnswers(3)

yourAnswerToTheQuestion