Monday, February 11, 2013

MVVM for Windows Phone Developers - Use it Guys! (Part 1)

UPDATE: You can download the code on GitHub. I have added all files, except for the source for SQLight. The repository can be found here: WindowsPhone8MVVM

Talking to WP developers all over the world, made me think about, why many of them still don't want to use MVVM in their applications.

Many of the excuses where:

  • Too complicated!
  • Sucks!
  • Learning curve to stale!
  • Performance bottle neck!
  • Don't want to refactor my app to use MVVM!
and many more....

First of all - you write apps for fun - and you want your apps to be great and make money

That's really cool. And adorable :) But you should consider also the lifetime of your app and all the consequences and the job that is to do to extend it and make it better! Users want change, and they want to stay up to date. If your app is becoming successful, they will ask for changes and extra features.

There we are: lifetime, extension and being up to date

This is maybe the best arguments to use MVVM and some common development techniques, to put some grip on speed and feasibility of you app development. Some of you will never measure their development time in money, well that's a bad habit. If you want to have a highly manageable and testable source base - there's no better solution than to use MVVM for app development! You really don't want to spend hours and hours to mess around with a bunch of code-behind that is not testable and leads to tons of code-behind that put's a heavy weight on your development fun! And that's what it should be -  fun!


At first I want to mention what I think, nobody can ignore anymore when it comes to MVVM:

  • Visual Studio and Blend already offer templates for quite a while based on MVVM
  • MVVM was developed to be used with XAML-based UI technologies which includes Windows Phone, Windows 8 Modern UI Apps, Windows 7+8 desktop applications
  • Following the separation of concerns principle
  • Blendability (See for example sample data in your lists during design)
  • Better testability - if you ever have done that jet (We'll cover it here)
  • Dependency Injection (We cover it here)
  • Separate view from logic
  • Long term investment in you code

Basics about design patterns



Design patterns have been here for decades already. Everybody knows about the "Gang of Four" the guys who really established design patterns in the software development community. Therefore people speak about the "Gang of four"-book or use it for other terminologies connected to design patterns. If you want to know more about

  • Erich Gamma
  • Richard Helm
  • Ralph Johnson
  • John Vlissides
and of course Grady Booch who wrote the foreword for the book they published. Check them out on Wikipedia: http://en.wikipedia.org/wiki/Design_Patterns

You will find there a link to the best selling book about design patterns ever published!





MVVM Light Toolkit
MVVM Light Toolkit
 

MVVM-Light



MVVM-Light is a MVVM-Toolkit that allows you to create MVVM driven apps for Windows Phone, WPF and Windows 8 and very soon also for portable libraries (PCL).

It is easy to use and offers a bunch of very useful implementations like:

  • ViewModelBase (The base class for your ViewModel, which implements already INotifyPropertyChanged)
  • Messenger
  • Behavior's that play excellent with Expression Blend
  • Project templates for Expression Blend
  • Item templates for Expression Blend and Visual Studio
  • A bunch of code-snippets for Visual Studio
We will use MVVM Light using the view-first approach where we instantiate the view-model inside our views (pages).

AppBarUtils - Bindable appbar



This toolkit provides behaviors, triggers and actions to be used with an appbar on WP7 and WP8. It gives us the chance to remove ugly code-behind from the appbar commands and - what is really cool, to switch between different appbars :) Makes sense?

Moq - The simplest mocking library for .NET



Pronounced "Moq" or "Moq-You" is a widely used mocking library for .NET. And it claims to be the easiest mocking library to use. It is completely written in .NET. And it was made for developers who are not using a mocking library currently. Quite good for this article. It makes heavy use of LINQ and is strongly typed.

What are mocks and what is mocking ?

First, there are trillions of definition about mocks and what they are. First rule : Mocks are not stubs :) I don't want to start a religious discussion here about this stuff. I picked a good definition from Stack Overflow, which I really liked and I want to share with you:

A mock is like a stub, but the test will also verify, that the object under test (OUT) calls the mock as excepted. Part of the test is verifying that the mock was used correctly.

A stub on the other hand can be compared to a "Minimal" simulated object and implements just enough behavior, to allow the object under test to execute.



Here an excellent explanation from Martin Fowlers article "Mocks aren't Stubs" what mocking is:

Mocking is one particular technique to allow testing of a unit of code with out being reliant upon dependencies. In general, what differentiates mocking from other methods is that mock objects used to replace code dependencies will allow expectations to be set - a mock object will know how it is meant to be called by your code and how to respond. - Martin Fowler


Ok. So much for a simple introduction into the world of mocking. If you want to learn more about mocking check the following resources:

What is Mock testing? (YouTube)
An Introduction to Mocking Frameworks in .NET (YouTube)
Mocking With Moq (Pluralsight – you will need a subscription)

Our development scenario

We create an simple application, that reads user-data from a SQLite database. To handle our data, we will use the Repository Pattern and create an interface for CRUD (Create, Read, Update, Delete) operations.
Users can be added, displayed in a list, edited and deleted.
Our goal is to use as less code-behind as possible.

Base architecture

Our base architecture will consist of an application layer (the GUI and related stuff), a DAL (Data Access Layer) and a Data Abstraction Layer, placed between the Model and the DAL. Here is a graphic to illustrate this:
Architecture
The second layer where the MVVM pattern was placed is a mix-up between view-abstraction (ViewModel) and the Data Layer (Model). The View itself is part of the Application Layer. I would call it “Databinding Interaction Layer”, because it enables the view to interact with the under laying data by offering commands  to interact with data and bindings to use the data-values inside the view.
We have the Unit-Of-Work-Factory producing units of work for us, which interact with the specific type of data-storage like SQLight, Isolated Storage or the Entity Framework, to access the data. The specific units of work implement the interface IUnitOfWork for every specific type of data-storage and offer the basic CRUD operations. The specific unit-of-work will then be used by a IRepository<T> to perform the CRUD operations via the unit-of-work on our model classes like the User-Class we will use here.
This separates our concerns in a logical and useful way. It enables us later to test the components in isolation.
Also it allows us, to show how DI (Dependency Injection) works, using Ninject.

The implementation

First you create a new Windows Phone 8 project using Visual Studio. Name it anyway you want.

Installing SQLight for Windows Phone 8

This is a little bit tricky, but works fine.
First we need to install the Visual Studio extension “SQLite for Windows Phone”. This is done via “Tools –> Extensions and Updates”. Select “Online” on the left and type in “SQLite for Windows Phone”. Select the extension, and install it. Restart Visual Studio after a successful installation. Your project will be re-loaded automatically.
InstallSQLiteExtensionVisualStudio
Next is to download the sources for sqlite-net-wp8. This is native code written in C++, re-factored for Windows Phone 8.
sqlite-net-wp8 download
After downloading the zip-file, or cloning the repository, add the project file “sqlite.vcxproj” to your Windows Phone Solution.
Then try to compile everything. Should work fine.
Now add a new Windows 8 class library project to your solution and name it “SQLiteWP8”.
Add a reference to the class library project to the Sqlite native project by choosing “Add Reference..”  and then “Solution”, choosing “Sqlite”.
Last step to do is to download the source code of sqlite-net, and add two source files from that project to your class library:
sqlite-net download
  1. src\SQLite.cs
  2. src\SQLiteAsync
You can do this by right-clicking on the SQLiteWP-Project,  choosing “Add Existing Item…” and browse to the sqlite-net folder, choose the above files, and the files will be added to your class library.
The last step is to add the conditional build symbol “USE_WP8_NATIVE_SQLITE” to the project properties of your SQLiteWP8 class library.
Open your “SQLiteWP8” project properties, click on the “build” tab select “All Configurations” from the configurations dropdown,  and add a semicolon right after the last entry in the field “Conditional compilation symbols”, then copy and paste “USE_WP8_NATIVE_SQLITE” (without the quotes) into the “Conditional compilation symbols” field.
ConditionalBuildConfiguration
Now rebuild the solution. Everything should work out fine!. Congrats! You compiled and added SQLite to your project!
We have put all that SQLite stuff into a separate assembly, so that we can use it later anywhere we want in our Windows Phone projects.
After all the steps performed, your solution should look something similar to this:
solution_after_sqlite
A quick overview on how to use SQLite for Windows Phone 8 can be found also on the sqlite-net site.

Perparing the unit test environment

Currently the Visual Studio Update 2 (CTP) adds a new template to Visual Studio to enable you to create a new test project specifically for Windows Phone 8. This will not work with WP7. But not everyone wants to install VS-Update 2. Therefore we create our testing environment manually.
First add a new Windows Phone 8 project to your solution and call it “UnitTesting” or something else. Yes, we need to add a separate project for that.
Then we need to install 2 NuGet packages:
  1. The Windows Phone Toolkit (WPToolkit)
  2. The unit testing framework (WPToolkitTestFX)
Right click on the “References” entry within your testing application and choose “Manage NuGet Packages…”.
Choose “Online” on the left side and type “WPToolkit” into the search field on the right side. Click Install on the “Windows Phone toolkit” package.
Then type “WPToolkitTestFX” into the search field on the right, and click install on the “Windows Phone Toolkit Test Framework”.
That’s it for NuGet.
Now we need to modify the constructor of the MainPage in our test project, to load the testing environment. First add a the follwing using statement:

using Microsoft.Phone.Testing;


Add the following line after the call to "InitialzeComponent()”:


this.Content = UnitTestSyste.CreateTestPage();


Now run your newly created test project on the emulator. You should see something similar to this:

TestScreen



That’s it for part one. In the next part we continue the install of the other components and finally we start coding!





    20 comments:

    1. Great article and exactly what I am looking for. I am waiting for the next part. May be later in the comming chapters to use PCL would be also a good idea to see how cross platform development can be done using MVVM pattern in both (WP8 / WinRT) platform.
      Thanks for the post again.

      ReplyDelete
      Replies
      1. Thank you for the great feedback :) One other reader already made the suggestion to include PCL. I will do that :)

        Delete
    2. Thank you for the great feedback :) I am going to extend the post using PCL.

      ReplyDelete
    3. Great article.

      Using your guidelines, I decided to make a separate SQLite solution. I was able to successfully build it, but I cannot reference it in my windows phone app: a reference to a higher version or incompatible assembly cannot be added to the project.

      Any ideas?
      I ensured both solutions/projects are targeting windows phone 8

      ReplyDelete
    4. Hi, I think you forgot to add the conditional compilation symbol "USE_WP8_NATIVE_SQLITE" to your "SQLiteWP8" assembly properties. Could you verify this? Thanks.

      ReplyDelete
      Replies
      1. The conditional compilation already exists for Release|Arm and Debug|Arm configurations.

        Delete
      2. Hi, just set it for all configurations. I have uploaded the source code to github. You can download the code here: https://github.com/Injac/WindowsPhone8MVVM
        You can check the settings there and compare them with yours. Hope that helps.

        Delete
      3. Thanks, but you have the SQLiteWP8 project in the same solution as the windows phone app. I am trying to do them in different solutions.

        Delete
      4. Hi, it should not be a problem, to have everything in separate solutions. Would you mind sending me your source to Ilija[dot]Injac[at]outlook[dot]com ? So that I can take a look at the problematic one? Thank you.

        Delete
      5. I emailed you the source for my SQLiteWP8 solution. Thanks for your help

        Delete
      6. I emailed you the modified solution. You are very welcome :)

        Delete
      7. Thank you so much for your help. The reason I was getting that error was because I was actually trying to add a reference to SQLite.dll instead of my SQLiteWP8.dll.

        Sorry for wasting your time, but I definitely appreciate your help.

        Delete
    5. Great article, and I'm glad to hear that you're planning on covering Portable Class Libraries. Related to that, I think a big advantage of MVVM (in addition to what you listed) is that it makes it a lot easier to share your code across platforms, because the View should be platform-specific but the ViewModel can probably be shared.

      Here's a couple of links on that topic:
      How to Make Portable Class Libraries Work for You
      Create Cross-platform Apps using Portable Class Libraries

      ReplyDelete
      Replies
      1. Hi Daniel, I read you posts earlier, some weeks ago :) Great overview of all types that can be used within the different frameworks. And thank you for the great links :)

        Delete
    6. Why all the fuzz about Moq when you can't use Moq on WP8 ? I tried to add it to my solution, and it always fails. I don't see the package in your GitHub repository, so I'm guessing Moq was a "want have" feature that turns out like a "can't have" feature, right ? Or am I doing it wrong ?

      BTW: By checking your packages.config files, I saw that you added Microsoft.BCL to your WindowsPhone8MVVM project... I'm guessing you did that to use PCL... to use an async/await syntax instead of BeginMethodName and EndMethodName. To do that - on Windows Phone 8 at least - you don't need that.
      The following syntax allows just that:

      using System.Threading.Tasks;

      var request = HttpWebRequest.Create("http://www.somewhere.com/") as HttpWebRequest;
      var factory = new TaskFactory();
      var task = factory.FromAsync(request.BeginGetResponse, request.EndGetResponse, null);
      var response = await task;

      Greetings,

      Michael

      ReplyDelete
      Replies
      1. Hi Michael, Moq cannot be added via NuGet, because there is no official port for WP8. The Silverlight version is working fine for WP8, and in part 2 I show how to install that, by just adding a reference to the Silverlight assembly. You are right with the Microsoft.BCL stuff, but I have not added it explicitly to the project, don't know which or what package did so. Will check that also. Thank you for pointing that out, and thank you for your short example.

        Delete
      2. Yes you are right. I also did not know regarding MVVM . Thanks for your nice information. Mac starter kit

        Delete
    7. You are very welcome :) Thanks for visiting my blog!

      ReplyDelete
    8. This is very helpful thanks.
      Question for you. I'm a first time dev in C# and am planning my first WP8 app ( my past has been in open source, php, python, and done a lot of MVC stuff)

      So I was wondering if maybe, on the very first WP8 app, I should apply MVVM manually without a framework in order to learn it?

      But I'm thinking, no, why should I. I've already been reading tons of articles on mvvm and watches a lot of channel9 videos. It would be great to just dive into using MVVM Light since it's highly valued.

      Thanks for reading this out-loud blabbing.

      ReplyDelete
    9. Hi, when you say: "Now add a new Windows 8 class library project to your solution and name it “SQLiteWP8”.", how is this done in Visual Studio Express ?

      When I select File / New Project, I couldn't find a template for this. They all seem to be windows phone templates.
      Thanks
      Steve

      ReplyDelete