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
iViewModelLocator.cs
, a do tego modyfikujeApp.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 IsInDesignMode
i IsInDesignModeStatic
. 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 ShowMessage
i ShowError
, 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