63
Patterns for reusing .NET skills and code for iOS, Android and Windows Apps Vincent Hoogendoorn twitter.com/ vincenth_net Sander Egberink

Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

  • Upload
    others

  • View
    6

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

Patterns for reusing .NET skills and code for

iOS, Android and Windows Apps

Vincent Hoogendoorn twitter.com/vincenth_net

Sander Egberink

Page 2: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

Agenda

- Introduction

- Demo and code FlyBy BCC App

- MVP+

- MVVM+

- Pattern Comparison

- Next Steps, Resources, Questions

Page 3: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

IntroductionOngoing research goal:

“Optimise reuse of .NET code and skills when building native Apps for iOS,

Android, Windows Store and Windows Phone.”

Case App: BCC Veiling – Responsive Design, Azure, SignalR, Complex

Authentication, clients for Mobile Web, iOS, Android and Windows Store

V1: MVP+; in stores.

V2: MVVM+; almost done.

Spoiler: MVVM+ lets a non-mobile .NET developer write most code for you

Page 4: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

Demo – BCC App

Page 5: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

FlyBy – All the code you need to add 2nd+

platform…

With MVVM+

Page 6: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

MVP+ - Overview

Model• Entities (POCOs)

public class Lot{

public int Id { get; set; }public string AuctionTitle { get; set; }public string Title { get; set; }public string Info { get; set; }}

public class LotUpdate{

public decimal ProgressRemaining { get; set; }public decimal CurrentPrice { get; set; }public RemainingTime TimeRemaining { get; set; }

}

Page 7: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

MVP+ - Overview

Presenter• Properties

• INotifyPropertyChanged

implemented

Model• Entities (POCOs)

public Lot ActiveLot{

get { return _activeLot; }set {

_activeLot = value;NotifyPropertyChanged("ActiveLot"); }

}

public List<Lot> ProductsList{

get { return _productsList; }set {

_productsList = value;NotifyPropertyChanged("ProductsList"); }

}

public event PropertyChangedEventHandlerPropertyChanged;

Page 8: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

MVP+ - Overview

Presenter• Properties

• INotifyPropertyChanged

implemented

Model• Entities (POCOs)

ServiceAgent• Service Methods

• Service Events

• Connection Management

private SignalRConnectionResponseInitialSignalRConnect(){

connection = newHubConnection(serviceInfo.SignalRRootUrl);

proxy = connection.CreateProxy(serviceInfo.SignalRHubName);

proxy.On<Lot>("auctionInitialized", HandleAuctionInitialized);}

private void HandleAuctionInitialized(Lot lot){ MainModel.Current.ActiveLot = lot; }

public void InvokePlaceBid(int lotId, decimallotCurrentPrice){

proxy.Invoke("PlaceBid", new object[] { lotId, lotCurrentPrice });

}

Page 9: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

MVP+ - Overview

Presenter• Properties

• INotifyPropertyChanged

implemented

Model• Entities (POCOs)

ServiceAgent• Service Methods

• Service Events

• Connection Management

View• Markup

• Data binding code

(if not supported in markup)

• UI Manipulation Code

Entry

Point

ServiceAgent.Current.InitiateConnection();

Presenter.Current.PropertyChanged += OnCurrentChanged;private void OnCurrentChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)

{if (e.PropertyName == "ActiveLot"){

Activity.RunOnUiThread(delegate{

FullUIUpdate(); });

}}

private void FullUIUpdate(){

currentProductHeader.Text = Presenter.Current.ActiveLot.Title;

regularStorePrice.Text = Presenter.Current.ActiveLot.RegularPrice.ToString("C");

Page 10: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

MVP+ – Application Startup

Presenter• Properties

• INotifyPropertyChanged

implemented

Model• Entities (POCOs)

ServiceAgent• Service Methods

• Service Events

• Connection Management

View• Markup

• Data binding code

(if not supported in markup)

• UI Manipulation Code

Entry

Point

1) Application starts Initial View

2) View calls Service agent constructor which establishes connection

3) ServiceAgent requests initial data and sets listeners for updates

4) ServiceAgent receives data and passes it to the Presenter

5) Presenter’s properties are INotifyPropertyChanged – Being set by

the ServiceAgent raises the event which is caught by View, which

subsequently updates the UI.1

2 3

4

5

Page 11: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

MVP+ - Ordering a product

Presenter• Properties

• INotifyPropertyChanged

implemented

Model• Entities (POCOs)

ServiceAgent• Service Methods

• Service Events

• Connection Management

View• Markup

• Data binding code

(if not supported in markup)

• UI Manipulation Code

Entry

Point

ServiceAgent.Current.InvokePlaceBid(Presenter.Current.ActiveLot.Id, Presenter.Current.ActiveLot.UpdateInformation.CurrentPrice);

Page 12: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

MVP+ - Ordering a product

Presenter• Properties

• INotifyPropertyChanged

implemented

Model• Entities (POCOs)

ServiceAgent• Service Methods

• Service Events

• Connection Management

View• Markup

• Data binding code

(if not supported in markup)

• UI Manipulation Code

Entry

Point

public void InvokePlaceBid(int lotId, decimallotCurrentPrice){

proxy.Invoke("PlaceBid", new object[] { lotId, lotCurrentPrice });

}

proxy.On<Lot>("BidPlaced", BidPlaced);proxy.On("BidFailed", BidFailed);proxy.On("BidFailedOnAuthentication",

BidFailedOnAuthentication);

proxy.On("BidCancelled", BidCancelled);proxy.On("CancelBidFailed", CancelBidFailed);

Page 13: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

MVP+ - Ordering a product

Presenter• Properties

• INotifyPropertyChanged

implemented

Model• Entities (POCOs)

ServiceAgent• Service Methods

• Service Events

• Connection Management

View• Markup

• Data binding code

(if not supported in markup)

• UI Manipulation Code

Entry

Point

private void BidPlaced(Lot reservedLot){

Presenter.Current.ReservedLot = reservedLot;}

Page 14: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

MVP+ - Ordering a product

Presenter• Properties

• INotifyPropertyChanged

implemented

Model• Entities (POCOs)

ServiceAgent• Service Methods

• Service Events

• Connection Management

View• Markup

• Data binding code

(if not supported in markup)

• UI Manipulation Code

Entry

Point

private Lot _reservedLot;public Lot ReservedLot{

get { return _reservedLot; }set {

_reservedLot = value;NotifyPropertyChanged("ReservedLot");

}}

public event PropertyChangedEventHandlerPropertyChanged;

private void NotifyPropertyChanged(string propertyName){

var eventHandler = PropertyChanged;if (eventHandler != null) {

eventHandler(this, newPropertyChangedEventArgs(propertyName));

}}

Page 15: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

MVP+ - Ordering a product

Presenter• Properties

• INotifyPropertyChanged

implemented

Model• Entities (POCOs)

ServiceAgent• Service Methods

• Service Events

• Connection Management

View• Markup

• Data binding code

(if not supported in markup)

• UI Manipulation Code

Entry

Point

Presenter.Current.PropertyChanged += OnCurrentChanged;

private void OnCurrentChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e){if (e.PropertyName == "ReservedLot"){if (null != Presenter.Current.ReservedLot)

{ Activity.RunOnUiThread(delegate{ BuyLot(); }); }}}}

private void BuyLot(){if (null != Presenter.Current.ReservedLot){Intent i = new Intent(Activity,

typeof(FinalizeOrderActivity));StartActivity(i);}

}

Page 16: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

MVP+ – Shared Code

Presenter• Properties

• INotifyPropertyChanged

implemented

Model• Entities (POCOs)

ServiceAgent• Service Methods

• Service Events

• Connection Management

- Entities

- Application-wide Model

(through presenter)

- Application-wide Model

change events

- Service Agent

- Business Logic

Page 17: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

MVVM+ ViewModel Properties

ViewModel• Properties

• Commands

• INotifyPropertyChanged,

INotifyCollectionChanged

public decimal ActiveLotCurrentPrice{

get { return _activeLotCurrentPrice; }set{

_activeLotCurrentPrice = value;PropChanged("ActiveLotCurrentPrice");

}}

public bool SigninButtonIsAvailable{

get{

return !_auctionApplication.IsUserLoggedIn();}

}

Page 18: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

MVVM+ ViewModel Commands

ViewModel• Properties

• Commands

• INotifyPropertyChanged,

INotifyCollectionChanged

public RelayCommand PlaceBidCommand{ get; private set; }

private void WireupCommands(){

PlaceBidCommand = new RelayCommand(PlaceBid);PlaceBidCommand.IsEnabled = true;…

}

private void PlaceBid(){

ShowReasonForRejection = false;var placeBidRequest = new PlaceBidRequest{

LotId = ActiveLotId,Price = ActiveLotCurrentPrice

};_auctionServiceAgent.RaisePlaceBidAsync(placeBidRequest);

}

Page 19: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

MVVM+ ViewModel Data Binding

ViewModel• Properties

• Commands

• INotifyPropertyChanged,

INotifyCollectionChanged

public abstract class ViewModelBase : INotifyPropertyChanged, INotifyCollectionChanged…protected void PropChanged(string propName){

RunOnUIThread(() => OnPropertyChanged(propName));}

public class AuctionViewModel : ViewModelBase…public DateTime AuctionStartsAt{

get { return _auctionStartsAt; }set{

_auctionStartsAt = value;PropChanged("AuctionStartsAt");

}}.

Page 20: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

MVVM+ View

ViewModel• Properties

• Commands

• INotifyPropertyChanged,

INotifyCollectionChanged

View• Markup

• Data binding code

(if not supported in markup)

• UI Manipulation Code

View development can start at the earliest right after a ViewModel has

its properties and commands defined, and an instance with hardcoded

design time data in the properties is available.

public class AuctionViewModelStub : AuctionViewModel{

public AuctionViewModelStub(){

// Set all base ViewModel properties to// hardcoded values, optionally with random// selection from multiple values or value sets.

}}

View development can start at the latest after all shared code has

been completed.

The View implementation is platform specific. Details for each

platform are shown later in this presentation.

Page 21: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

MVVM+ Model Entities

ViewModel• Properties

• Commands

• INotifyPropertyChanged,

INotifyCollectionChanged

Model• Entities (POCO)

View• Markup

• Data binding code

(if not supported in markup)

• UI Manipulation Code

public class ClientLotUpdate{

public decimal CurrentPrice { get; set; }public int ProgressRemaining { get; set; }public RemainingTime TimeRemaining { get; set; }

public ClientLotUpdate(){

TimeRemaining = new RemainingTime();}

}

Page 22: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

MVVM+ Service Entities

ViewModel• Properties

• Commands

• INotifyPropertyChanged,

INotifyCollectionChanged

ServiceAgent• Service Entities

• Service Events

• Service Methods

View• Markup

• Data binding code

(if not supported in markup)

• UI Manipulation Code

public class ClientLotUpdate{

public decimal CurrentPrice { get; set; }public int ProgressRemaining { get; set; }public RemainingTime TimeRemaining { get; set; }

public ClientLotUpdate(){

TimeRemaining = new RemainingTime();}

}

Note that in simple cases service entities defined in the service contract can be used directly as the ‘model’.

Page 23: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

MVVM+ Model ServiceAgent Events

ViewModel• Properties

• Commands

• INotifyPropertyChanged,

INotifyCollectionChanged

Model• Entities (POCO)

ServiceAgent• Service Entities

• Service Events

• Service Methods

View• Markup

• Data binding code

(if not supported in markup)

• UI Manipulation Code

public class LotUpdatedEventArgs : EventArgs{

public ClientLotUpdate clientLotUpdate { get; set; }}

public event EventHandler<LotUpdatedEventArgs> ActiveLotUpdated;

Page 24: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

MVVM+ Model ServiceAgent Methods

ViewModel• Properties

• Commands

• INotifyPropertyChanged,

INotifyCollectionChanged

Model• Entities (POCO)

ServiceAgent• Service Entities

• Service Events

• Service Methods

View• Markup

• Data binding code

(if not supported in markup)

• UI Manipulation Code

public class PlaceBidRequest{

public int LotId { get; set; }public decimal Price { get; set; }

}

public Task RaisePlaceBidAsync(PlaceBidRequestplaceBidRequest)

{return _hubProxy.Invoke(

"PlaceBid", new object[] { placeBidRequest });

}

Page 25: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

MVVM+ ViewModel use of Application

ViewModel• Properties

• Commands

• INotifyPropertyChanged,

INotifyCollectionChanged

Model• Entities (POCO)

ServiceAgent• Service Entities

• Service Events

• Service Methods

Application• ViewModels instance

• Navigation context

• Navigation transitions

View• Markup

• Data binding code

(if not supported in markup)

• UI Manipulation Code

public interface IAuctionApplication{

void ContinueToAuction();void ContinueToCheckout(Basket basket);void ContinueToOrderConfirmed();void ContinueToProductList();void ContinueToProductPage(ClientLot product);void UserWantsToSignIn();bool IsUserLoggedIn();

}

The ViewModel only uses the application to initiate navigation and to obtain relevant application state.

This is not available to ViewModels:

public interface IApplication<TNavigationContext>{

TNavigationContext CurrentNavigationContext { set; }TViewModel GetViewModel<TViewModel>();

}

Page 26: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

MVVM+ Application

ViewModel• Properties

• Commands

• INotifyPropertyChanged,

INotifyCollectionChanged

Model• Entities (POCO)

ServiceAgent• Service Entities

• Service Events

• Service Methods

Application• ViewModels instance

• Navigation context

• Navigation transitions

View• Markup

• Data binding code

(if not supported in markup)

• UI Manipulation Code

public class AuctionApplication<TNavigationContext> :IAuctionApplication,IApplication<TNavigationContext>

public void ContinueToCheckout(Basket basket, TNavigationContext navigationContext)

{CheckoutViewModel = new CheckoutViewModel(basket,_auctionServiceAgentBase, this, _taskScheduler);

RunOnUIThread(() =>_auctionNavigator.NavigateToCheckoutView(navigationContext)

);}

Application initializes viewmodel and then calls navigator for platform-specific view navigation.

Page 27: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

MVVM+ Application use of Navigator

ViewModel• Properties

• Commands

• INotifyPropertyChanged,

INotifyCollectionChanged

Model• Entities (POCO)

ServiceAgent• Service Entities

• Service Events

• Service Methods

Application• ViewModels instance

• Navigation context

• Navigation transitions

View• Markup

• Data binding code

(if not supported in markup)

• UI Manipulation Code

Navigator• Navigate to view

implementation

public interface IAuctionNavigator<TNavigationContext>{

void NavigateToSignInView(TNavigationContext c);void NavigateToAuctionView(TNavigationContext c);void NavigateToCheckoutView(TNavigationContext c);void NavigateToOrderConfirmed(TNavigationContext c);void NavigateToProductsView(TNavigationContext c);void NavigateToProductNotInAuctionView(

TNavigationContext navigationContext);}

The navigator implementation is platform specific (TNavigationContext)

Page 28: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

MVVM+ Application Entry Point for Windows

Store App

ViewModel• Properties

• Commands

• INotifyPropertyChanged,

INotifyCollectionChanged

Model• Entities (POCO)

ServiceAgent• Service Entities

• Service Events

• Service Methods

Application• ViewModels instance

• Navigation context

• Navigation transitions

View• Markup

• Data binding code

(if not supported in markup)

• UI Manipulation Code

Navigator• Navigate to view

implementation

Entry

Point

public static AuctionApplication<Frame> AuctionApplication { get; private set; }

private static void EntryPoint(){

var taskScheduler =TaskScheduler.FromCurrentSynchronizationContext();

AuctionApplication =await AuctionApplication<Frame>.GetInstance(

rootFrame, new AuctionNavigator(), taskScheduler

);

AuctionApplication.Start();}

The entry point is platform specific (TNavigationContext, here a WinRT Frame).

Page 29: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

MVVM+ Navigator for Windows Store App

ViewModel• Properties

• Commands

• INotifyPropertyChanged,

INotifyCollectionChanged

Model• Entities (POCO)

ServiceAgent• Service Entities

• Service Events

• Service Methods

Application• ViewModels instance

• Navigation context

• Navigation transitions

View• Markup

• Data binding code

(if not supported in markup)

• UI Manipulation Code

Navigator• Navigate to view

implementation

Entry

Point

public class AuctionNavigator : IAuctionNavigator<Frame>{

public void NavigateToAuctionView(Frame navigationContext)

{navigationContext.Navigate(typeof(AuctionPage));

}

public async void NavigateToOrderConfirmed(Frame navigationContext)

{var dialog = newWindows.UI.Popups.MessageDialog(“Message");await dialog.ShowAsync();NavigateToAuctionView(navigationContext);

}…

}

The navigator is platform specific (TNavigationContext, here a WinRT Frame).

Page 30: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

MVVM+ View for Windows Store App – Data

Binding

ViewModel• Properties

• Commands

• INotifyPropertyChanged,

INotifyCollectionChanged

Model• Entities (POCO)

ServiceAgent• Service Entities

• Service Events

• Service Methods

Application• ViewModels instance

• Navigation context

• Navigation transitions

View• Markup

• Data binding code

(if not supported in markup)

• UI Manipulation Code

Navigator• Navigate to view

implementation

Entry

Point

<local:CheckoutViewBasex:Class="MobileAuction.W8.Views.CheckoutView"xmlns:local="using:MobileAuction.W8.Views“d:DataContext="{d:DesignInstance

IsDesignTimeCreatable=True,Type=shared:CheckoutViewModelStub}"

<TextBox x:Name="txtVoornaam“Text="{Binding FirstName, Mode=TwoWay}" />

public class Page<TViewModel> : Page{

protected Page(IApplication<Frame> application){

if (application != null) DataContext =application.GetViewModel<TViewModel>();

}}

Note: both design-time and runtime data is supported.

Page 31: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

MVVM+ View for Windows Store App – C#

ViewModel• Properties

• Commands

• INotifyPropertyChanged,

INotifyCollectionChanged

Model• Entities (POCO)

ServiceAgent• Service Entities

• Service Events

• Service Methods

Application• ViewModels instance

• Navigation context

• Navigation transitions

View• Markup

• Data binding code

(if not supported in markup)

• UI Manipulation Code

Navigator• Navigate to view

implementation

Entry

Point

<local:CheckoutViewBasex:Class="MobileAuction.W8.Views.CheckoutView"xmlns:local="using:MobileAuction.W8.Views“d:DataContext="{d:DesignInstance

IsDesignTimeCreatable=True,Type=shared:CheckoutViewModelStub}"

// This class can be eliminated once the x:TypeArguments // attribute is supported in XAML:// http://stackoverflow.com/questions/14478469/windows-8-store-application-support-for-xtypearguments

public abstract class CheckoutViewBase :Mobile.Presentation.W8.Page<

MobileAuction.Shared.CheckoutViewModel>{

public CheckoutViewBase() :base(App.AuctionApplication) { }

}

Page 32: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

MVVM+ Navigator for Android

ViewModel• Properties

• Commands

• INotifyPropertyChanged,

INotifyCollectionChanged

Model• Entities (POCO)

ServiceAgent• Service Entities

• Service Events

• Service Methods

Application• ViewModels instance

• Navigation context

• Navigation transitions

View• Markup

• Data binding code

(if not supported in markup)

• UI Manipulation Code

Navigator• Navigate to view

implementation

Entry

Point

public class AuctionNavigator : IAuctionNavigator<Activity>

{

public void NavigateToCheckoutView(ActivitynavigationContext)

{Intent i = new Intent(navigationContext,

typeof(CheckoutActivity));navigationContext.StartActivity(i);

}

public void NavigateToAuctionView(ActivitynavigationContext)

{Intent i = new Intent(navigationContext,

typeof(HomeActivity));navigationContext.StartActivity(i);

}

Page 33: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

MVVM+ View for Android

ViewModel• Properties

• Commands

• INotifyPropertyChanged,

INotifyCollectionChanged

Model• Entities (POCO)

ServiceAgent• Service Entities

• Service Events

• Service Methods

Application• ViewModels instance

• Navigation context

• Navigation transitions

View• Markup

• Data binding code

(if not supported in markup)

• UI Manipulation Code

Navigator• Navigate to view

implementation

Entry

Point

public class Activity<TActivity, TViewModel> : global::Android.Support.V4.App.Activity,

IView<TViewModel> where TActivity : Activity<TActivity, TViewModel>

where TViewModel : INotifyPropertyChanged{

public TViewModel ViewModel { get; set; }

public override void OnCreate(BundlesavedInstanceState)

{base.OnCreate(savedInstanceState);ViewModel =

AuctionApplication<Activity>.GetInstance().GetViewModel<TViewModel>(); }}

Page 34: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

MVVM+ View for Android

ViewModel• Properties

• Commands

• INotifyPropertyChanged,

INotifyCollectionChanged

Model• Entities (POCO)

ServiceAgent• Service Entities

• Service Events

• Service Methods

Application• ViewModels instance

• Navigation context

• Navigation transitions

View• Markup

• Data binding code

(if not supported in markup)

• UI Manipulation Code

Navigator• Navigate to view

implementation

Entry

Point

public class SplashScreen : Activity{

protected override void OnCreate(BundlesavedInstanceState)

{base.OnCreate(savedInstanceState);

AuctionApplication<Activity>.GetInstance(this, newAuctionNavigator(), TaskScheduler.FromCurrentSynchronizationContext()).Start(); }}

Note: The initial definition of the AuctionApplication in a view is also the Entry Point

Page 35: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

MVVM+ Navigator for iOS

ViewModel• Properties

• Commands

• INotifyPropertyChanged,

INotifyCollectionChanged

Model• Entities (POCO)

ServiceAgent• Service Entities

• Service Events

• Service Methods

Application• ViewModels instance

• Navigation context

• Navigation transitions

View• Markup

• Data binding code

(if not supported in markup)

• UI Manipulation Code

Navigator• Navigate to view

implementation

Entry

Point

public class AuctionNavigator : IAuctionNavigator<UIViewController>

{

public void NavigateToCheckoutView(UIViewController context)

{CheckoutViewController checkoutView =

context.Storyboard.InstantiateViewController ("CheckoutViewController")

as CheckoutViewController;context.NavigationController.PushViewController(checkoutView, false);}

public void NavigateToAuctionView(UIViewController context){context.NavigationController.PopToRootViewController (false);}

}

Page 36: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

MVVM+ View for iOS

ViewModel• Properties

• Commands

• INotifyPropertyChanged,

INotifyCollectionChanged

Model• Entities (POCO)

ServiceAgent• Service Entities

• Service Events

• Service Methods

Application• ViewModels instance

• Navigation context

• Navigation transitions

View• Markup

• Data binding code

(if not supported in markup)

• UI Manipulation Code

Navigator• Navigate to view

implementation

Entry

Point

public partial class ViewController<TViewController, TViewModel> : UIViewController, IView<TViewModel>

where TViewController: ViewController<TViewController, TViewModel>

where TViewModel : INotifyPropertyChanged{

public TViewModel ViewModel { get; set; }

public override void ViewDidLoad (){

ViewModel = AuctionApplication<UIViewController>.GetInstance ().GetViewModel<TViewModel> ();

base.ViewDidLoad ();}

}

Page 37: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

MVVM+ View for iOS

ViewModel• Properties

• Commands

• INotifyPropertyChanged,

INotifyCollectionChanged

Model• Entities (POCO)

ServiceAgent• Service Entities

• Service Events

• Service Methods

Application• ViewModels instance

• Navigation context

• Navigation transitions

View• Markup

• Data binding code

(if not supported in markup)

• UI Manipulation Code

Navigator• Navigate to view

implementation

Entry

Point

public partial class AuctionViewController : ViewController<AuctionViewController, AuctionViewModel>{

public AuctionViewController (IntPtr handle) : base(handle)

{InvokeOnMainThread (delegate {

AuctionApplication<UIViewController>.GetInstance (this, new AuctionNavigator (),

TaskScheduler.FromCurrentSynchronizationContext ()).Start ();});

}}

Note: The initial definition of the AuctionApplication in a view is also the Entry Point

Page 38: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

MVVM – Composite ViewModels

ViewModel• Properties

• Commands

• INotifyPropertyChanged,

INotifyCollectionChanged

View• Markup

• Data binding code

(if not supported in markup)

• UI Manipulation Code

ViewModel• Properties

• Commands

• INotifyPropertyChanged,

INotifyCollectionChanged

ViewModel• Properties

• Commands

• INotifyPropertyChanged,

INotifyCollectionChanged

Page 39: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

MVVM – Composite ViewModels Android

Page 40: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

MVVM – Composite ViewModels Android

public class AuctionFragment : Fragment<AuctionFragment, AuctionViewModel>{

}

public class AuctionFragment : Fragment<AuctionFragment, AuctionViewModel>{

}

public class Fragment<TFragment, TViewModel> : global::Android.Support.V4.App.Fragment, IView<TViewModel> where TFragment : Fragment<TFragment, TViewModel>

where TViewModel : INotifyPropertyChanged{

public TViewModel ViewModel { get; set; }

public override void OnCreate(Bundle savedInstanceState){

base.OnCreate(savedInstanceState);ViewModel = AuctionApplication<Activity>.GetInstance().GetViewModel<TViewModel>(); }

}

Page 41: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

MVVM – Composite ViewModels Android

<LinearLayoutandroid:orientation="vertical"android:layout_width=“fill_parent"android:layout_height="fill_parent"android:background="@color/white">

<fragment class="mobile.android.ProductListFragment"android:layout_width=“0dip"android:layout_height="match_parent"android:layout_weight="0.5"/>

<fragment class="mobile.android.ProductListFragment"android:layout_width=“0dip"android:layout_height="match_parent"android:layout_weight="0.5"/>

</LinearLayout>

Page 42: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

MVVM – Composite ViewModels iOS

Page 43: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

MVVM – Composite ViewModels iOS

public partial class AuctionViewController : ViewController<AuctionViewController, AuctionViewModel>{

}

public partial class ProductListController : DialogViewController<ProductListController, ProductsViewModel>{

}

public partial class ViewController<TViewController, TViewModel> : UIViewController, IView<TViewModel>where TViewController: ViewController<TViewController, TViewModel>

where TViewModel : INotifyPropertyChanged{

public TViewModel ViewModel { get; set; }

public override void ViewDidLoad (){

ViewModel = AuctionApplication<UIViewController>.GetInstance ().GetViewModel<TViewModel> ();base.ViewDidLoad ();

}}

Page 44: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

MVVM – Composite ViewModels iOSAuctionViewController auctionViewController =

UIStoryboard.FromName ("MainStoryboard_iPad", null).InstantiateViewController("AuctionViewController")as AuctionViewController;

AuctionApplication<UIViewController>.GetInstance ().CurrentNavigationContext = this;

UIViewController productsViewController = UIStoryboard.FromName ("MainStoryboard_iPad", null).InstantiateViewController

("ProductListViewController") as UIViewController;

RectangleF rect = this.View.Bounds;rect.Width = rect.Width / 2;

UIView auctionView = auctionViewController.View;auctionView.Frame = new RectangleF (new PointF (0, 0), new SizeF (this.View.Bounds.Width / 2,

this.View.Bounds.Height));

UIView aboutView = productsViewController.View;aboutView.Frame = new RectangleF (new PointF (this.View.Bounds.Width / 2, 0), new SizeF

(this.View.Bounds.Width / 2, this.View.Bounds.Height));

this.View.AddSubviews (new UIView[] { auctionView, aboutView });

this.AddChildViewController (auctionViewController);this.AddChildViewController (productsViewController);

Page 45: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

Demo: Windows Store App Composite

ViewModels – Design time

Page 46: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

Demo: Windows Store App Composite

ViewModels – Design time

Page 47: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

Demo: Windows Store App Composite

ViewModels - Runtime

Page 48: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

MVVM+ Composite View for Windows Store App

– C#

ViewModel• Properties

• Commands

• INotifyPropertyChanged,

INotifyCollectionChanged

Model• Entities (POCO)

ServiceAgent• Service Entities

• Service Events

• Service Methods

Application• ViewModels instance

• Navigation context

• Navigation transitions

View• Markup

• Data binding code

(if not supported in markup)

• UI Manipulation Code

Navigator• Navigate to view

implementation

Entry

Point

public class UserControl<TViewModel> : UserControl{

protected UserControl(IApplication<Frame> application)

{ if (application != null) DataContext =application.GetViewModel<TViewModel>(); }

}

// This class can be eliminated once the x:TypeArguments attribute is supported in XAML: http://stackoverflow.com/questions/14478469/windows-8-store-application-support-for-xtypeargumentspublic abstract class AuctionViewBase :

Mobile.Presentation.W8.UserControl<MobileAuction.Shared.AuctionViewModel>

{public AuctionViewBase() :

base(App.AuctionApplication) { }}

Page 49: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

MVVM+ Composite View for Windows Store App

- XAML

ViewModel• Properties

• Commands

• INotifyPropertyChanged,

INotifyCollectionChanged

Model• Entities (POCO)

ServiceAgent• Service Entities

• Service Events

• Service Methods

Application• ViewModels instance

• Navigation context

• Navigation transitions

View• Markup

• Data binding code

(if not supported in markup)

• UI Manipulation Code

Navigator• Navigate to view

implementation

Entry

Point

<local:AuctionViewBasex:Class="MobileAuction.W8.Views.AuctionView“d:DataContext="{d:DesignInstanceIsDesignTimeCreatable=True,Type=shared:AuctionViewModelStub}"…

<local:ProductsViewBasex:Class="MobileAuction.W8.Views.ProductsView“d:DataContext="{d:DesignInstanceIsDesignTimeCreatable=True,Type=shared:ProductsViewModelStub}"…

<views:AuctionView d:DataContext="{d:DesignInstanceIsDesignTimeCreatable=True,Type=shared:AuctionViewModelStub}" /><views:ProductsView d:DataContext="{d:DesignInstanceIsDesignTimeCreatable=True,Type=shared:ProductsViewModelStub}" />

Page 50: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

MVVM+ Runtime flow

ViewModel• Properties

• Commands

• INotifyPropertyChanged,

INotifyCollectionChanged

Model• Entities (POCO)

ServiceAgent• Service Entities

• Service Events

• Service Methods

Application• ViewModels instance

• Navigation context

• Navigation transitions

View• Markup

• Data binding code

(if not supported in markup)

• UI Manipulation Code

Navigator• Navigate to view

implementation

Entry

Point

Runtime flow: Application starts with AuctionView, user places bid and navigates to CheckoutView.1. Entrypoint is called, creates Application instance

and calls Application.Start().

1

Page 51: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

MVVM+ Runtime flow

ViewModel• Properties

• Commands

• INotifyPropertyChanged,

INotifyCollectionChanged

Model• Entities (POCO)

ServiceAgent• Service Entities

• Service Events

• Service Methods

Application• ViewModels instance

• Navigation context

• Navigation transitions

View• Markup

• Data binding code

(if not supported in markup)

• UI Manipulation Code

Navigator• Navigate to view

implementation

Entry

Point

Runtime flow: Application starts with AuctionView, user places bid and navigates to CheckoutView.1. Entrypoint is called, creates Application instance

and calls Application.Start().2. Application ctor creates ServiceAgent

Start() creates AuctionViewModel + ProductsViewModel

1

2

2

Page 52: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

MVVM+ Runtime flow

ViewModel• Properties

• Commands

• INotifyPropertyChanged,

INotifyCollectionChanged

Model• Entities (POCO)

ServiceAgent• Service Entities

• Service Events

• Service Methods

Application• ViewModels instance

• Navigation context

• Navigation transitions

View• Markup

• Data binding code

(if not supported in markup)

• UI Manipulation Code

Navigator• Navigate to view

implementation

Entry

Point

Runtime flow: Application starts with AuctionView, user places bid and navigates to CheckoutView.1. Entrypoint is called, creates Application instance

and calls Application.Start().2. Application ctor creates ServiceAgent

Start() creates AuctionViewModel + ProductsViewModel3. Application calls

_auctionNavigator.NavigateToAuctionView()

1

2

3

2

Page 53: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

MVVM+ Runtime flow

ViewModel• Properties

• Commands

• INotifyPropertyChanged,

INotifyCollectionChanged

Model• Entities (POCO)

ServiceAgent• Service Entities

• Service Events

• Service Methods

Application• ViewModels instance

• Navigation context

• Navigation transitions

View• Markup

• Data binding code

(if not supported in markup)

• UI Manipulation Code

Navigator• Navigate to view

implementation

Entry

Point

Runtime flow: Application starts with AuctionView, user places bid and navigates to CheckoutView.1. Entrypoint is called, creates Application instance

and calls Application.Start().2. Application ctor creates ServiceAgent

Start() creates AuctionViewModel + ProductsViewModel3. Application calls

_auctionNavigator.NavigateToAuctionView()4. Navigator calls platform-specific navigate to

AuctionView

1

2

3

4

2

Page 54: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

MVVM+ Runtime flow

ViewModel• Properties

• Commands

• INotifyPropertyChanged,

INotifyCollectionChanged

Model• Entities (POCO)

ServiceAgent• Service Entities

• Service Events

• Service Methods

Application• ViewModels instance

• Navigation context

• Navigation transitions

View• Markup

• Data binding code

(if not supported in markup)

• UI Manipulation Code

Navigator• Navigate to view

implementation

Entry

Point

Runtime flow: Application starts with AuctionView, user places bid and navigates to CheckoutView.1. Entrypoint is called, creates Application instance

and calls Application.Start().2. Application ctor creates ServiceAgent

Start() creates AuctionViewModel + ProductsViewModel3. Application calls

_auctionNavigator.NavigateToAuctionView()4. Navigator calls platform-specific navigate to

AuctionView5. View base class gets ViewModel from Application1

2

3

4

5

2

Page 55: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

MVVM+ Runtime flow

ViewModel• Properties

• Commands

• INotifyPropertyChanged,

INotifyCollectionChanged

Model• Entities (POCO)

ServiceAgent• Service Entities

• Service Events

• Service Methods

Application• ViewModels instance

• Navigation context

• Navigation transitions

View• Markup

• Data binding code

(if not supported in markup)

• UI Manipulation Code

Navigator• Navigate to view

implementation

Entry

Point

Runtime flow: Application starts with AuctionView, user places bid and navigates to CheckoutView.1. Entrypoint is called, creates Application instance

and calls Application.Start().2. Application ctor creates ServiceAgent

Start() creates AuctionViewModel + ProductsViewModel3. Application calls

_auctionNavigator.NavigateToAuctionView()4. Navigator calls platform-specific navigate to

AuctionView5. View base class gets ViewModel from Application6. On platforms without native data binding, the view

subscribes itself to PropertyChanged and CollectionChanged on ViewModel, for select (groups of) properties (it is not necessary to bind to each individual property). Also the commands of the views are invoked from code in an event handler.

1

2

3

4

5 6

2

Page 56: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

MVVM+ Runtime flow

ViewModel• Properties

• Commands

• INotifyPropertyChanged,

INotifyCollectionChanged

Model• Entities (POCO)

ServiceAgent• Service Entities

• Service Events

• Service Methods

Application• ViewModels instance

• Navigation context

• Navigation transitions

View• Markup

• Data binding code

(if not supported in markup)

• UI Manipulation Code

Navigator• Navigate to view

implementation

Entry

Point

Runtime flow: Application starts with AuctionView, user places bid and navigates to CheckoutView.1. Entrypoint is called, creates Application instance

and calls Application.Start().2. Application ctor creates ServiceAgent

Start() creates AuctionViewModel + ProductsViewModel3. Application calls

_auctionNavigator.NavigateToAuctionView()4. Navigator calls platform-specific navigate to

AuctionView5. View base class gets ViewModel from Application6. On platforms without native data binding, the view

subscribes itself to PropertyChanged and CollectionChanged on ViewModel, for select (groups of) properties (it is not necessary to bind to each individual property). Also the commands of the views are invoked from code in an event handler.

7. The viewmodel is updated by events from service and commands from view. The view updates w data binding.

1

2

3

4

5 6

72

Page 57: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

MVVM+ Runtime flow

ViewModel• Properties

• Commands

• INotifyPropertyChanged,

INotifyCollectionChanged

Model• Entities (POCO)

ServiceAgent• Service Entities

• Service Events

• Service Methods

Application• ViewModels instance

• Navigation context

• Navigation transitions

View• Markup

• Data binding code

(if not supported in markup)

• UI Manipulation Code

Navigator• Navigate to view

implementation

Entry

Point

Runtime flow: Application starts with AuctionView, user places bid and navigates to CheckoutView.1. Entrypoint is called, creates Application instance

and calls Application.Start().2. Application ctor creates ServiceAgent

Start() creates AuctionViewModel + ProductsViewModel3. Application calls

_auctionNavigator.NavigateToAuctionView()4. Navigator calls platform-specific navigate to

AuctionView5. View base class gets ViewModel from Application6. On platforms without native data binding, the view

subscribes itself to PropertyChanged and CollectionChanged on ViewModel, for select (groups of) properties (it is not necessary to bind to each individual property). Also the commands of the views are invoked from code in an event handler.

7. The viewmodel is updated by events from service and commands from view. The view updates w data binding.

8. A command on a viewmodel can invoke the ContinueTo… method on application … continue with step 3.

1

2

3

4

5 6

782

Page 58: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

MVVM+ Runtime flow

ViewModel• Properties

• Commands

• INotifyPropertyChanged,

INotifyCollectionChanged

Model• Entities (POCO)

ServiceAgent• Service Entities

• Service Events

• Service Methods

Application• ViewModels instance

• Navigation context

• Navigation transitions

View• Markup

• Data binding code

(if not supported in markup)

• UI Manipulation Code

Navigator• Navigate to view

implementation

Entry

Point

Runtime flow: Application starts with AuctionView, user places bid and navigates to CheckoutView.1. Entrypoint is called, creates Application instance

and calls Application.Start().2. Application ctor creates ServiceAgent

Start() creates AuctionViewModel + ProductsViewModel3. Application calls

_auctionNavigator.NavigateToAuctionView()4. Navigator calls platform-specific navigate to

AuctionView5. View base class gets ViewModel from Application6. On platforms without native data binding, the view

subscribes itself to PropertyChanged and CollectionChanged on ViewModel, for select (groups of) properties (it is not necessary to bind to each individual property). Also the commands of the views are invoked from code in an event handler.

7. The viewmodel is updated by events from service and commands from view. The view updates w data binding.

8. A command on a viewmodel can invoke the ContinueTo… method on application … continue with step 3.

1

2

3

4

5 6

782

Page 59: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

MVP+ Shared Code

Presenter• Properties

• INotifyPropertyChanged

implemented

Model• Entities (POCOs)

ServiceAgent• Service Methods

• Service Events

• Connection Management

MVVM+ Shared Code

ViewModel• Properties

• Commands

• INotifyPropertyChanged,

INotifyCollectionChanged

Model• Entities (POCO)

ServiceAgent• Service Entities

• Service Events

• Service Methods

Application• ViewModels instance

• Navigation context

• Navigation transitions

View• Markup

• Data binding code

(if not supported in markup)

• UI Manipulation Code

Navigator• Navigate to view

implementation

Entry

Point

View• Markup

• Data binding code

(if not supported in markup)

• UI Manipulation Code

• Navigation logic

Entry

Point

Pattern Comparison

Page 60: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

MVP+ Shared Code MVVM+ Shared Code

Presenter.Current.PropertyChanged += OnCurrentChanged;

private void OnCurrentChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e){if (e.PropertyName == "ReservedLot"){if (null != Presenter.Current.ReservedLot)

{ Activity.RunOnUiThread(delegate{ BuyLot(); }); }}}}

private void BuyLot(){if (null != Presenter.Current.ReservedLot){Intent i = new Intent(Activity,

typeof(FinalizeOrderActivity));StartActivity(i);}

}

View• Markup

• Data binding code

(if not supported in markup)

• UI Manipulation Code

ViewModel• Properties

• Commands

• INotifyPropertyChanged,

INotifyCollectionChanged

private void OnBidPlaced(object sender, BidPlacedEventArgs e){

if (e.PlaceBidResult.BidIsAccepted){

var lot = e.PlaceBidResult.Lot;var basket = new Basket{

// Basket Init code here};

_auctionApplication.ContinueToCheckout(basket);}public class AuctionNavigator :

IAuctionNavigator<Activity>{

public void NavigateToCheckoutView(ActivitynavigationContext)

{Intent i = new Intent(navigationContext,

typeof(CheckoutActivity));navigationContext.StartActivity(i);

}

Page 61: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

MVP+ Shared Code MVVM+ Shared Code

Android Specific

26%

Shared Code

74%

CODE SHARE

Android Specific

52%

Shared Code

48%

CODE SHARE

Page 62: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

Pro/Con of MVP+ versus MVVM+MVP+ MVVM+

Pro • Less total Code – esp for cases

where API matches view closely.

• Simpler pattern to apply

(write)

• First client by single developer takes

less time

• Higher % shared code

• Second cmeters to viewlient takes less

time

• Working application can be developed

by any .NET developer; no mobile

development tools, licenses, hardware,

skills needed.

(mobile devs are more scarse and more

expensive than.NET devs)

• Consistent behaviour across platforms

easer

• Application logic simpler to understand

(read)

• Fully unit testable

• Can pass complex objects as para

Con Inverse of MVVM+ Pro’s Inverse of MVP+ Pro’s

Page 63: Patterns for reusing .NET skills and code for iOS, Android and Windows Appsfiles.meetup.com/5083302/Patterns for reusing dot NET... · 2013-06-20 · • Data binding code (if not

Next Steps, Resources, QuestionsNext for MVVM+

• Optimize for less total LOC

• Possibly automation for repetitive development steps

(e.g. add a property)

• Possibly open source an example implementation.

Resources:

• http://stackoverflow.com/questions/2056/what-are-mvp-and-mvc-and-

what-is-the-difference

• http://propertycross.com/

• http://braincells2pixels.wordpress.com/2013/06/07/the-case-for-xamarin/

• http://vincenth.net

Questions?

[email protected]; for MVVM shared code questions: [email protected]