UI Composition
Problemi e “possibili” Soluzioni



Mauro Servienti
Microsoft MVP - Visual C#
Software Mason @ Managed Designs

http://blogs.ugidotnet.org/topics
mauro.servienti@gmail.com
Agenda
• Indagine di mercato;
• M-V-VM:
  – Overview;
  – Il dottore ha detto...
• UI Composition
  – Ma pecccchè?
  – I problemi;
  – Le possibili soluzioni;
• Parliamone insieme.
Italiani! :-P

INDAGINE DI MERCATO
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?
Tutti ne parlano... Ma che cosa è?

M-V-VM: OVERVIEW
Please welcome M-V-VM




                                               presentation
                       View

                          DataBinding

                           Command




                                               engine
Il centro del        ViewModel          D.I.

   mondo!

                       Repository<T>

                       Model




                                               data
                              Adapter



                   Somewhere in
                      time...
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... 
Il libro che ho letto dice che devo fare così, ma tu invece hai fatto cosà...!

M-V-VM: IL DOTTORE HA DETTO...
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:
    class MyViewModel
    {
      public MyViewModel( IRepository<Customer> repo ){ ... }
    }


• Tanto vale farlo fino in fondo:
    class MyViewModel
    {
      public MyViewModel( IView view, IRepository<Customer> repo ){ ... }
    }
...e ‘I’View diventa

        interface IView
        {
          Object DataContext{ get; set; }
        }
                        interface ICloseableView : IView
                        {
                          event CancelEventHandler Closing;
                          event EventHandler Closed;
                        }



Alla fine il nostro compito è consegnare valore non
                     filosofeggiare ;-)
È un investimento decisamente onoreso, ne vale la pena?

UI COMPOSITION: PERCHÈ?
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;
Ok, chiaro... Ma a che costo?

UI COMPOSITION: I PROBLEMI
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?
    CustomerWindow: Instance 1   CustomerWindow: Instance 2
    “ContentRegion”              “ContentRegion”




• IRegionManager.GetRegion( name ) ?
• svc.RegisterRegion( name, view );
• svc.GetManager( view ).GetRegion( name );
Come comunicano?


                                                Una toolbar contestuale
l’elemento selezionato deve
                                                compare quando visualizziamo
“attivare” un Command nella
                                                contenuti contestuali
toolbar




                              La variazione di selezione deve
                              essere intercettata per iniettare
                              i 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;
Comporre, scomporre e ricomporre questo è il segreto...

UI COMPOSITION: LE POSSIBILI
SOLUZIONI
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:
 var regionManager = this.regionService.GetRegionManager( this.View );
 var msg = new ViewModelLoading<IShellViewModel>( this, regionManager );
 this.broker.Dispatch( msg );


• che possiamo usare a nostro uso e consumo:
 this.broker.Subscribe<ViewModelLoading<IShellViewModel>>( this, msg =>
 {
       var viewModel = this.provider.GetService( typeof( IMyContentViewModel ) )
       msg.RegionManager[ "myRegionName" ].Add( viewModel.View );
 } );
IMessage lifecycle
            SearchRequestMessage              Broker




                                     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/Disattiva
                                 zione 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
m-v-vm @ UgiAlt.Net

m-v-vm @ UgiAlt.Net

  • 1.
    UI Composition Problemi e“possibili” Soluzioni Mauro Servienti Microsoft MVP - Visual C# Software Mason @ Managed Designs http://blogs.ugidotnet.org/topics mauro.servienti@gmail.com
  • 2.
    Agenda • Indagine dimercato; • M-V-VM: – Overview; – Il dottore ha detto... • UI Composition – Ma pecccchè? – I problemi; – Le possibili soluzioni; • Parliamone insieme.
  • 3.
  • 4.
    Per alzata dimano... Abbiamo 29 slide...dobbiamo capire come usarle.. Agili, agili ;-) • Quanti hanno familiarità con IoC e DI? • Quanti conoscono e usano M-V-VM?
  • 5.
    Tutti ne parlano...Ma che cosa è? M-V-VM: OVERVIEW
  • 6.
    Please welcome M-V-VM presentation View DataBinding Command engine Il centro del ViewModel D.I. mondo! Repository<T> Model data Adapter Somewhere in time...
  • 7.
    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... 
  • 8.
    Il libro cheho letto dice che devo fare così, ma tu invece hai fatto cosà...! M-V-VM: IL DOTTORE HA DETTO...
  • 9.
    Il centro delmondo • 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...
  • 10.
    Iniettiamo anche la‘I’View... • Se facciamo uso di IoC, ci siamo già in parte tagliati le gambe: class MyViewModel { public MyViewModel( IRepository<Customer> repo ){ ... } } • Tanto vale farlo fino in fondo: class MyViewModel { public MyViewModel( IView view, IRepository<Customer> repo ){ ... } }
  • 11.
    ...e ‘I’View diventa interface IView { Object DataContext{ get; set; } } interface ICloseableView : IView { event CancelEventHandler Closing; event EventHandler Closed; } Alla fine il nostro compito è consegnare valore non filosofeggiare ;-)
  • 12.
    È un investimentodecisamente onoreso, ne vale la pena? UI COMPOSITION: PERCHÈ?
  • 13.
    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;
  • 14.
    Ok, chiaro... Maa che costo? UI COMPOSITION: I PROBLEMI
  • 15.
    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;
  • 16.
    Domain Model • Contabilità“dipende” da Anagrafiche? • Dipende... ;-) da che cosa? – Se modularizzo per necessità di sviluppo; – Se modularizzo per necessità di deploy;
  • 17.
    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
  • 18.
    Semplicità...adesso un po’meno... Ecco perchè per mettere M-V-VM al centro del mondo è necessario sporcarsi le mani
  • 19.
    Region: statiche edinamiche • Toolbars e Documents sono region “statiche”; – Referenziabili per “nome”; • Ma se avessimo più Window? CustomerWindow: Instance 1 CustomerWindow: Instance 2 “ContentRegion” “ContentRegion” • IRegionManager.GetRegion( name ) ? • svc.RegisterRegion( name, view ); • svc.GetManager( view ).GetRegion( name );
  • 20.
    Come comunicano? Una toolbar contestuale l’elemento selezionato deve compare quando visualizziamo “attivare” un Command nella contenuti contestuali toolbar La variazione di selezione deve essere intercettata per iniettare i contenuti contestuali
  • 21.
    L’ecosistema: è unmondo 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;
  • 22.
    Comporre, scomporre ericomporre questo è il segreto... UI COMPOSITION: LE POSSIBILI SOLUZIONI
  • 23.
    Il mio DomainModel • Il pericolo è il mio mestiere: • Potreste avere un Repository<T> basato su servizi WCF; • Naturalmente... non si possono fare le join;
  • 24.
    RegionService, RegionManager, Region •Wpf e Xaml vi danno la massima libertà: lunga vita alle Attached Property; <ContentPresenter rg:RegionService.Region="{rg:ContentPresenterRegion 'myRegionName'}" />
  • 25.
    Il postino suonasempre 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;
  • 26.
    Italiani...! La shellsi avvia! • Il nostro postino trasporta messaggi: ViewModelLoading<IShellViewModel>() • che contengono informazioni: var regionManager = this.regionService.GetRegionManager( this.View ); var msg = new ViewModelLoading<IShellViewModel>( this, regionManager ); this.broker.Dispatch( msg ); • che possiamo usare a nostro uso e consumo: this.broker.Subscribe<ViewModelLoading<IShellViewModel>>( this, msg => { var viewModel = this.provider.GetService( typeof( IMyContentViewModel ) ) msg.RegionManager[ "myRegionName" ].Add( viewModel.View ); } );
  • 27.
    IMessage lifecycle SearchRequestMessage Broker MessageHandler Handler -“Risolve” il ViewModel; - passa le informazione sulla ricerca richiesta; - Inietta la View nella Region; ViewModel -Esegue la ricerca; - Visualizza i risultati;
  • 28.
    Messaggi o Eventi:l’unione fa la forza • Ingestibili con messaggi: – Attivazione/Disattiva zione 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