I primi due concetti di Prism che andiamo ad approfondire sono la Shell ed il Bootstrapper.
Shell
La Shell rappresenta il “contenitore” che andrà ad ospitare l’applicazione Prism. Essa deve essere creata seguendo alcune direttive di CAL, ma essenzialmente può essere una Window o una Page. Al suo interno possono essere collocati dei controlli generici e dei controlli “particolari” che rappresentano le “regions” all’interno delle quali vengono iniettate le Views dei vari moduli (ricordiamoci che Prism è nato per supportare la modularità…).
Un esempio di Shell può essere il seguente:
1: <Window x:Class="PrismOne.Shell"
2: xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3: xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4: xmlns:cal="http://www.codeplex.com/CompositeWPF"
5: Title="Prism One!" Height="300" Width="300">
6:
7: <ItemsControl x:Name="MainRegion" cal:RegionManager.RegionName="MainRegion"/>
8:
9: </Window>
Nello snippet si possono vedere un paio di “particolarità”:
- Viene utilizzato il namespace cal, dove è possibile trovare la classe RegionManager, utilizzata per “taggare” le regions che andranno ad ospitare le view dei nostri moduli.
- Abbiamo un ItemsControl (il repeater di WPF, per intenderci) che viene marcato con la RegionName “MainRegion”. Questa regione si potrà poi ritrovare nella collection Regions della classe RegionManager.
Un riferimento all’interfaccia IRegionManager verrà passata poi al costruttore del modulo ospitato che provvederà, tramite Unity, a risolverla all’interno del container.
In pratica, quando una Shell viene caricata, CAL si occupa di interpretare tutti i tag che marcano le varie region e di memorizzarle in modo che i moduli sappiano dove andare a collocarsi (mediante view discovery o view injection). Vedremo poi in un futuro post come realizzare un modulo e come sia organizzata la UI Composition.
Bootstrapper
L’altro argomento che voglio esaminare, senza cui non si può neppure cominciare a programmare un’applicazione Prism è il Bootstrapper. Il bootstrapper è una semplicissima classe che deve ereditare da Microsoft.Practices.Composite.UnityExtensions.UnityBootstrapper. La funzione del bootstrapper è un pò quella della “messa in moto” dell’applicazione. Nello snippet seguente vediamo un esempio base di Bootstrapper:
1: using Microsoft.Practices.Composite.Modularity;
2: using Microsoft.Practices.Composite.UnityExtensions;
3:
4: namespace PrismOne
5: {
6: class Bootstrapper : UnityBootstrapper
7: {
8: protected override System.Windows.DependencyObject CreateShell()
9: {
10: //Bootstrapper create (or resolve) shell
11: Shell _shell = new Shell();
12: _shell.Show();
13: return _shell;
14: }
15:
16: protected override IModuleCatalog GetModuleCatalog()
17: {
18: ModuleCatalog _catalog = new ModuleCatalog();
19: //Fill catalog with modules...
20: return _catalog;
21: }
22: }
23: }
Nelle applicazioni WPF siamo abituati ad avere la classe App che fa partire una determinata Window (o Page) come specificato nello StartupUri. In una Prism Application è effettivamente il Bootstrapper che avvia la visualizzazione della shell ed amministra il catalogo dei moduli. Infatti, nello script, si vede che è stato fatto l’override dei soli due metodi CreateShell e GetModuleCatalog. Nel GetModuleCatalog è essenziale che venga creato un catalogo, anche se vuoto. Non è possibile ritornare null, a meno che non si voglia incorrere in un errore appena si avvia l’applicazione.
A proposito di avvio dell’applicazione, c’è un ultimo accorgimento da adottare per far avviare correttamente la nostra applicazione. E’ infatti necessario rimuovere il riferimento dello StartupUri dal file App.xaml ed aggiungere il metodo OnStartup, che viene lanciato all’avvio dell’applicazione stessa, come è possibile vedere nello snippet seguente:
1: namespace PrismOne
2: {
3: /// <summary>
4: /// Interaction logic for App.xaml
5: /// </summary>
6: public partial class App : Application
7: {
8: protected override void OnStartup(StartupEventArgs e)
9: {
10: base.OnStartup(e);
11: Bootstrapper _bootstrapper = new Bootstrapper();
12: _bootstrapper.Run();
13: }
14: }
15: }
L’ultima riga dello snippet, tramite il metodo Run, avvia il Bootstrapper che a sua volta popola il catalogo, crea la shell e la visualizza. Nei prossimi post vedremo come creare un modulo e come inserirlo nella nostra semplicissima infrastruttura Prism. Nel frattempo, scaricate la versione di Prism che potete trovare qui.