Upload
mauro-servienti
View
504
Download
1
Embed Size (px)
DESCRIPTION
m-v-vm @ UgiAlt.Net
Citation preview
Mauro Servienti
UI Composition
Microsoft MVP - Visual C#Software Mason @ Managed Designs
http://blogs.ugidotnet.org/[email protected]
Problemi e “possibili” Soluzioni
Agenda
• Indagine di mercato;• M-V-VM:– Overview;– Il dottore ha detto...
• UI Composition– Ma pecccchè?– I problemi;– Le possibili soluzioni;
• Parliamone insieme.
INDAGINE DI MERCATOItaliani! :-P
Per alzata di mano...
Abbiamo 29 slide...dobbiamo capire come usarle.. Agili, agili ;-)
• Quanti hanno familiarità con IoC e DI?
• Quanti conoscono e usano M-V-VM?
M-V-VM: OVERVIEWTutti ne parlano... Ma che cosa è?
Il centro del mondo!
Please welcome M-V-VM
Somewhere in time...
ViewModel
Repository<T>
D.I.
View
DataBinding
Command pres
enta
tion
engi
neda
ta
Model
Adapter
Pregi & Difetti
• + Testabilità della logica della UI;• + Sostituibilità della UI (stesso View Engine);• + Elevata manutenibilità;
• - Aumento della complessità e mancanza di “controllori” (San csc.exe non aiuta...);
• - il data binding non risolve tutti gli scenari... dobbiamo sporcarci le manine...
M-V-VM: IL DOTTORE HA DETTO...Il libro che ho letto dice che devo fare così, ma tu invece hai fatto cosà...!
Il centro del mondo
• Il designer non deve scrivere codice;– > Il ViewModel deve diventare il vostro unico
punto di riferimento;• Ma non tutto si può “bindare” purtroppo:– Come gestiamo il processo di chiusura della View?– E quello di attivazione?– Come interagiamo con l’utente?• Dialog (dialog owner), MessageBoxes, etc...
Iniettiamo anche la ‘I’View...
• Se facciamo uso di IoC, ci siamo già in parte tagliati le gambe:
• Tanto vale farlo fino in fondo:
class MyViewModel{ public MyViewModel( IRepository<Customer> repo ){ ... }}
class MyViewModel{ public MyViewModel( IView view, IRepository<Customer> repo ){ ... }}
...e ‘I’View diventa
Alla fine il nostro compito è consegnare valore non filosofeggiare ;-)
interface IView{ Object DataContext{ get; set; }}
interface ICloseableView : IView{ event CancelEventHandler Closing; event EventHandler Closed;}
UI COMPOSITION: PERCHÈ?È un investimento decisamente onoreso, ne vale la pena?
Bella domanda...
• Cliente: necessità di modularizzare:– Acquistare in configurazioni diverse;– Installare in configurazioni diverse;
• Team: necessità di gestire e lavorare:– Team grande o distribuito;– Soluzione/i di dimensioni ingestibili in VS;– Tempi di sviluppo diversi dei “moduli” che non
devono condizionarsi/bloccarsi a vicenda;
UI COMPOSITION: I PROBLEMIOk, chiaro... Ma a che costo?
Requisiti: un esempio
• Semplice applicazione “gestionale”:– Anagrafiche;– Contabilità;
• Il cliente deve poter installare il “modulo” anagrafiche senza la contabilità;
• Il team deve poter sviluppare i 2 moduli indipendentemente;
Domain Model• Contabilità “dipende” da Anagrafiche?
• Dipende... ;-) da che cosa?– Se modularizzo per necessità di sviluppo;– Se modularizzo per necessità di deploy;
Semplicità, adesso è tutto così facile...“Region... perchè sei tu region”
Toolbars e Documents sono Region in cui poter iniettare contenuti a runtime
xxxDetails è una Region in cui poter iniettare contenuti contestuali a runtime
Semplicità...adesso un po’ meno...
Ecco perchè per mettere M-V-VM al centro del mondo è necessario sporcarsi le mani
Region: statiche e dinamiche• Toolbars e Documents sono region “statiche”;– Referenziabili per “nome”;
• Ma se avessimo più Window?
• IRegionManager.GetRegion( name ) ?
CustomerWindow: Instance 1“ContentRegion”
CustomerWindow: Instance 2“ContentRegion”
• svc.RegisterRegion( name, view );• svc.GetManager( view ).GetRegion( name );
Come comunicano?
l’elemento selezionato deve “attivare” un Command nella toolbar
La variazione di selezione deve essere intercettata per iniettare i contenuti contestuali
Una toolbar contestuale compare quando visualizziamo contenuti contestuali
L’ecosistema: è un mondo difficile
• L’ecosistema: lunga vita a Visual Studio– la shell;– i moduli;– il processo di bootstrap;
• Diligenza assoluta, farsi prendere la mano, e sporcarla, è molto facile ma il rischio è di pagarla cara dopo;
• La navigazione e il ciclo di vita dei “documenti”: RunningDocumentsService;
UI COMPOSITION: LE POSSIBILI SOLUZIONI
Comporre, scomporre e ricomporre questo è il segreto...
Il mio Domain Model
• Il pericolo è il mio mestiere:
• Potreste avere un Repository<T> basato su servizi WCF;
• Naturalmente... non si possono fare le join;
RegionService, RegionManager, Region
• Wpf e Xaml vi danno la massima libertà: lunga vita alle Attached Property;
<ContentPresenter rg:RegionService.Region="{rg:ContentPresenterRegion 'myRegionName'}" />
Il postino suona sempre 2 volte
• I vari attori, aka Module, non si conoscono ma hanno la necessità di comunicare tra loro:– Dobbiamo definire una lingua nota a tutti;– Dobbiamo designare qualcuno come postino;
Italiani...! La shell si avvia!
• Il nostro postino trasporta messaggi: ViewModelLoading<IShellViewModel>()
• che contengono informazioni:
• che possiamo usare a nostro uso e consumo:
var regionManager = this.regionService.GetRegionManager( this.View );var msg = new ViewModelLoading<IShellViewModel>( this, regionManager );this.broker.Dispatch( msg );
this.broker.Subscribe<ViewModelLoading<IShellViewModel>>( this, msg => {
var viewModel = this.provider.GetService( typeof( IMyContentViewModel ) )msg.RegionManager[ "myRegionName" ].Add( viewModel.View );
} );
IMessage lifecycle
BrokerSearchRequestMessage
MessageHandler
Handler-“Risolve” il ViewModel;- passa le informazione sulla ricerca richiesta;- Inietta la View nella Region;ViewModel-Esegue la ricerca;- Visualizza i risultati;
Messaggi o Eventi: l’unione fa la forza
• Ingestibili con messaggi:– Attivazione/
Disattivazione Document;
– Cambio di selezione;
• Gli eventi tornano ad essere vincenti:– Una Region notifica il cambio di contenuto attivo;– Un ViewModel può interagire con il contenuto:– IHandlePrintScenario -> PrintScenarioChanged
Si aprano le danze
?