Confessions of a Dangerous Mind

Brain.FlushBuffer()
posts - 176, comments - 234, trackbacks - 93

WPF Prism Technical Concepts: Communication Techniques

Una applicazione modulare, qualsiasi sia l’ambiente “tecnologico” in cui opera, necessita di poter far comunicare tra di loro le parti delle quali è composta. Nel caso di Prism, abbiamo già visto come l’Event Aggregator possa essere d’aiuto per implementare una comunicazione “Loosely-Coupled Event-Based”. Esistono però anche altre tecniche di comunicazioni tra l’utente ed i moduli e tra moduli. Vediamo insieme le varie possibilità messe a disposizione dal Prism Framework.

Commanding

L’utilizzo di comandi per implementare l’interazione Utente-Applicazione è la prima forma di comunicazione. Prism mette a disposizione i due tipi di comandi (già visti in un precedente post) DelegateCommand e CompositeCommand. Inoltre sono comunque disponibili i Routed Commands standard di WPF, anche se il loro utilizzo rimane piuttosto limitato all’ambito “locale” (rispetto al modulo). Il CompositeCommand può essere utilizzato in modo proficuo per implementare una comunicazione trasversale tra moduli, in quanto diversi moduli possono registrare i propri comandi “locali” all’interno di un comando composito condiviso, in modo che l’azionamento di tale comando faccia scattare l’azionamento di tutti i comandi registrati.
Piccola nota sui Routed Events: dobbiamo buttarli via? Assolutamente no! Come già detto in precedenza non c’è nulla di male nello scrivere codice nel codebehind della View, per cui questi Events possono essere utilizzati quando siamo interessati ad impiegare le caratteristiche di Event Tunnelling, ad esempio in un Custom Control.

Event Aggregation

Come già visto in questo post, l’Event Aggregator è il sistema offerto da Prism per inviare messaggi attraverso l’applicazione. L’impiego dell’Event Aggregator è molto semplice e permette di effettuare comunicazioni modulo-host e modulo-modulo, in modo “multicast”: ovvero è possibile che per ogni evento pubblicato siano registrati più sottoscrittori, in modo da implementare di fatto una comunicazione “One-to-Many”. Definendo gli eventi in un assembly separato rispetto agli assembly contenenti i moduli, si riesce inoltre ad implementare una comunicazione intra-modulo evitando di dover creare referenze dirette tra moduli.

Region Context

Spesso è utile poter condividere informazioni (identificatori, interi oggetti o collections) tra diverse View. Questo concetto diventa sicuramente più chiaro nel caso di Views di tipo Master-Detail. In questo scenario, infatti, esisterà una View “Parent” che visualizzerà i dati Master ed una View “Child” che visualizzerà i dati child, provenienti ad esempio da una collection esposta come property dal ViewModel collegato alla proprietà DataContext della Master View. In questo caso, l’utilizzo di un RegionContext, permette di esporre oggetti alle viste contenute. Questo region context può essere inizializzato nei seguenti modi:

  • Dichiarativo, nello XAML della Master View
  • Imperativo, nel codice della Master View

un esempio di tali utilizzi segue nel prossimo snippet di codice:

   1: //Declarative
   2: <TabControl
   3:     cal:RegionManager.RegionName="Region1"
   4:     cal:RegionManager.RegionContext="{Binding Path=SelectedEmployee.EmployeeId}"/>
   5:  
   6: //Imperative
   7: RegionManager.Regions[“Region1”].Context = employeeId;

Non è MAI una buona idea utilizzare il DataContext come “zona di comunicazione”, in quanto la sua funzione è quella di offrire i dati per il databinding alle view e non quella di immagazzinare dati in comune tra le viste.

Shared Services

Come già anticipato in un precedente post, anche i Servizi possono essere utilizzati per comunicare tra i moduli di una Prism Application. Infatti, grazie a Unity ed al pattern Dependency Injection, è possibile registrare nel container i servizi in modalità Singleton, ovvero ogni servizio che impieghi tale servizio utilizzerà sempre la stessa istanza. In questo modo, il servizio può essere utilizzato come “buffer” di trasmissione dati tra moduli. Un esempio potrebbe essere un ipotetico servizio di Autenticazione: un Modulo effettua la “Login” dell’utente ed immagazzina nel servizio i dati utili per effettuare successive chiamate ad altri servizi; gli altri moduli preleveranno tale servizio dal container ed utilizzeranno i dati dell’utente in una modalità condivisa.

Concludendo questa breve “overview” sulle possibili modalità di comunicazione intra-application di Prism, voglio solo porre l’accento sull’importanza di una buona architettura quando si vuole impiegare un’infrastruttura di comunicazione come quella appena vista. E’ necessario infatti pianificare con cura  (e documentare!) il ruolo di ogni messaggio e di ogni modulo onde evitare la proliferazione di messaggi ed eventi duplicati che renderebbero il sistema inutilmente complesso.

Print | posted on giovedì 1 ottobre 2009 01:58 |

Feedback

Gravatar

# UX: ma come sono abituati bene :-)

UX: ma come sono abituati bene :-)
02/10/2009 18:51 | [ topics . it ]
Comments have been closed on this topic.

Powered by:
Powered By Subtext Powered By ASP.NET