Creating portable code in Windows Store Apps (PCL + MVVM + OData Services)

Introduction

This sample has the goal to show how to create portable code from a existing Windows Store App. The focus is to move all portable code to Portable Class Library (PCL) project.

 

The initial code sample can be find here:

Consuming Odata Service in Windows Store Apps (Include MVVM Pattern)

Before you start, take a look in this presentation:

Do not do more copy and paste between windows store and windows phone apps

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 plaftorms.

 

Let’s start!

 

Start creating the Portable Class Library

 

and then select the following targets:

 

that are the default in 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 pratices can be very complicate. That i recomend 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:

1. In my first attemps 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

2. 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.
3. 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.

4. 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.

4.1 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:

 

5. ServiceManager and ViewModelLocator cannot be in PCL project, because it dependes from references that aren´t portable and don´t make sense change it.

6. 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!)

7. 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