MVVM Light Toolkit – prosty framework MVVM dla Xamarin i Xamarin.Forms

Wcześniej pisałem już o dwóch frameworkach do MVVM – FreshMvvm i MvvmCross. Dzisiaj przyjrzę się możliwościom Mvvm Light Toolkit. Jest to jeden ze starszych i pewnie jeden z bardziej znanych frameworków do MVVM. Przed Xamarinem był częstym wyborem (przynajmniej moim, ale pewnie też wielu innych osób) w WPF i Windows Phone’ie.

Do zaprezentowania Mvvm Light stworzyłem, podobnie jak przy poprzednich frameworkach, prostą aplikację do budżetu i na jej podstawie będę opisywał funkcjonalności (link do kodu na końcu).

Funkcjonalności

Mvvm Light Toolkit to dość lekka biblioteka, podobnie jak FreshMvvm. Posiada tylko podstawowe funkcjonalności:

  • Zaimplementowane INotifyPropertyChanged w view modelach
  • Wbudowana implementacja ICommand – RelayCommand
  • Tryb designu
  • Wbudowany Messenger do wzorca publish/subscribe
  • Kontener IoC
  • Nawigacja i dialogi

Inicjalizacja

Paczka Mvvm Light jest dostępna na nugecie. Mamy do wyboru 2 wersje:

  • MvvmLight – dodaje do naszego projektu biblioteki oraz przykładowe pliki MainViewModel.cs i ViewModelLocator.cs, a do tego modyfikuje App.xaml.cs
  • MvvmLightLibs – dodaje do projektu tylko biblioteki i nic automatycznie nie zmienia (jak paczka powyżej)

Ja zawsze korzystam z drugiej paczki – ustawienie projektu jest proste i do tego w Formsach robię to trochę inaczej niż skrypt z nugeta.

Standardowo, w Mvvm Light używamy klasy nazwanej ViewModelLocator, w której rejestrujemy wszystkie view modele i usługi.

Później, żeby mieć dostęp do ViewModelLocatora, tworzymy jego instancję w klasie App.xaml.cs:

Dodajemy ją również do Resources, żeby mieć wygodny dostęp z xamla. To tyle, jeśli chodzi o wstępną konfigurację.

ViewModele

W view modelach mamy zaimplementowany INotifyPropertyChanged i możemy informować widoki o zmianach metodą RaisePropertyChanged. W zasadzie poza tym jest niewiele więcej. Nie ma tu dostępnych, tak jak w innych frameworkach, metod wywoływanych przy pokazywaniu/ukrywaniu widoku, czy nawigacji między view modelami z przekazywaniem parametrów. Mamy tu tylko niezbędne minimum.

RelayCommand

Do komend mamy wbudowaną implementację interfejsu ICommand – RelayCommand:

Możemy używać zwykłych komend lub z parametrem. Parametr dostępny jest tylko jeden, jeśli musimy przekazać coś więcej, to trzeba to opakować w jakiś obiekt.

Tryb designu

Design Mode to całkiem ciekawa funkcja, ale nie znajdziemy jej w Xamarin.Forms. Działa tylko dla WPF/WP. W view modelach mamy dostępne właściwości IsInDesignModeIsInDesignModeStatic. Za ich pomocą można sprawdzić, czy jesteśmy w trybie designu (czyli praca w Visual Studio, podgląd xamla w designerze), czy w działającej aplikacji. Jest to pomocne, gdy chcemy wyświetlić testowe dane w designerze xamla.

Messenger

Mamy dostęp do wbudowanego messengera. Z poziomu view modelu możemy użyć właściwości MessengerInstance, a w innych miejscach GalaSoft.MvvmLight.Messaging.Messenger.Default.

Jak widzimy, wysyłamy wiadomość metodą Send. Możemy wysłać wiadomość do wszystkich subskrybentów, do konkretnej klasy lub do subskrybentów z danym tokenem. Aby się zarejestrować używamy metody Register z podaniem typu wiadomości jakie chcemy odbierać i opcjonalnie tokenem.

IoC i Dependency Injection

Mvvm Light używa prostego kontenera IoC nazywanego SimpleIoc. W pierwszym fragmencie kodu, przy okazji inicjalizacji, widzieliśmy już jak go używać. Możemy rejestrować klasy za pomocą SimpleIoc.Default.Register – podając samą klasę lub także odpowiadający jej interfejs. Przy okazji DbService używam tam DependencyService, który jest częścią Xamarin.Forms. Jego metoda Get pozwala nam pobrać implementację interfejsu dla danej platformy. Tutaj potrzebowałem instancji IFileService jako parametru dla DbService.

W tym samym fragmencie kodu, w linijkach 13 i 14, widzimy jak odwoływać się do klas zarejestrowanych w kontenerze.

Framework zapewnia nam wstrzykiwanie przez konstruktor do view modeli obiektów, które zarejestrowaliśmy w kontenerze IoC.

Bindowanie

Bindowanie nie jest tutaj automatyczne. Musimy sami przypisać view model do właściwości BindingContext danej strony. Robimy to w konstruktorze strony:

Właśnie dlatego stworzyliśmy właściwość ViewModelLocatora w klasie App – dzięki temu będzie nam wygodnie się do niej odwoływać.

Nawigacja i dialogi

Mvvm Light ma także wbudowaną nawigację, jednak jest to nawigacja przeznaczona dla aplikacji w natywnym Xamarinie, a nie Xamarin.Forms. Tutaj musiałem zbudować swój serwis, który wykorzystywał nawigację z Formsów, tak abym mógł używać jej w view modelach.

Framework ma wbudowane podstawowe dialogi z metodami ShowMessageShowError, gdzie możemy ustawić tytuł, wiadomość, tekst przycisku (lub przycisków) i akcję po zamknięciu.

Implementacja tych dialogów jest zależna od platform, więc musimy zainicjalizować je oddzielnie w każdej platformie. Niestety, wygląda na to, że dialog te nie są w pełni kompatybilne z Xamarin.Forms. Działają one bez problemu na UWP i iOS, ale z Androidem jest już problem. Lepiej pewnie będzie użyć domyślnych dialogów z Formsów lub np. ACR User Dialogs, które są bardzo rozbudowane.

Podsumowanie

Mvvm Light Toolkit to mały i prosty w obsłudze framework do MVVM. Dobrze nadaje się do małych aplikacji lub gdy dopiero zaczynamy przygodę z mvvm. Jako, że jest popularny, znajdziemy w sieci dużo materiałów na jego temat, a także dużo odpowiedzi na StackOverflow. Powinien być odpowiedni dla kogoś, kto chce się nauczyć na czym polega mvvm. Posiada niezbędne elementy i niewiele poza tym, a więc nie będzie niepotrzebnie mieszał w głowie i obciążał aplikacji.

Link do przykładowej aplikacji: https://github.com/tomwis/SimpleBudgetMvvmLight

Link do oficjalnej strony: http://www.mvvmlight.net