sobota, 10 marca 2012

Prism 4.1 na Windows Phone

Zasadnicze pytanie: jaki jest sens używania Prism na Windows Phone? O zaletach prisma nie będę pisać. Jest ich wiele. Natomiast z mojego punktu widzenia sens przeniesienia Prisma na Phona jest zasadniczy: projekt wieloplatformowy oparty na Prismie - test jego wydajności, zalet i wad. Projekt jest tworzony na WP7, Silverlighta oraz WPF. Podchodząc do tematu od strony reużywania kodu i jego spójności sprawą kluczową staje się wspólny framework.

Przede wszystkim spotkałem się w necie z krytyką mówiącą, że prism na phona jest mega ciężki i lepiej korzystać z caliburn'a micro lub innych bibliotek. Ok, ok, ok... zacznijmy od początku.
Prism na phona tak naprawde nie istnieje - dlatego nie wiem skąd wzięły się opinie że jest za ciężki. W prismie na phone'a znajdziemy dosłownie 3 klasy na krzyż i brakuje tam wszystkiego dzięki czemu Prism jest używany przez wielu ludzi na świecie czyli brak IoC, modułów i regionów. Ughh... ciężki kawałek chleba. Postanowiłem zmigrować prisma silverlightowego na Phone'a. Ograniczyłem się do minimum czyli kompilowalność kodu i zachowanie elementarnej logiki.
Zaczynamy od głównego projektu. Prism.Silverlight. Przede wszystkim pozbywamy się wszelkich powiązań z kontrolką TabControl. Następnie docieramy do powiązania z klasą HashSet (której nie ma w wp7), czym się nie należy przejmować bo za chwile trzeba będzie przeorać całego ModuleManagera i HashSet będzie nie potrzebny. Zasadniczy problem przy migracji jest taki, że na WP7 nie możemy dynamicznie ładować assembly (zainteresowanych odsyłam tu i tu). Dochodzimy do funkcji LoadModuleTypes ModuleManager'a w której trzeba przyjąć że modułu nie zaciągamy z nikąd tylko on po prostu już jest. Wtedy po moich zmianach funkcja LoadModuleTypes wygląda tak:
private void LoadModuleTypes(IEnumerable moduleInfos)
{
if (moduleInfos == null)
{
return;
}

foreach (ModuleInfo moduleInfo in moduleInfos)
{
if (moduleInfo.State == ModuleState.NotStarted)
{
bool isUnavailable = Type.GetType(moduleInfo.ModuleType) == null;
if (isUnavailable)
{
throw new ModuleTypeLoadingException(string.Format
(Resources.FailedToGetType, moduleInfo.ModuleType));
}

moduleInfo.State = ModuleState.ReadyForInitialization;
}
}

this.LoadModulesThatAreReadyForLoad();
}

Jest to kluczowa zmiana w migracji. Jak widać zaciąganie modułu zamieniłem na rzucanie wyjątkiem jeżeli moduł jest niedostępny. Teraz całą resztę niepotrzebnego kodu związanego z ładowaniem modułów możemy spokojnie usunąć :) Nie będę dokładnie pisać co wywaliłem (dynamiczne ładowanie modułów i inicjalizacje modułu na żądanie). Projekt można ściągnąć i porównać kody z oryginalnym Prismem Silverlightowym.
Następnie możemy się zająć biblioteką Interactivity dla Prisma. Tutaj wystarczy wywalić wszystkie pliki powiązane z ChildWindow, który na WP7 nie jest używany (przynajmniej takie jest założenie:)
I to tak naprawdę wszystko. Dodatkowo jeżeli potrzebujemy zrobić testy jednostkowe powinniśmy zmigrować sobie Prism.Silverlight.TestSupport. Reszty bibliotek nie potrzebuję. Dodatkowo do tego zestawu wybrałem Ninject, który pomoże mi z DI. W następnym poście opisze testy jednostkowe dla WP7 na przykładzie Prisma. Cały projekt można ściągnąć pod tym linkiem

0 komentarze:

Prześlij komentarz

 
Design by Free WordPress Themes | Bloggerized by Lasantha - Premium Blogger Themes | Online Project management