Jeśli zdarza się nam pracować z plikami .xaml i korzystamy z dobrobytu jakim jest bindowanie kod-widok (niezależnie od tego czy będzie to MVVM czy code behind), po pewnym czasie nadchodzi moment, gdy szlag nas trafia i musimy napisać po raz kolejny zamiast prostego ładnego property:
public class MyClass { public string MyProperty { get; set; } }
jakiegoś takiego potworka:
public class MyClass { public event PropertyChangedEventHandler PropertyChanged; string _myProperty; public string MyProperty { get { return _myProperty; } set { if (value != _myProperty) { _myProperty = value; OnPropertyChanged("MyProperty"); } } } public virtual void OnPropertyChanged(string propertyName) { var propertyChanged = PropertyChanged; if(propertyChanged != null) { propertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } }
Pojawiają się w naszej klasie: event, implementacja metody OnPropertyChanged, oraz jej wykorzystanie w setterach. Pomijam tu “smaczek” podawania nazwy w stringu. To i tak nie jest najgorsze co się nam może przydarzyć. Moglibyśmy mieć property, które odwołuje się do kilku innych. Wtedy musimy dodatkowo pamiętać, by OnPropertyChanged dla niego wykonać w setterach składowych.
Bleh…
Z pomocą przychodzi np. Fody. Jest to prosty pakiet, który należy ściągnąć (np. stąd, lub nugetem), zainstalować i nakazać projektowi, by go używał (Project > Fody > Enable). Dodatkowo, przyda się konfiguracja weavera. Jest na to kilka opcji, a tu już odsyłam do dokumentacji.
Ja akurat używam pliku .xml:
<?xml version="1.0" encoding="utf-8" ?> <Weavers> <PropertyChanged EventInvokerNames="raisePropertyChanged"/> </Weavers>
Dzięki temu nie muszę w swojej klasie ani w moim property robić nic poza czystym get i set. Moje ViewModele stają się zwykłymi klasami, bo chyba do tego zostały wymyślone.
Fody oczywiście sporo od siebie dodaje i kod przybiera inną formę. Nasza klasa zaczyna implementować interfejs, dostaje event, ma zaimplementowaną metodę OnPropertyChanged, a wszystkie property są poorane w przedstawiony wcześniej sposób, nawet te złożone z kilku innych. Ale czego oczy nie widzą, tego sercu nie żal
Oj fody potrafi sporo więcej nawet jeśli patrzymy na ten jeden jego pakiet. Pisałem o nim tutaj: http://blog.octal.pl/2014/03/fody.html a tutaj http://blog.octal.pl/2014/03/fody-po-prelekcji-na-kgd-net.html jest link do mojej prezentacji o Fody na KGD.NET
Pozdrawiam,
Paweł Łukasik
Paweł, wiem wiem, że potrafi, ale nie chcę wchodzić w Twoje kompetencje 🙂
Fajne, wygląda dużo czyściej i mniej roboty niż alternatywne podejście z proxy (np.: http://jonas.follesoe.no/2009/12/23/automatic-inotifypropertychanged-using-dynamic-proxy/).
Ale z końcową oceną zaczekam do dzisiejszej sesji Pawła na WG.NET :). Bo proxy/IoC jakoś tam ogarniam, a to na razie czarna magia…
Świetna sprawa. Tylko dlaczego w celu uzyskania czytelności kodu trzeba stosować zewnętrzne biblioteki? W idealnym świecie tworzenie aplikacji w MVVM wyglądałoby tak od początku. Niestety świat nie jest idealny…
Niestety…
Osobiście bardzo lubię polegać na narzędziach zewnętrznych, które wprowadzają nam jakąś magię. Taki kompromis to cena za stosowanie tooli.
Ale zawsze możemy mieć nadzieję, że w następnych wersjach świat może idealny nie będzie, ale choć trochę piękniejszy.
Zgadza się takie magiczne toole to coś pięknego. Do niedawna w magii prowadził Caliburn.Micro, ale teraz zdecydowanie Fody.
Pingback: dotnetomaniak.pl
Zastanawiam się czy podejście wzorowane na automatycznym śledzeniu zależności podobne do tego w knockout.js nie byłoby rozsądnym kompromisem. Fakt z jednej strony zostałoby trochę brzydkiego powielanego kodu(Ale mniej niż w podejściu klasycznym) z drugiej strony nie byłoby automagii która z czasem może nas kopnąć z zaskoczenia.