Sviluppare applicazioni cross-platform con Xamarin Forms e PrismMatteo PaganiWindows AppConsult Engineer @ [email protected]: @qmatteoq
MILAN 25-26 NOVEMBER 2016
Shared C# codebase • 100% native API access • High performance
Shared C# Business Logic(Portable Class Library)
Shared C# UI (XML)
XAMARIN FORMS
<?xml version="1.0" encoding="UTF-8"?><TabbedPage xmlns=“…" xmlns:x=“…“ x:Class="MyApp.MainPage" > ><TabbedPage.Children><ContentPage Title="Profile" Icon ="Profile.png"> < <StackLayout Spacing="20" Padding="20” VerticalOptions="Center"> <<Entry Placeholder="Username" Text="{Binding Username}"> <<Entry Placeholder="Password” Text="{Binding Password}” IsPassword="true">> <<Button Text="Login" TextColor="White” BackgroundColor=”…” Command=”…">/> </<StackLayout>> </ContentPage>> <ContentPage Title = "Settings"
Icon = "Settings.png">> <!-- Settings --></ <ContentPage>></TabbedPage.Children>
XAMARIN FORMS
THE MVVM PATTERNVi
ew
View
Mod
el
Mod
el
UI events
Model change events
Property
changed
events
ViewModel data
Update
Read
PRISM FOR XAMARIN FORMS
• Prism was a MVVM framework originally created by the Patterns & Practises division by Microsoft
• Now it’s an open source project driven by Brian Lagunas, a Microsoft MVP, and by the community
• It provides the basic infrastructure to implement the MVVM pattern:• Base class for ViewModels• Dependency injection container with multiple framework choices• Messages
• It provides advanced features to solve specific requirements of Xamarin Forms:• Navigation from a ViewModel• Handling the page’s lifecycle• Handling platform specific code• Deep linking
https://github.com/PrismLibrary
CONFIGURATION
• Manually, by adding the following NuGet packages:• Prism.Core• Prism.Forms• Prism.xyz.Forms, where xyz is one of the supported dependency
injection containers (Unity, Ninject, Autofact, etc.)• Automatically, with the project wizard:
DEPENDENCY INJECTION
With the standard approach, objects that are used in a ViewModel are created at compile time:
public MainViewModel MainViewModel{ public MainViewModel() {
DataService service = new DataService(); service.GetItems(); }}
DEPENDENCY INJECTION
MainViewModel IDataService
public MainViewModel(IDataService dataService){ }
DataServiceTestDataService
DEPENDENCY INJECTION
• In the App class you associate the interface with its concrete implementation:
Container.RegisterType<IDataService, DataService>();
• In the constructor of the ViewModel, you create a dependency by adding a parameter to the class’ constructor:
private readonly IDataService _apiService;
public MainPageViewModel(IDataService apiService){ _apiService = apiService;}
• You use the class in any method or property of your ViewModel
CONFIGURATION
• Your App class needs to inherit from PrismApplication• RegisterTypes() method to register classes inside the dependency
container.• OnInitialized() method to navigate to the main page of the app using the
NavigationService provided by Prism
KEYWORD: flexibility• Default naming convention: MainPage -> MainPageViewModel• You don’t like it? Feel free to override it and manually specify the
connection in the dependency container.
Container.RegisterTypeForNavigation<MainPage>();Container.RegisterTypeForNavigation<DetailPage, MyCustomDetailViewModel>();
NAVIGATION
• INavigationAware is an interface that you can implement in your ViewModels to get access to the following events:• OnNavigatedTo() when you navigate to the page• OnNavigatedFrom() when you navigate away from the page• OnNavigatingTo() when you are navigating to the page
• NavigationService can be used to navigate from one page to another, with support to parameters:
NavigationParameters param = new NavigationParameters();param.Add("text", “This is a parameter");await _navigationService.NavigateAsync("DetailPage", param);
• In the OnNavigatedTo() method of the destination page you can retrieve the parameter
NAVIGATION
• Deep link: you can create complex navigation paths and retain the stack of the pages
await NavigationService.NavigateAsync("MainTabbedPage/NavigationPage/ShowsListPage/DetailPage?id=279121");
MainTabbedPage Navigation ShowsList Detail
DEMOAdvanced navigation
HANDLING PLATFORM SPECIFIC CODE
• Xamarin Forms allows to share business logic and user interface but, at some point, you need to write platform specific code
• Xamarin Forms offers a DependencyService class and a Dependency attribute to handle this scenario
Portable Class Library
IShareService
IosShareService
DroidShareService
UwpShareService
[assembly: Dependency(typeof(UwpShareService))]
HANDLING PLATFORM SPECIFIC CODE WITH DI
IShareService shareService = DependencyService.Get<IShareService>();Container.RegisterInstance<IShareService>(shareService);
• With a traditional dependency injection approach, you have first to get a reference to the platform specific service and then register it into the DI container
• Prism automatically register every class tagged with the Dependency attribute inside the container, so you can just use it in your ViewModels
private readonly IShareService _shareService;
public MainPageViewModel(IShareService shareService){ _shareService = shareService;}
DEMOPlatform specific code with DI
REFERENCES
• Slides: https://doc.co/P2VavL • Samples: https://github.com/qmatteoq/XamarinForms-Prism
• Prism: https://github.com/PrismLibrary/• Templates for Prism:
https://marketplace.visualstudio.com/items?itemName=BrianLagunas.PrismTemplatePack
• Blog posts with more detailed info about Prism: http://blog.qmatteoq.com/tag/prism/
• Blog posts to learn more about MVVM: http://blog.qmatteoq.com/the-mvvm-pattern-introduction/
• MVA course about Xamarin Forms: https://aka.ms/xamarin-forms-mva
Q & AMatteo PaganiWindows AppConsult Engineer @ [email protected]: @qmatteoq
MILAN 25-26 NOVEMBER 2016