Upload
codemotion
View
225
Download
3
Embed Size (px)
Realizzare applicazioni cross-platform con Xamarin e il pattern MVVMMatteo PaganiWindows AppConsult Engineer Microsoft
ROME 18-19 MARCH 2016
@qmatteoq
AGENDA
1. Xamarin
2. Il pattern MVVM
3. Xamarin & MVVM
4. Servizi & Dependency Injection
XAMARIN + MICROSOFT
Accesso a tutte le
feature della piattaforma
Interfaccia utente nativa
Sviluppo Android, iOS e Windows con Visual Studio
Stesse performance
delle applicazioni
native
Possibilità di riutilizzare le skill su C#
e .NET
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 MVVMVi
ew
View
Mod
el
Mod
el
UI events
Model change events
Property
changed
events
ViewModel data
Update
Read
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
Primapublic string Name { get; set; }
Dopoprivate 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
Codiceprivate 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
ViewModel1
ViewModel2
ViewModel3
ViewModelN
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
ViewModel1
ViewModel2
ViewModel3
ViewModelN
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: [email protected]: @qmatteoq
All pictures belongto their respective authors