Le problematiche più comuni di un'architettura M-V-VM con WPF
di Cristian Civera, in Windows Presentation Foundation, 6 ottobre 2009
Archiviato in: .NET Framework, .NET Framework 3.0, .NET Framework 3.5, Architettura, Windows Presentation Foundation, XAML, Pattern
Il mediator pattern
Nel paragrafo precedente si sono evidenziati l'utilità, ma anche i difetti di un approccio basato sugli eventi per far comunicare la View con il VM. La comunità degli sviluppatori non è nuova a queste problematiche, grazie anche all'esperienza fatta con altri framework e per questo scopo trova un'ottima applicazione il mediator pattern.
Dal punto di vista teorico esistono due attori: il mediator e il colleague. Il primo funge da oggetto coordinatore e intermediario tra più colleague i quali non si conoscono, ma comunicano grazie appunto al mediatore. Questo permette sia di disaccoppiare, mantenendo la possibilità di testare ogni singola unità, sia di non avere i limiti che si hanno con gli eventi, descritti in precedenza.
All'atto pratico nel MVVM Light Toolkit, citato ad iniziato articolo, è presente una classe Messenger che è il mediatore per lo scambio di messaggi tra la View e il VM. L'interfaccia di scambio di nome IMessageRecipient è adibita al semplice scambio di messaggi ed è così definita:
public interface IMessageRecipient { void ReceiveMessage(MessageBase message); }
Per realizzare come nel paragrafo precedente la chiusura dell'applicazione, si deve quindi implementare tale interfaccia per l'oggetto che vuole ricevere un messaggio, nel caso specifico la finestra. Quest'ultima per ricevere il messaggio deve inoltre registrarsi sulla classe Messenger e indicare quale tipo di messaggio vuole ricevere. Il tipo MessageBase è infatti generico e non porta alcuna informazione con se, perciò occorre definire un proprio messaggio o sfruttare quelli preconfezionati, come il CommandMessage che porta con sé una stringa identificativa del comando. Ecco quindi come la finestra si registra per ricevere il messaggio:
public partial class MainWindow : Window, IMessageRecipient { public MainWindow() { Messenger.Default.Register(this, typeof(CommandMessage)); } }
La proprietà statica Default crea e restituisce in automatico un'istanza predefinita della classe Messenger, ma è possibile istanziarne una specifica per raggruppare un'insieme di messaggi e di ascoltatori a patto che questa istanza sia visibile da tutte le parti in causa.
L'implementazione dell'interfaccia si deve quindi limitare ad identificare il tipo di messaggio, valutarne le informazioni ed eseguire l'eventuale operazione. Nell'esempio preso in considerazione si verifica se il comando è quello di chiusura per agire poi di conseguenza.
void IMessageRecipient.ReceiveMessage(MessageBase message) { CommandMessage cm = message as CommandMessage; if (cm != null && cm.Command == "Close") this.Close(); }
L'implementazione della classe Messenger fa sì che il metodo ReceiveMessage venga invocato solo su quelle istanze che si sono registratate per quel tipo di messaggio, perciò questa tecnica gode di buone prestazioni. Inoltre il mediatore mantiene al suo interno una WeakReference dell'istanza e di conseguenza non è richiesto togliere la registrazione qualora l'istanza della finestra muoia. Il tutto viene automaticamente gestito dal CLR consentendo di dimenticarsi completamente del processo di messaggistica.
A questo punto non resta che mandare il messaggio dove richiesto, sull'implementazione del comando CloseApplicationCommand situato nel VM.
private void Close() { Messenger.Default.Broadcast(new CommandMessage(this, "Close")); }
Facendo riferimendo alla stessa istanza di Messenger, si trasmette il messaggio creato a chi è in ascolto: la View. Nel toolkit preso in considerazione esistono altri messaggi già pronti all'uso:
- GenericMessage
: dispone di una proprietà Content che fa da contenitore dove è possibile inserire qualsiasi oggetto di tipo T; - DialogMessage: identifica la richiesta di mostrare una finestra di dialogo, trasmettendo il titolo, il messaggio, i pulsanti e un eventuale callback da chiamare;
- PropertyChangedMessage
: messaggio per identificare il cambio di una proprietà.
Il tipo di messaggio è quindi la discrimintante per identificare l'operazione da eseguire e in generale il tipo di notifica. Può però essere esteso con una proprietà per avere informazioni aggiuntive, come nel caso del CommandMessage, e permette di supportare diversi scenari: finestre di dialogo, finestre modali, visualizzazione degli errori e notifiche di operazioni.
La tecnica illustrata è piuttosto rapida da utilizzare, garantisce il disaccoppiamento e permette facilmente di creare mock che permettano di intercettare il messaggio e di testare l'intero ciclo di trasmissione dei messaggi.
Attenzione: Questo articolo contiene un allegato.
Contenuti dell'articolo
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimeti
-
Introduzione a Team Foundation Server 2010
-
Multithreading e parallelismo con il .NET Framework 4.0
-
Le novità nel .NET Framework 4.0 di WPF, WCF e WF
-
Le novità di Visual Basic 2010 e C# 4
-
Mostrare le camere di sorveglianza tramite il .NET Micro Framework
-
La piattaforma Microsoft per il cloud computing: Windows Azure
-
Interoperabilità con WCF: invocare servizi da PHP e Flash
-
Le novità di Windows 7 per gli sviluppatori
-
Costruire una chat per Silverlight con il PollingDuplexHttpBinding

Commenti
mi piace
non mi piace
Facebook
Twitter









