Chcecie napisać aplikacje mobilną? Pokażę wam jak to zrobić w Xamarin Forms razem z MVVMLight

Posted by Maciej Gos on Tuesday, January 31, 2017

TOC

Witajcie cześć i czołem pytacie skąd się wziąłem… A na imię mi Xamarin Forms razem z MVVMLight i pokrótce chciałbym wam pokazać jak łatwo można użyć wzorca Model-View-ViewModel w aplikacji mobilnej.

Instalacja MVVMLight

MVVMLight jest pakietem NuGet, który może pobrać używając konsoli NuGet Package Manager Console.

W tym celu w naszej aplikacji należy otworzyć konsolę NuGet Package Manager w Visual Studio, szukam pakietu MvvmLightLibs i instalujemy go w naszych wszystkich projektach.

Konfiguracja kontenera Inversion Of Control

Na początek czeka nas odrobina konfiguracji naszego nowego projektu. Na razie konfiguracja kontenera IoC wygląda na nadmiarową pracę ale zapewniam was, że później to zaprocentuje w postaci łatwego przełączania się pomiędzy kodem „produkcyjnym” i „mock”.

Na początek stwórzmy prosty ViewModel o nazwie MainViewModel, który będzie korzystał z interfejsu IAccountService.

MainViewModel

[code lang=”csharp”]
using Client_BankOfSanEscobar.Interfaces;
using Client_BankOfSanEscobar.Models;
using GalaSoft.MvvmLight;
using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;

namespace Client_BankOfSanEscobar.ViewModels
{
public class MainViewModel : ViewModelBase
{
private readonly IAccountService accountService;

public string Title { get; set; }
public ObservableCollection Accounts { get; set; }
public float AvailableBalance { get; set; }

public MainViewModel(IAccountService accountService)
{
if (accountService == null)
throw new ArgumentNullException(“accontService”);

this.accountService = accountService;

Task.Run(() => Init());
}

public async Task Init()
{
if (Accounts != null)
return;

Accounts = new ObservableCollection(await accountService.GetAll());
foreach (var balance in Accounts.Select(a => a.Balance))
AvailableBalance += balance;
}
}
}
[/code]

Teraz stwórzmy interfejs IAccountService

IAccountService

[code lang=”csharp”]
using Client_BankOfSanEscobar.Models;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace Client_BankOfSanEscobar.Interfaces
{
public interface IAccountService
{
Task<IEnumerable> GetAll();
}
}
[/code]

oraz jego implementację w postaci obiektu „mock”

AccountServiceMock

[code lang=”csharp”]
using Client_BankOfSanEscobar.Interfaces;
using Client_BankOfSanEscobar.Models;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace Client_BankOfSanEscobar.Mock
{
public class AccountServiceMock : IAccountService
{
public Task<IEnumerable> GetAll()
{
const int numberOfAccountsToGenerate = 4;
return Task.Run(() => GenerateAccounts(numberOfAccountsToGenerate));
}

private IEnumerable GenerateAccounts(int numberOfAccounts)
{
var accounts = new List(numberOfAccounts);
for (int i = 0; i < numberOfAccounts; i++)
{
accounts.Add(new Account(name: $“Account {i}”, number: $“26200400001545234{i}”, balance: 150.56f + i));
}
return accounts;
}
}
}
[/code]

Uff prawie dobrnęliśmy do końca jeszcze tylko….Konfiguracja kontenera IoC.

W naszym kodzie użyjemy myśli technologicznej firmy Microsoft w postaci ServiceLocator, a implementacja wygląda następująco. Niektórzy twierdzą, że jest fajny The Service Locator Pattern, a inni twierdzą, że nie Antywzrorzec Service Locator.

Locator

[code lang=”csharp”]
using Client_BankOfSanEscobar.Interfaces;
using Client_BankOfSanEscobar.Mock;
using Client_BankOfSanEscobar.ViewModels;
using GalaSoft.MvvmLight.Ioc;
using Microsoft.Practices.ServiceLocation;

namespace Client_BankOfSanEscobar
{
public class Locator
{
public Locator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);

//ViewModels
SimpleIoc.Default.Register();

//Services
SimpleIoc.Default.Register<IAccountService, AccountServiceMock>();
}

public MainViewModel Main
{
get
{
return ServiceLocator.Current.GetInstance();
}
}
}
}
[/code]

Musimy jeszcze zainicjować nasz Locator możemy to zrobić w klasie App.cs

App

[code lang=”csharp”]
using Xamarin.Forms;

namespace Client_BankOfSanEscobar
{
public partial class App : Application
{
private static readonly Locator locator = new Locator();

public static Locator Locator
{
get
{
return locator;
}
}

public App()
{
InitializeComponent();

MainPage = new Views.MainPage();
}
}
}
[/code]

Cała konfiguracja i robota papierkowa za nami teraz możemy dojść do mięcha.

Binding ViewModel do UI

A więc żeby użyć naszego nowego pachnącego ViewModel należy go „podłączyć” do naszego widoku. Robimy to poprzez odpowiednie skonfigurowanie BindingContext.

[code lang=”csharp”]
public MainPage()
{
InitializeComponent();
BindingContext = App.Locator.Main;
}
[/code]

Podsumowanie

A więc jak widzicie użycie MVVMLight i Xamarin Forms jest możliwe. Na początku konfiguracja i powiązanie wszystkiego zajmuje trochę czasu ale w przyszłości będzie miało to plusy. Cały kod źródłowy możecie znaleźć na GitHub

Maciej Gos

真诚赞赏,手留余香

使用微信扫描二维码完成支付


comments powered by Disqus