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
April 10th, 2014 at 9:11 am
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
April 10th, 2014 at 9:33 am
Paweł, wiem wiem, że potrafi, ale nie chcę wchodzić w Twoje kompetencje 🙂
April 10th, 2014 at 12:17 pm
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…
April 10th, 2014 at 8:46 pm
Ś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…
April 11th, 2014 at 10:46 am
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.
April 11th, 2014 at 8:21 pm
Zgadza się takie magiczne toole to coś pięknego. Do niedawna w magii prowadził Caliburn.Micro, ale teraz zdecydowanie Fody.
April 14th, 2014 at 8:34 pm
Basia Fusińska o IT » Fody Weaver i PropertyChanged…
Dziękujemy za dodanie artykułu – Trackback z dotnetomaniak.pl…
April 22nd, 2014 at 1:58 pm
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.