(The app was called ComicDB in its begin stages, the namespaces stayed but the app title was changed to Comic Cloud)
The solution exists of five projects, first there’s the app itself using MVVM Light, win8nl for winRT behaviors (written by Joost van Schaik), MarkedUp for analytics, Callisto for settings fly-out, the Live SDK for the User class and the Telerik RAD controls for their controls (obviously).
The Model project contains all classes, there’s the ComicVine classes (thank God for paste JSON as class…) and some classes for RSS feeds and links.
Since I want to limit the amount of data stored in my WAMS database, I only save the userID and the link to the ComicVine API for each item. For that I needed a second version of some classes, that’s what the DTO project is for.
The framework is a project that I can reuse in other projects without changing anything, all classes that are app independent. Things like the RestClient (providing generic CRUD functions), the GroupInfoList for grouped gridviews, navigationservice to navigate between pages and so on. The ComicVineHelper is an extension method that changes the casing of some object to be compatible with the way the ComicVine API works. All these classes are implementing interfaces, so that will be a big plus when I start porting.
The SDKBroker takes all the different services I use and puts them together in one big SDK that’s easy to use from the app.
So the idea was to take all those libraries, put them in PCL libraries and reference them from both the Windows Store app and the Windows Phone app. Next to that I wanted to use the portable version of MVVM Light to share my viewmodels over both projects as well. Turns out that, as usual, a good idea is stopped by technical limitations.
The problem is the difference between Windows 8 and Windows Phone, they don’t share their entire codebase. Meaning I can’t reuse all my code in a PCL. Also the Azure Mobile Services SDK has no portable version, so same problem there.
The solution is abstractions, create an interface for every class that isn’t compatible with the PCL projects and implement them in a platform specific library. The PCLs I’m using only target .net 4.5, winRT and WP8 so a lot of problems are already taken care of by not selecting WP7.X compatibility.
I wanted to start out by replacing MVVM Light with the PCL version. This turned out to be easier said than done, the initial project was started from the MVVM Light template so I threw out the references to MVVM Light and added the PCL version through NuGet. Visual Studio went quite mad and started throwing all sorts of weird build errors, I eventually found out that the win8nl library also includes the MVVM Light assemblies and those conflicted with the PCL versions. But I needed the win8nl assembly for the eventtocommand behaviors in WinRT so that posed a big problem. Luckily there’s the winRTBehaviors assembly that contains the logic to do behaviors but it doesn’t include the actual eventtocommand one. The solution was to go to the Codeplex site of win8nl and copy the behavior classes from there and put them in my framework project. One problem solved.
The next step was to add a PCL for the Framework and SDKBroker projects, the Model was already a PCL so that one could stay as it was. The PCL libs got named ComicDB.Framework and ComicDB.SDKBroker, they contain a combination of interfaces and classes. Everything that couldn’t be made portable was abstracted into an interface and implemented in platform specific libraries called ComicDB.Framework.WinRT and ComicDB.SDKBroker.WinRT. The classes that needed abstraction were the NavigationService, Network helper, WAMS service class and Service helper. Thanks to the new portable HttpClient assembly I could copy my RestClient class to a PCL without any adjustments.
With some tinkering I got the project to build and run again and I saw that it was good. The time had come to move my ViewModels over to a PCL. I added a new PCL project called ComicDB.ViewModel (same namespace as my VMs already had) and added the portable MVVM Light version. The ViewModelLocator can’t be moved since it needs to register all the correct interface implementations into the IOC container, so I’ll have a separate Locator class for Win8 and WP8. As I started moving ViewModels I quickly ran into a navigational problem, my viewmodels have navigation logic and the pages they are navigating to aren’t known in the PCL. To solve this I’ve created an interface for every page and set that as navigational target, I don’t know if this will work but I’ll find out soon enough and put it in part 2 if this diary.
Navigational problem solved, on to the next one. Two of my viewmodels could show toast notifications, I use the notifications helper classes from MSDN to get this done but the notification classes aren’t portable (and they really don’t need to be since Windows Phone doesn’t support in-app toasts, the C4F toolkit fixes that luckily) so I created an IMessageAPI interface that has a PopToast() method. In FrameWork.WinRT it shows a build-in toast just like the app used to do.
Hey remember that we have to do everything async now and that we can call the Dispatcher to execute something on the UI thread? Not happening in a PCL… MVVM Light contains a DispatcherHelper that checks if an action needs to be executed on the UI thread and actually executes it there when needed, except in the PCL version. So IDispatcher was born.
With that done I got my project to build again and to run but it’s currently still using the old viewmodels, I expect a whole bunch of new problems when I try to change it to the PCL versions, but that will be for part 2.
In part 2 I hope to make the app use the PCL version of the viewmodels and I’ll start working on the Windows Phone project.
PCL projects sound very good in theory but in reality they are a great PITA to work with. Portable HttpClient and portable MVVM Light make them useful but you’ll have to right loads of extra code, abstractions and helper classes to get to something that looks like build once run on two platforms. I could’ve given up and just rebuild everything in a separate solution for WP8 but I want to see how far I can take this and document it along the way.
That said, I have no idea when part 2 will be live, that depends on when I can gather the courage to reference the viewmodel project
This is an imported post. It was imported from my old blog using an automated tool and may contain formatting errors and/or broken images.