Egyik Windows Phone-os pet projektemet szerettem volna továbbfejleszteni Windows Phone 7-es és 8-as platformon is.
Ennek a megvalósítására több lehetőség is van:
- Egy Windows Phone 7-es alkalmazást készítünk: ez ugyanis a Windows Phone 8-as platformon is futni fog. Ez a legegyszerűbb hozzáállás, de így nem lehet használni a 8-as által kínált funkciókat.
- Copy-paste megoldás: két alkalmazást készítünk, az egyiket 7-re a másikat 8-ra és folyamatosan mindkettőbe integráljuk a legújabb fejlesztéseket. Nem. Erre egyszerűen csak ezt tudom mondani. Teljes rémálom karbantarthatóság szempontjából!
- Közös kódbázis létrehozása: a közös kódot beletesszük egy osztálykönyvtárba, és ezt fordítjuk bele a különálló 7-es és 8-as projektbe. Hogy ezt megtehessük az osztálykönyvtárnak a 7-es verzióra kell épülnie (ez a 8-assal is kompatibilis), viszont így nem lehet benne 8-as specifikus kód.
- Kódfájlok megosztása: két projektet hozunk létre és linkként hozzáadjuk az egyik projekthez a másik file-jait. Ha a kódban különbség lenne a platformok különbözősége miatt, akkor feltételes fordítással oldjuk meg, hogy az adott kód csak a megfelelő verzióba forduljon bele.
Részletesebb leírása ennek az msdnen.
Nekem a harmadik megoldás volt a legszimpatikusabb, így ebbe vágtam bele Caliburn Microval nehezített pályán. Hátránya ennek elvileg az, hogy nem lehet benne 8-as specifikus kód, de hát a platform specifikus kód miért ne lehetne magában a 8-as projektben? Ezeket a részeket mindenképp kétszer kell majd megírni és interface-ek használatával könnyen megoldható. Tehát szétszedtem úgy a projekteket, hogy csak a View-k és a platform specifikus kódok maradtak az alap 7-es és 8-as projektekben, és a többi ment a közös osztálykönyvtárba (ViewModelek, Modelek és egyéb segédosztályok).
Itt jött képbe a Caliburn Micro, ami konvenció alapján társítja össze a Viewkat és a ViewModeleket. A probléma az volt, hogy nem találta a “szokásos” helyen a ViewModeleket, így nem tudta kötni a View-khoz. Ezért be kell konfigurálni a Bootstrapperben induláskor, hogy a framework milyen namespaceben keresse ezeket:
protected override void OnStartup(object sender, StartupEventArgs e)
{
var config = new TypeMappingConfiguration
{
DefaultSubNamespaceForViewModels = "PhoneClassLibrary.ViewModels",
DefaultSubNamespaceForViews = "PhoneApp.Views",
};
ViewLocator.ConfigureTypeMappings(config);
ViewModelLocator.ConfigureTypeMappings(config);
base.OnStartup(sender, e);
}
Ha csak ennyit teszünk, akkor mintha mi sem történt volna, a Caliburn Micro továbbra sem tud kötni. Ez azért történik, mert a framework nem néz bele másik assembly-be. Ha erre rá akarjuk venni, akkor a Bootstrapper SelectAssemblies függvényét kell felülírnunk, például a következő módon:
protected override IEnumerable<System.Reflection.Assembly> SelectAssemblies()
{
var assemblies = new List<Assembly>();
var refAssemblies = AppDomain.CurrentDomain.GetAssemblies();
assemblies.AddRange(refAssemblies);
assemblies.Add(Assembly.Load("PhoneClassLibrary, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"));
return assemblies;
}
Ezek után már működni fog a projekt! 🙂