Introduction
This sample aims to show how to create portable code from an existing Windows Store app. The focus is to move all portable code to a Portable Class Library (PCL) project.
The initial code sample can be find here:
Before you start, take a look in this presentation:
Get the code for this sample, here.
Building the sample
You only need Visual Studio 2012 and Windows 8, both the RTM version.
Description
After you got the code sample from Consuming Odata Service in Windows Store Apps (Include MVVM Pattern) you are available to start a refactoring with the goal to create portable code, that can be used in other
platforms.
Let’s start!
Start creating the Portable Class Library
and then select the following targets:
that are the default in the PCL project template.
Now we can focus in creating portable code, in theory we can say:
Views (Platform-specific)
- How to display information
- Written in XAML
View Models (Portable)
- What information to display
- Flow of interaction
Models (Portable)
- Data objects
- Business logic
- Etc.
This is simple, but in practices can be very complicate. That I recommend is: move a small parts of code, for create portable code the Abstraction pattern is the key and resolve each problem that you have !
Don't try move all things and don't forgot that some namespaces are not available in PCL. Another note, dependency injection and ioc can be useful!
See this:
Returning to the sample, the first thing we can try to do is move all about Model, View Model, and Helpers to inside the PCL project.
But wait, like I said before, move only small parts of code!
Let’s move only the Model and Helpers:
Move Helper and Model folder to PCL project and delete it from ClientApp project.
Resolve dependencies related with
- BitmapImage
- NotifyPropertyChangedInvocator
- CallerMemberName
Each will resolver this way
BitmapImage
– will be replaced with url string and is necessary to fix all related issues ( it is right because I will binding image’s source with the url path and it loads the image this way);NotifyPropertyChangedInvocator
– will be removed because is related with Resharper (see this http://bit.ly/11CGebN);CallerMemberName
– will be resolved with Microsoft.Bcl.Async ( See Notes 1.)
Move all view model and classes related with dependency injection/ioc to inside the PCL
This means, move ViewModel and Service folder to PCL project.
Resolve dependencies related with
- Old using (“
using Windows.UI.Xaml.Media.Imaging;
”) inside FakeServiceManager - ViewModelBase from MVVM Light Toolkit
- Task.Run
- Task.WhenAll
Each will resolver this way:
- Remove “
using Windows.UI.Xaml.Media.Imaging;
” because is not necessary,
I change bitmap to string from last commit. (See Notes 3) - ViewModelBase from MVVM Light Toolkit – install the MVVM Light (PCL) package (See Notes 4.)
- Replace Task.Run with Task.Factory.StartNew (see more about it here: http://bit.ly/11wTB1Y)
- Replace Task.WhenAll with TaskEx.WhenAll
Notes:
- In my first attempts I thought, it could not be possible to be solve. But after some search I found to important package in Nuget: Async for .NET Framework 4,
Silverlight 4 and 5, and Windows Phone 7.5 and 8
- TitleItemview is deleted because it depends from my DataServices and
I prefere use only MyTitleItemView and the other things is the fact the OData services is not supported in PCL projects, because is not portable, for now. See this:
http://bit.ly/VpE4wD.
- The path for url image in FakeServiceManager must be defined in especific projec in the same moment that I regist the dependency in my container. This is important too, because in other platforms the path is not the same.
- Before I install the MVVM Light (PCL) package in PCL project, I removed the MVVM Light packages from ClientApp because it can cause some issues related with differentes packages from same toolkit (that contains same namespace… be aware!). And when you do this, the App.xaml will change and it can be broken, but don´t worry, you need to replace this file with the version from last commit because the unique diference is the references.
- The PCL project was created with defatul targets and when you install the MVVM Light (PCL) you will see this error:
Like you can see, if you want to use it you should set Windows Phone 7.5 and higher
I could remove Silverlight, but no matter because you will have this:
- ServiceManager and ViewModelLocator cannot be in the PCL project, because it depends
on references that aren't portable and don't make sense change it.
- Attention with namespace I am using, I like to keep congruent namespace and StyleCop + Resharper help me to keep rules (but is not necessary, you can change all without it!)
- This packages contains one GIT repository that can be used for see all step
I said before. Each commit has the respective comment and file changes.
Example:
Source Code Files
The solution has the following structure:
Details:
- IServiceManager.cs has the
IServiceManager
interface and define the interface for the
ServiceManager
. - ServiceManager.cs has the
ServiceManager
class and it encapsulate the
NetFlixService
and exposes only the methods that is need in ViewModel. - FakeServiceManager.cs is the implementation of the
IServiceManager
, but is a fake data.
- TitlesViewModel.cs has
TitlesViewModel
class and it is used for binding with the
DataContext
from TitlesPage
. - ViewModelLocator.cs has the
ViewModelLocator
class that help to binding the view model with the view. - ViewModelHelper.cs has the
ViewModelHelper
class the helps to create grouped data.
- TitlesPage.xaml and TitlesPage.xaml.cs that is the main page.
- Templates.xaml is a resource dictionary that has the
DataTemplate
for the view. - NetFlixItemTemplateSelector.cs has the
NetFlixItemTemplateSelector
that is used for get the
ItemTemplate
for each item in GridView
.
Others References
Run the sample
To debug the app and then run it, press F5 or use Debug > Start Debugging. To run the app without debugging, press Ctrl+F5 or use Debug > Start Without Debugging.
More Information
Ask me on twitter @saramgsilva