Realizzare applicazioni cross-platform
con Xamarin e il pattern MVVM
Matteo Pagani
Windows AppConsult Engineer
Microsoft
ROME 18-19 MARCH 2016
matteo.pagani@microsoft.com
@qmatteoq
AGENDA
1. Xamarin
2. Il pattern MVVM
3. Xamarin & MVVM
4. Servizi & Dependency Injection
XAMARIN + MICROSOFT
XAMARIN
XAMARIN TRADIZIONALE
XAMARIN FORMS
IL PATTERN MODEL-VIEW-VIEWMODEL
• Aiuta lo sviluppatore a separare la logica dall’interfaccia
utente, migliorando la leggibilità, la testabilità e il design
del codice
• In ottica di sviluppo cross-platform, aiuta a massimizzare il
riutilizzo del codice su diverse piattaforme
• Il codice è suddiviso in tre layer differenti
• Nasce nel mondo delle tecnologie Microsoft, in quanto
sfrutta alcune delle principali feature dello XAML come il
data binding
IL PATTERN MVVM
DATA BINDING
• Permette di creare un canale per collegare due
proprietà di due oggetti: «source» e «target»
• La comunicazione può essere bidirezionale
• Nel pattern MVVM, il binding è utilizzato per
collegare i controlli nello XAML con le
proprietà di un ViewModel
<TextBlock Text="{Binding Path=Name}" />
DATACONTEXT
• Definisce il contesto a cui ogni controllo XAML può accedere
per sfruttare il binding.
• Il DataContext supporta l’ereditarietà.
• Nel pattern MVVM, il ViewModel viene definito come
DataContext dell’intera View: in questo modo, la View può
accedere a tutte le proprietà e comandi esposti dal
ViewModel.
<Page
x:Class="MVVMLight.Messages.Views.MainView"
DataContext="{Binding Source={StaticResource
MainViewModel}">
</Page>
INOTIFYPROPERTYCHANGED
• Come comportamento predefinito, una proprietà non è in
grado di far sapere al canale di binding che il suo valore è
cambiato
• Di conseguenza, i controlli non sono in grado di aggiornarsi in
automatico quando il valore della proprietà collegata cambia
• L’implementazione dell’interfaccia INotifyPropertyChanged
permette di gestire questo scenario
• Nel pattern MVVM, tutti i ViewModel implementano questa
interfaccia
INOTIFYPROPERTYCHANGED
Prima
public string Name { get; set; }
Dopo
private string name;
public string Name
{
get { return name; }
set
{
name = value;
NotifyOfPropertyChange(() => Name);
}
}
XAML
<TextBlock Text="{Binding Path=Name}" />
I COMMAND
• Solitamente le interazioni dell’utente sono gestite con gli event
handler, ovvero speciali metodi che sono collegati ad un
evento e che possono essere definiti solamente nel code
behind
• I command sono un modo per definire un’azione utilizzando
una proprietà e, di conseguenza, possono essere collegati da
un controllo tramite binding
• I command supportano la gestione dello stato (abilitato o
disabilitato), che si riflette automaticamente sulla UI del
controllo nell’interfaccia
I COMMAND
Codice
private ICommand _pinToStart;
public ICommand PinToStart
{
get
{
return _pinToStart
?? (_pinToStart = new RelayCommand(
() => taskService.PinToStart(CurrentItem),
() => canPin));
}
}
XAML
<Button Text="Pin to start" Command="{Binding Path=PinToStart}" />
DEMO
ROME 18-19 MARCH 2016
Il pattern MVVM
PROBLEMA
• Il pattern MVVM si basa su concetti, come il
binding, che sono specifici del mondo XAML
• Ci serve uno strumento per poter gestire il
binding anche su piattaforme differenti da
Windows
• Esistono diverse librerie che permettono di
aggiungere le funzionalità che ci servono
MVVM LIGHT
• Libreria open source creata da Laurent Bugnion, Microsoft
MVP e membro della .NET Foundation
• Compatibile con numerose tecnologie: WPF, Silverlight,
Universal Windows Platform, Xamarin Android e iOS
• Offre gli strumenti base per implementare il pattern:
• Classe base per i ViewModel
• Classe base per i Command
• Dependency injection e messaggi
http://www.mvvmlight.net/
MVVM CROSS
• Libreria open source disponibile su GitHub
• E’ un framework completo che, oltre a mettere a disposizione
gli strumenti base per implementare il MVVM, offre
funzionalità per risolvere scenari specifici delle varie
piattaforme
• Alcuni esempi:
• Dependency injection
• Gestione del ciclo di vita della pagina
• Navigazione
http://mvvmcross.com/
DEMO
ROME 18-19 MARCH 2016
MVVM e Xamarin
SERVIZI
• Per poter riutilizzare non solo la business logic ma anche i
ViewModel in ottica cross-platform, questi non dovrebbero
contenere alcun riferimento ad API specifiche di una
piattaforma
• Un ViewModel dovrebbe solamente descrivere le operazioni
da effettuare e le interazioni con l’utente, demandando ad
altre classi l’implementazione vera e propria
• Benvenuti servizi 
SERVIZI
public RelayCommand ShowDialogCommand
{
get
{
return new RelayCommand(async () =>
{
MessageDialog dialog = new MessageDialog("Hello world");
await dialog.ShowAsync();
});
}
}
Problema: questo command utilizza una API
specifica della Universal Windows Platform
SERVIZI
public interface IDialogService
{
Task ShowDialogAsync(string message);
}
I servizi vengono descritti da una interfaccia, che
descrive solamente le operazioni, e che viene
inclusa nel progetto condiviso
SERVIZI
L’implementazione vera e propria viene inclusa nel
progetto specifico per la piattaforma.
public class DialogService : IDialogService
{
public async Task ShowDialogAsync(string message)
{
MessageDialog dialog = new
MessageDialog(message);
await dialog.ShowAsync();
}
}
SERVIZI
Il ViewModel sfrutta l’interfaccia per invocare
l’operazione da eseguire:
public RelayCommand ShowDialogCommand
{
get
{
return new RelayCommand(async () =>
{
await _dialogService.ShowDialogAsync("Hello world");
});
}
}
PROBLEMA
Nell’approccio tradizionale, i servizi vengono
istanziati in fase di compilazione:
public MainViewModel MainViewModel
{
public MainViewModel()
{
DataService service = new DataService();
service.GetItems();
}
}
PROBLEMA
DataService service = new DataService();
service.GetItems();
DataService service = new DataService();
service.GetItems();
DataService service = new DataService();
service.GetItems();
DataService service = new DataService();
service.GetItems();
DEPENDENCY INJECTION
MainViewModel IDataService
public MainViewModel(IDataService dataService)
{
}
DataServiceTestDataService
LA SOLUZIONE
public ViewModel1(IDataService dataService)
public ViewModel2(IDataService dataService)
public ViewModel3(IDataService dataService)
public ViewModelN(IDataService dataService)
IDataService
DataServiceTestDataService
DEMO
ROME 18-19 MARCH 2016
Servizi e dependency injection
http://aka.ms/mvacs
CORSI MVA
C# Xamarin Forms
http://aka.ms/mvaforms
MATERIALE
https://github.com/qmatteoq/
Codemotion2016
DEMO
https://doc.co/ctc7Y2
SLIDE
Thanks!
ROME 18-19 MARCH 2016
Mail: matteo.pagani@microsoft.com
Twitter: @qmatteoq
All pictures belong
to their respective authors

Realizzare applicazioni cross-platform con Xamarin e il pattern MVVM

  • 1.
    Realizzare applicazioni cross-platform conXamarin e il pattern MVVM Matteo Pagani Windows AppConsult Engineer Microsoft ROME 18-19 MARCH 2016 matteo.pagani@microsoft.com @qmatteoq
  • 2.
    AGENDA 1. Xamarin 2. Ilpattern MVVM 3. Xamarin & MVVM 4. Servizi & Dependency Injection
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
    IL PATTERN MODEL-VIEW-VIEWMODEL •Aiuta lo sviluppatore a separare la logica dall’interfaccia utente, migliorando la leggibilità, la testabilità e il design del codice • In ottica di sviluppo cross-platform, aiuta a massimizzare il riutilizzo del codice su diverse piattaforme • Il codice è suddiviso in tre layer differenti • Nasce nel mondo delle tecnologie Microsoft, in quanto sfrutta alcune delle principali feature dello XAML come il data binding
  • 8.
  • 9.
    DATA BINDING • Permettedi creare un canale per collegare due proprietà di due oggetti: «source» e «target» • La comunicazione può essere bidirezionale • Nel pattern MVVM, il binding è utilizzato per collegare i controlli nello XAML con le proprietà di un ViewModel <TextBlock Text="{Binding Path=Name}" />
  • 10.
    DATACONTEXT • Definisce ilcontesto a cui ogni controllo XAML può accedere per sfruttare il binding. • Il DataContext supporta l’ereditarietà. • Nel pattern MVVM, il ViewModel viene definito come DataContext dell’intera View: in questo modo, la View può accedere a tutte le proprietà e comandi esposti dal ViewModel. <Page x:Class="MVVMLight.Messages.Views.MainView" DataContext="{Binding Source={StaticResource MainViewModel}"> </Page>
  • 11.
    INOTIFYPROPERTYCHANGED • Come comportamentopredefinito, una proprietà non è in grado di far sapere al canale di binding che il suo valore è cambiato • Di conseguenza, i controlli non sono in grado di aggiornarsi in automatico quando il valore della proprietà collegata cambia • L’implementazione dell’interfaccia INotifyPropertyChanged permette di gestire questo scenario • Nel pattern MVVM, tutti i ViewModel implementano questa interfaccia
  • 12.
    INOTIFYPROPERTYCHANGED Prima public string Name{ get; set; } Dopo private string name; public string Name { get { return name; } set { name = value; NotifyOfPropertyChange(() => Name); } } XAML <TextBlock Text="{Binding Path=Name}" />
  • 13.
    I COMMAND • Solitamentele interazioni dell’utente sono gestite con gli event handler, ovvero speciali metodi che sono collegati ad un evento e che possono essere definiti solamente nel code behind • I command sono un modo per definire un’azione utilizzando una proprietà e, di conseguenza, possono essere collegati da un controllo tramite binding • I command supportano la gestione dello stato (abilitato o disabilitato), che si riflette automaticamente sulla UI del controllo nell’interfaccia
  • 14.
    I COMMAND Codice private ICommand_pinToStart; public ICommand PinToStart { get { return _pinToStart ?? (_pinToStart = new RelayCommand( () => taskService.PinToStart(CurrentItem), () => canPin)); } } XAML <Button Text="Pin to start" Command="{Binding Path=PinToStart}" />
  • 15.
    DEMO ROME 18-19 MARCH2016 Il pattern MVVM
  • 16.
    PROBLEMA • Il patternMVVM si basa su concetti, come il binding, che sono specifici del mondo XAML • Ci serve uno strumento per poter gestire il binding anche su piattaforme differenti da Windows • Esistono diverse librerie che permettono di aggiungere le funzionalità che ci servono
  • 17.
    MVVM LIGHT • Libreriaopen source creata da Laurent Bugnion, Microsoft MVP e membro della .NET Foundation • Compatibile con numerose tecnologie: WPF, Silverlight, Universal Windows Platform, Xamarin Android e iOS • Offre gli strumenti base per implementare il pattern: • Classe base per i ViewModel • Classe base per i Command • Dependency injection e messaggi http://www.mvvmlight.net/
  • 18.
    MVVM CROSS • Libreriaopen source disponibile su GitHub • E’ un framework completo che, oltre a mettere a disposizione gli strumenti base per implementare il MVVM, offre funzionalità per risolvere scenari specifici delle varie piattaforme • Alcuni esempi: • Dependency injection • Gestione del ciclo di vita della pagina • Navigazione http://mvvmcross.com/
  • 19.
    DEMO ROME 18-19 MARCH2016 MVVM e Xamarin
  • 20.
    SERVIZI • Per poterriutilizzare non solo la business logic ma anche i ViewModel in ottica cross-platform, questi non dovrebbero contenere alcun riferimento ad API specifiche di una piattaforma • Un ViewModel dovrebbe solamente descrivere le operazioni da effettuare e le interazioni con l’utente, demandando ad altre classi l’implementazione vera e propria • Benvenuti servizi 
  • 21.
    SERVIZI public RelayCommand ShowDialogCommand { get { returnnew RelayCommand(async () => { MessageDialog dialog = new MessageDialog("Hello world"); await dialog.ShowAsync(); }); } } Problema: questo command utilizza una API specifica della Universal Windows Platform
  • 22.
    SERVIZI public interface IDialogService { TaskShowDialogAsync(string message); } I servizi vengono descritti da una interfaccia, che descrive solamente le operazioni, e che viene inclusa nel progetto condiviso
  • 23.
    SERVIZI L’implementazione vera epropria viene inclusa nel progetto specifico per la piattaforma. public class DialogService : IDialogService { public async Task ShowDialogAsync(string message) { MessageDialog dialog = new MessageDialog(message); await dialog.ShowAsync(); } }
  • 24.
    SERVIZI Il ViewModel sfruttal’interfaccia per invocare l’operazione da eseguire: public RelayCommand ShowDialogCommand { get { return new RelayCommand(async () => { await _dialogService.ShowDialogAsync("Hello world"); }); } }
  • 25.
    PROBLEMA Nell’approccio tradizionale, iservizi vengono istanziati in fase di compilazione: public MainViewModel MainViewModel { public MainViewModel() { DataService service = new DataService(); service.GetItems(); } }
  • 26.
    PROBLEMA DataService service =new DataService(); service.GetItems(); DataService service = new DataService(); service.GetItems(); DataService service = new DataService(); service.GetItems(); DataService service = new DataService(); service.GetItems();
  • 27.
    DEPENDENCY INJECTION MainViewModel IDataService publicMainViewModel(IDataService dataService) { } DataServiceTestDataService
  • 28.
    LA SOLUZIONE public ViewModel1(IDataServicedataService) public ViewModel2(IDataService dataService) public ViewModel3(IDataService dataService) public ViewModelN(IDataService dataService) IDataService DataServiceTestDataService
  • 29.
    DEMO ROME 18-19 MARCH2016 Servizi e dependency injection
  • 30.
    http://aka.ms/mvacs CORSI MVA C# XamarinForms http://aka.ms/mvaforms
  • 31.
  • 32.
    Thanks! ROME 18-19 MARCH2016 Mail: matteo.pagani@microsoft.com Twitter: @qmatteoq All pictures belong to their respective authors