Create an offline HTML5 application for IOS with ASP.NET MVC3

 You need to build an application for the IPad or IPhone but you don’t have the time to learn objective-c and cocoa.  The good news is that you don't need to! 

This walkthrough demonstrate how to use the .Net web technology stack to create applications for the IOS platform.  Because we want to be capable of using the application also offline, the UI need to rely purely on HTML and Javascript and we can't use any server side markup generation. Nevertheless we'll need ASP.NET MVC for the creation of web services and his brand new model binding feature to deserialize the JASON message back to a server side model.

We'll first create a new Visual Studio Asp.Net MVC3 empty web application and add an “index.htm” page to the project root:

<!DOCTYPE html>
    <title>Subscription Form</title>
    <link href="Content/Site.css" rel="stylesheet" type="text/css" />
    <script src="/Scripts/jquery-1.5.1.min.js" type="text/javascript"></script>
    <script src="/Scripts/jquery.validate.min.js" type="text/javascript"></script>
    <div class="page">
            <div id="title">
               Subscription Form
        <section id="main">
        <span id="resultmessage"></span>
        <form id="sub_form" method="" action="">
                        <input type="text" id="firstname" name="firstname" />
                        <input type="text" id="lastname" name="lastname" />
                        <input type="text" id="email" name="email" />
                        <input type="text" id="phone" name="phone" />
                        <input type="button" id="create_subscription" value="Create" >
                        <input type="button" id="send_data" value="Send" />
                <span id="busy"><img src="/Content/wait.gif" alt="wait" /></span>
    <script src="/Scripts/index.js" type="text/javascript"></script>

The first line uses the Html5 doctype and the header links to jQuery. We uses two buttons, one to create the profiles in the browser local storage and another the send the profiles to the server.

To create red boxes arround our input boxes when jQuery detects some validation we need to add these few lines of css to stylesheet:

input.error { border: 2px solid red; }

Now it’s time to implement our UI logic with javascript. By creating a separate file for our javascript we keep the  html page clean.

Add a “index.js” to the script folder:

var root = '/Subscription';
var subscriptionsUploaded = 0;
//jQuery on document ready handler
$(function () {
    //Show the busy indicator during ajax calls
    $("#busy").ajaxStart(function () { $("#busy").show(); })
    $("#busy").ajaxStop(function () { $("#busy").hide(); })
    var x = $("#createSubscription");
    //When the createSubscription button is clicked create a subscription
    //When the sendData button is clicked retrieve the subscriptions stored in the local storage and send the data to the server
    //Define jQuery validation rules and execute the validation when the form is validated 
        rules: {
            firstname: {
                required: true,
                minlength: 2
            lastname: {
                required: true,
                minlength: 2
            email: {
                required: true,
                email: true
            phone: {
                required: true,
                number: true,
                minlength: 9,
                maxlength: 9
        messages: {
            firstname: "",
            lastname: "",
            email: "",
            phone: ""
function sendDataClick() {
    //Iterate over the subscriptions stored in the local storage
    for (var i = 0; i < window.localStorage.length; i++) {
        //Retrieve the serialized subscription  
        var json = window.localStorage.getItem(window.localStorage.key(i));
        try {
            //Send the subscription to the server 
            //On success remove the subscription from the local storage 
                    function (data) {
                        $("#resultmessage").html(subscriptionsUploaded + " subscriptions uploaded!");
            //On error
                    function (xhr) {
        catch (e) { alert(e); }
//Stores a subscription into the local storage
function createSubscriptionClick() {
    //check the jQuery validation rules 
    if ($("#sub_form").valid()) {
        var person = getSubscription();
        //seialize the subscription 
        var jsData = JSON.stringify(person);
        //store the subscription
        window.localStorage.setItem($("#email").val(), jsData);
        //update the resultMessage
        $("#resultmessage").html($("#email").val() + " stored in local storage");
//Create a subscription object and bind to the input boxes values
function getSubscription() {
    var firstname = $("#firstname").val();
    var lastname = $("#lastname").val();
    var email = $("#email").val();
    var phone = $("#phone").val();
    return { Firstname: firstname, Lastname: lastname, Email: email, Phone: phone };
//Clear the input boxes values
function clearAll() {
    $("#firstname").attr("value", "");
    $("#lastname").attr("value", "");
    $("#email").attr("value", "");
    $("#phone").attr("value", "");
//Ajax: post the json serilized subscriptions 
function sendData(json, success, error) {
        url: root + '/save',
        type: 'POST',
        dataType: 'json',
        data: json,
        contentType: 'application/json; charset=utf-8',
        success: success,
        error: error

When the user click on the create button the createSubscription function is called, this function is responsible for serializing the data into a Json object and to store it in the isolated storage.  Isolated storage is a feature defined in the Html5 spec. For each domain the browser provide access  to private key/value pair collection where data can be stored  and retrieved. The sendData button is attached with an anonymous function that iterate over the key/value pair collection that contains the JSON serialized subscriptions and post the JSON serialized subscription object.

The MVC 3 includes built-in JSON binding support that enables action methods to receive JSON-encoded data and model-bind it to action-method parameters. We will now create our Model to bind to, add a SubscriptionModel class to the models of the MVC app:

public class SubscriptionModel
    [Display(Name = "Firstname")]
    public string Firstname { get; set; }
    [Display(Name = "Lastname")]
    public string Lastname { get; set; }
    [Display(Name = "Phone")]
    public string Phone { get; set; }
    [Display(Name = "Email address")]
    public string Email { get; set; }
    public void Save()
        //store the object in db

The MVC3 model binder will automatically bind all properties that matches the properties in the JSON encoded data.  Now we will define our action method to post to, add a SubscriptionController class to the controllers folder:

public ActionResult Save(SubscriptionModel inputModel)
    //Server side validation
    if (ModelState.IsValid)
        //If the model is valid we can call the save method
        string message = inputModel.Email;
        //We return the email so that when a subscription has been successfully stored we can remove it from the localstorage.
        //--> SendData function in index.js-> window.localStorage.removeItem(window.localStorage.key(data.Message));
        return Json(new { Message = message });
        //When server side validation fails we return in the details about the validation rules that failed.
        string errorMessage = "<div class=\"validation-summary-errors\">"
                + "The following errors occurred:<ul>";
        foreach (var key in ModelState.Keys)
            var error = ModelState[key].Errors.FirstOrDefault();
            if (error != null)
                errorMessage += "<li class=\"field-validation-error\">"
                    + error.ErrorMessage + "</li>";
        errorMessage += "</ul>";
        return Json(new { Message = errorMessage });

Now you should be able to test the application. 

Set a breakpoint on the Save method of the SubscriptionModel. When you enter data in the form and push on create profiles are added to the local storage, when you click on send you should hit the breakpoint and all properties of the model should been set.

To be able to load the application when we are offline we need to use a new feature available in the latest browser like IE9, the Html5:”offline application”.  More info of this feature can be found here.

Add a cache.manifest file to the root of the application:


Change the doctype of the index.htm file:

<html manifest="cache.manifest">

You will also need to change the http header that is returned by the IIS server when serving the manifest file.  Therefore in IIS7 you need to click on HTTP Headers, open IIS console manager, navigate to the cache.manifest file, click on http headers, add for the name set-> manifest,value->text/cache-manifest.

If you want an optimal experience when deploying your app on the IPhone or IPad you should also add the following meta tags inside the HTML header:

<meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1.0, maximum-scale=1.0" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<link rel="apple-touch-icon" href="/Content/applogo.gif" />
<link rel="apple-touch-startup-image" href="/Content/startuplogo.gif" />

You should also add your own image files (applogo & startuplogo) in the content folder so that the startup and app icon is set on the IPhone.

Now you can navigate to the page with your IOS device, click on “+” button of the safari browser, add shortcut and voilà you’ve an offline application for your IPhone/IPad made entirely in HTML5/Javascript/ASP.NET MVC3.

Have fun!

kick it on

HTML5 Local Storage

There is a feature in HTML5 that enables you to store named key/value pairs in the local storage of your browser.  The advantage over using regular cookies is that your data is never send to the remote web server and that you can store a lot more compared to the 4KB limitation of cookie storage space.

As the local storage is a feature making part of the HTML5 specification, only modern browser supports is;
Safari 4.0, Opera 10.5,IE8, FireFox 3.5, Chrome 4.0 and IOS above version 2.0.

As for any feature of HTML5 before using it you should check if your browser supports the feature:

   1: function can_use_html5() {
   2:    try {
   3:        return 'localStorage' in window && window['localStorage'] !== null;
   4:    } 
   5:    catch (e) {
   6:        return false;
   7:    }
   8: }

To store or retrieve an item from the local storage:

   1: //Retireve an item:
   2: var item = localStorage.getItem("mykey");
   3: //Store an item:
   4: localStorage.setItem("myKey", "myValue");

To clear an item from the local storage or remove all items:

   1: //Remove an item
   2: localStorage.removeItem("myKey");
   3: //Remove all
   4: localStorage.clear();


With this feature we are now able to build web applications that can work offline.  Here under I build an application that stores persons profiles in the local storage.  I use the JSON.stringify method to serialize the persons before storing the JSON strings in the local storage and JQuery to retrieve the values and bind the events:

   1: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "">
   2: <html xmlns="">
   3: <head>
   4:     <title>Local Storage</title>
   5:     <script src="" type="text/javascript"></script>
   6: </head>
   8: <body>
   9:     <div id="resultMessage">&nbsp;</div>
  10:     <table style="position: absolute; left: 10px;">  
  11:         <tr>
  12:             <td>
  13:             Firstname:
  14:             </td>
  15:             <td><input type="text" id="firstname" />
  16:             </td>
  17:         </tr>
  18:         <tr>
  19:             <td>
  20:             Lastname:
  21:             </td>
  22:             <td><input type="text" id="lastname" />
  23:             </td>
  24:         </tr>
  25:         <tr>
  26:             <td>
  27:             E-mail: 
  28:             </td>
  29:             <td><input type="text" id="email" />
  30:             </td>
  31:         </tr>
  32:          <tr>
  33:             <td>
  34:                 <input type="button" id="save"  value="Create" />
  35:             </td>
  36:             <td>
  37:                 <input type="button" id="print"  value="Print"/>
  38:             </td>
  39:         </tr>
  40:     </table>
  41:     <script type="text/javascript">
  42:         $(function () {
  43:             if (!can_use_html5()) {
  44:                 alert("This browser does not support Html5 storage, upgrade or change your browser!");
  45:             }
  46:         });
  48:         $(function () {
  49:             $("#save").click(function () {
  51:                 var person = getPerson();
  53:                 //simple validation
  54:                 if (person == null) {
  55:                     alert("Fill in all fields please!");
  56:                     return;
  57:                 }
  59:                 var jsData = JSON.stringify(person);
  60:                 localStorage.setItem($("#email").val(), jsData);
  62:                 $("#resultMessage").html($("#email").val() + " stored in local storage");
  63:                 clearAllText();
  64:             })
  65:         });
  67:         $(function () {
  68:             $("#print").click(function () {
  69:                 for (var i = 0; i < window.localStorage.length; i++) {
  70:                     document.write('<div id="record_' + i + '"> ' + localStorage[localStorage.key(i)] + '</div>');
  71:                 }
  72:                 localStorage.clear();
  73:             })
  74:         });
  76:         function getPerson() {
  77:             var firstname = $("#firstname").val();
  78:             var lastname = $("#lastname").val();
  79:             var email = $("#email").val();
  80:             //simple validation
  81:             return (firstname == "" || lastname == "" || email == "") ? null : { Firstname: firstname, Lastname: lastname, Email: email };
  82:         }
  84:         function can_use_html5() {
  85:             try {
  86:                 return 'localStorage' in window && window['localStorage'] !== null;
  87:             } 
  88:             catch (e) {
  89:                 return false;
  90:             }
  91:         }
  93:         function clearAllText() {
  95:             $("#firstname").attr("value", "");
  96:             $("#lastname").attr("value", "");
  97:             $("#email").attr("value", "");
  98:         }
  99:     </Script>
 100: </body>
 101: </html>

HTML5 enables new possibilities for all types of scenarios like creating IPAD/IPhone web applications without having to program in objective c and/or upload the app to the app store.  In a future post I will demonstrate how you can extend this application to create such an application.   

kick it on

Answer for Puzzle 2

public IEnumerator GetEnumerator()


for (int index = 0; index < values.Length; index++)


yield return values[(index + startingPoint) % values.Length];



This small code block of c#2 replaces the entire Iterator class. The trick here is in the yield return statement.  When you write this statement you actually ask .Net to create a state machine for you. This statement is keeping track of what we were doing when we last returned a value.  Every time the yield return statement is hit the method returns but when the calling method ask for the next element in the IEnumerable collection you re-enter the method just after the last yield return statement as you would never have left it. All the state of the local variables inside the IEnumerator method is preserved.  What is also important to understand is that trick is not performed by the runtime but by the compiler so you don’t incurs real performance lost.

Puzzle 2: iterators using the yield statement (intermediate)

Remove the iterator class from the listing and replace the call to the iterator class, inside the iteration sample(line 29), by using the yield operator of C#2.

The output of the Problem() method should remain the same.

  1: using System;
  2: using System.Collections;
  4: namespace Puzzles
  5: {
  7:     public class Enumarators
  8:     {
  9:         public static void Problem()
 10:         {
 11:             var myValues = new[] { "a", "b", "c", "d" };
 12:             var col = new IterationSample(myValues);
 13:             foreach (var x in col)
 14:             {
 15:                 Console.WriteLine(x);
 16:             }
 17:         }
 19:         public class IterationSample : IEnumerable
 20:         {
 21:             internal object[] values;
 23:             public IterationSample(object[] values)
 24:             {
 25:                 this.values = values;
 26:             }
 27:             public IEnumerator GetEnumerator()
 28:             {
 29:                 return new Iterator(this);  //Change this line by using yield
 30:             }
 31:         }
 33:         public class Iterator:IEnumerator
 34:         {
 35:             IterationSample parent;
 36:             int position;
 38:             internal Iterator(IterationSample parent)
 39:             {
 40:                 this.parent = parent;
 41:                 position = -1;
 42:             }
 43:             public bool MoveNext()
 44:             {
 45:                 if (position != parent.values.Length)
 46:                 {
 47:                 position++;
 48:                 }
 49:                 return position < parent.values.Length;
 50:             }
 51:             public object Current
 52:             {
 53:                 get
 54:                 {
 55:                     if (position==-1 || position==parent.values.Length)
 56:                     {
 57:                      throw new InvalidOperationException();
 58:                     }
 59:                     return parent.values[position];
 60:                 }
 61:             }
 62:             public void Reset()
 63:             {
 64:                 position = -1;
 65:             }
 66:         }
 67:     }
 68: }

Answer for puzzle 1

The result is: xhello The thing here is that because the stringbuilder is a reference type, when you change the content of the stringbuilder inside the method AppendHello() this change is reflected in the caller method –> Problem() but when you set the stringbuilder to null this change is not visible inside the caller method. This is because in .Net all parameters are passed by value, even reference types. For reference types it’s not the value of the object itself that is passed by value but a pointer to the underlying value (the reference). The pointer is copied on the stack and is passed by value. When you change the value inside the called method this change is reflected in the underlying value and is visible for the calling method. When you set the pointer to null inside the called method you only destroy the copied pointer not the underlying value.

Puzzle 1: Passing reference types by value (Beginner)

With this post I’ll start a series about programming puzzles and kata’s.

These small exercises will focus on the specific features of C#1,2 & 3.

Have fun…


What is the output of: ValueRef.Problem() ?

Can you explain why?


  1: public class ValueRef
  2: {
  3:         public static void Problem()
  4:         {
  5:             StringBuilder myStrBuilder = new StringBuilder("x");
  6:             AppendHello(myStrBuilder);
  7:             Console.WriteLine(myStrBuilder.ToString());
  8:             Console.ReadLine();
  9:         }
 11:         static void AppendHello(StringBuilder builder)
 12:         {
 13:             builder.Append("hello");
 14:             builder = null;
 15:         }
 16: }
kick it on

Sharing Common Volatile Assemblies Across Solutions and Teams


I've taken over the role of Architect on a large project made of several applications all sharing a lot of common assemblies.


The project is composed of several sub teams, every team is responsible for an application and share multiple common assemblies (sort of framework). Because the project is still in an early stage, the common assemblies incurs a lot of modifications on implementation but also on contract level. Therefor common assemblies are generated by custom CI (Continous Integration)builds that drops the assemblies on a network folder.  The developers working on the applications, references the common assemblies through the network folder so that when a new version of the assembly is build, it is automatically refreshed by Visual Studio. 






This chaotic architecture and wrong way of working brings a lot of trouble. First of all, the developers are not isolated from each others changes. Because the applications are directly referencing the assemblies stored on the network share, every time a CI build generate a new version of the common assemblies - these are automatically picked-up by Visual Studio. When breaking changes are introduced in the common assemblies, dependent applications suddenly breaks.
e.g. -> When the developer A check’s in a file belonging to a shared project this trigger a CI build and refreshes the shared assembly on the build output folder –  Visual Studio of developer B detect that the referenced assembly has changed and refreshes the local bin folder - potentialy breaking the build of B and this without performing a get-latest version.

The teams also experiences a lot of runtime errors caused by not matching assembly manifests. The problem is that the common assemblies are versioned and also dependent on other common assemblies.
 e.g. -> App A depend on Common1-V1 and Common2-V1. Common1-V1 depend on common3-V1 & Common2-V1 depend on Common3-V2. This leads to runtime errors because only 1 assembly version of Common3 can be in the app bin folder at the same time. When the application creates a new instance of Common3 (not the right version) the runtime detect that the assembly manifest of Common3 is different from the expected version and throws a fatal error.

Despite all the pain, the teams didn't want to perform a big architectural refactoring right now – they are behind schedule and needs to release a first version of the applications next month.  So I searched for an efficient way to bring some order in this chaos without impacting the project too much.

The first thing was to change the references in the VS soltions. I created a local “_Reference” folder on the root of every VS solution and copied all tools and shared assemblies into this folder. I deleted and re-created all references so that they now point to the local "_Reference" folder. This improve the build time and isolate the teams from each other changes - but the spaghetti of dependencies was still causing a lot of trouble. The teams still needed to constanly update their local _Reference folder with the latest version of the common assemblies  otherwise they could experience integration issues later on. But copying constantly the common assemblies is error prone and tedious.

For this project automating the syncing of the local references was a must, therfore I made a small tool: JoPack. I grouped the shared assemblies in packages and created a central xml file representing our project catalogue.
The catalogue is basically an xml file defining the packages and the files included in those packages and the path (source) where they can be found. It also describes the dependencies between the packages. I added a local dependency.xml file to each solution root path. This file lists the packages used by a particular solution. The catalogue is versioned on our source controller and available through a network share.


Based on the dependency.xml, JoPack synchronizes the local reference folder with the shared files.


JoPack download all the packages present in the dependency.xml file but also other packages the root packages are dependent on.
Our shared assemblies listed in the catalog.xml file are still created by CI builds and put on the network shares but now each time a new version of an assembly is created a developer can use JoPack to synchronize his local reference folder. Once the solution is build and all tests are passing the local reference folder can be checked-in making it available to all other developers working on the same application.
We also automated this process by running JoPack as part of our CI build:
We setup a pre-build target that launches JoPack to sync the solution local reference folder on the CI server. When the build succeed the CI build check the _Reference folder back in. Now the developers don’t need to run JoPack on their local machine anymore.

 This strategy decreased the complexity due to the number of dependenices because the number of shared parts went from 100 assemblies to 15 packages. The dependencies are also more obvious because we now dispose of a catalogue that provides an overview of all the dependencies between packages. As only 1 version of a particular assembly can be listed in the catalogue the problem of non matching assembly manifest was also solved.  What was very apreciated by the developers is that the build time decreased drastically and that they didn't experienced suddenly breaking builds anymore.



Sources, binaries and docs for JoPack can be downloaded here – contribution can be made through the jopack google code repository.

kick it on

New version of the WCFMsmqFactory

Based on the comments I recieved on the article:

Create a WCF service and client, using Msmq, programmatically I've updated the MsmqFactory class.


Here is the new version:

using System; using System.Messaging; using System.ServiceModel; using System.ServiceModel.MsmqIntegration;

namespace BelgianAgencies.Wcf
    public class WcfMsmqFactory<I>
        private string _queueAddress;
        private string _netmsmqAddress;
        public WcfMsmqFactory(string queueName)
            _queueAddress = String.Format(@".\private$\{0}", queueName);
            _netmsmqAddress = String.Format(@"msmq.formatname:DIRECT=OS:{0}", _queueAddress);
            if (!MessageQueue.Exists(_queueAddress))
                MessageQueue.Create(_queueAddress, true);
        public bool UseCustomDeadLetterQueue
        /// <summary>
        /// Is the queue on a device connected to active directory.
        /// Standard = false.
        /// </summary>
        /// <value><c>true</c> if [in active directory]; otherwise, <c>false</c>.</value>
        public bool InActiveDirectory
            get; set;
        public ServiceHost CreateService<T>(string namespaceName)
            var sHost = new ServiceHost(typeof(T));
            MsmqIntegrationBinding binding;
            binding = InActiveDirectory ? new MsmqIntegrationBinding(MsmqIntegrationSecurityMode.Transport) : new MsmqIntegrationBinding(MsmqIntegrationSecurityMode.None);
            // Retry at most 5 times
            binding.ReceiveRetryCount = 1;
            // Max amount of retries before cancel message
            //  (1 + MaxRetryCycles) * (ReceiveRetryCount + 1) = total amount of retries
            binding.MaxRetryCycles = 3;
            // time before timout when unable to get message out of the queue
            binding.ReceiveTimeout = new TimeSpan(0, 0, 5);
            // when unable to dequeue put message on dead letter queue
            //TODO: set to reject on msmq 4.0
            binding.ReceiveErrorHandling = ReceiveErrorHandling.Fault;
            // this message is not volatile, when hard reboot message will not get lost
            binding.Durable = true;
            // timout when opening connection
            binding.OpenTimeout = new TimeSpan(0, 0, 5);
            // timout when closing connection
            binding.CloseTimeout = new TimeSpan(0, 0, 5);
            binding.Namespace = namespaceName;
                new Uri(_netmsmqAddress)
            return sHost;
        public I CreateChannel()
            var binding = new MsmqIntegrationBinding(MsmqIntegrationSecurityMode.None);
            var address = new EndpointAddress(String.Format("msmq.formatname:DIRECT=OS:{0}", _queueAddress));
            var channelFactory = new ChannelFactory<I>(binding, address);
            return channelFactory.CreateChannel();

.Net Interview questions

This morning a colleague of mine asked me for a list of questions to prepare for a .Net technical interview.

I thought it would be useful to share this list with everyone.

A) Developer


1) OO

  • Explain principles of Object Orientation?
  • Can you use abstract classes in place of Inheritance ? What are the differences between these two concepts?
  • Explain polymorphism and write an example in code (C#).

2) Patterns

  • What are Patterns?
  • List some patterns you’ve already used.
  • Explicit one pattern by writing a small example.
  • Explain following patterns: Repository, Factory, Root Aggregate.

3) UML

  • What are the most useful UML diagrams? (list & explain at least 5) .

4) Net & C#

  • What is .Net? (Managed Code - CLR - Runtime) ?
  • Explain concepts as JIT, CLR, GAC, GC?
  • Explain series of processing steps an ASP.NET page goes through (= page lifecycle of ASP.NET) ?
  • Explain following c# keywords: Static, ReadOnly, Const?
  • What is: a Webservice,WCF, WPF, Silverlight and how do these technologies/concepts relate to each other?

5) DB

  • Write simple query that joins 2 tables via a 1-to-N relation that contains a filter and a group by clause.
  • Explain what is a Transaction.
  • What are the properties of a transaction (-> ACID)
  • Explain concepts as Primary Key & Clustered Index and how these concepts relates?
  • Is a GUID a good Clustered index, explain why?


B) Architect

  • List and explains the Enterprise Integration patterns, provide advantage/inconvenient for each of them? ->(Primary integration patterns: Database, WebServices, Messaging)
  • What are non functional requirements, provide some examples (e.g. Accessibility, Availability, Security…)?
  • Explain concept Authentication/Authorization how does these concept relates?
  • What is Asynchronous Messaging - what type of infra do you need to set it up?
  • Explain – what is an ESB?
  • What is SOA & list and explain SOA Tenets?


C) Senior Developer / Team Lead

  • What is IOC - What is the Goal - which frameworks do you know?
  • Explain what are Unit tests and Integration tests, what differentiate these two types of tests?
  • Provide a small list of programming practices that you would enforce/setup in your dev team?
  • What is Waterfall/Prince2/RUP/Agile/XP/Scrum - how does these concepts relates ?
  • What is DDD?




Some other useful/funny resources:




Prism Walkthrough Part 4: Use Delegate Commands

The final source code can be downloaded here!

In this post we’ll bind a Command to our Menu so that it’s able to add views to the MainRegion.

Create a MenuViewModel:



Insert following code into the MenuViewModel:

   1:  public class MenuViewModel
   2:  {
   3:      private readonly IRegionManager _regionManager;
   4:      private readonly IUnityContainer _container;
   6:      public MenuViewModel(IRegionManager regionManager, IUnityContainer container)
   7:      {
   8:          this._regionManager = regionManager;
   9:          this._container = container;
  10:      }
  11:  }


Here we created our first ViewModel that will be the target of our View binding.   Our View reference our ViewModel but the ViewModel does not need a reference to a view. The view binds to properties on a ViewModel, which, in turn, exposes data contained in model objects and other state specific to the view. The bindings between view and ViewModel are simple to construct because a ViewModel object is set as the DataContext of a view. If property values in the ViewModel change, those new values automatically propagate to the view via data binding. 


When implementing MVVM you need to bind the View and ViewModel, therefore you have the choice between several options.  You can declare the ViewModel as a resource in your view xaml, you can also use  a presenter class that is responsible to instantiate and bind the View to the ViewModel.  This strategy is useful when you need to bind different Views to the same ViewModel.  Because we don’t need this flexibility here we chooses for a simpler design; here it’s the view itself that instantiate and bind to his ViewModel.  Some could claim that I’m not implementing the pure MVVM pattern as in this application the View knows his ViewModel.  I nevertheless chooses for this approach because it’s the simplest way to implement MVVM and also because it enable me to handle UI events like KeyboardPress events gracefully  (see folowing post). 


In this design, the ViewModel, never the View, performs all modifications made to the model data. The ViewModel and model are unaware of the View but the View reference his ViewModel.  This design still provide loose coupling in the sence that the ViewModel does not know about the View but it makes some concessions to the purity of MVVM.  Nevertheless these concessions pays dividends in many ways, as you will see in the next series.


To setup this binding update the MenuView class:


   1:  public partial class MenuView : UserControl
   2:  {
   3:      public MenuView(IRegionManager regionManager,IUnityContainer container)
   4:      {
   5:          InitializeComponent();
   6:          this.DataContext = new MenuViewModel(regionManager, container);
   7:      }
   9:      public MenuViewModel ViewModel
  10:      {
  11:          get
  12:          {
  13:              return this.DataContext as MenuViewModel;
  14:          }
  15:      }
  16:  }


When the user clicks a MenuItem in the MenuView, a command on the MenuViewModel should execute to display a view in the MainRegion (see line 36 - MenuViewModel).   Here we use the Prism DelegateCommand to implement the Command pattern. 


To retrieve the right View we choose for convention over configuration.  The  LoadViewCommand takes a parameter that is the the name of the View without the suffix View. 

The ViewModel has exactly the same name as the View but ends with ViewModel ->see MenuViewModel line 39.

To implement this convention we need to register the Views with a name parameter via the Unity container in the Module Initialization –> see Coremodule line 8 & 9.


Add the following code to the CoreModule.cs:


   1:  public void Initialize()
   2:  {
   3:      this.RegisterViewsWithRegions();
   4:  }
   6:  protected virtual void RegisterViewsWithRegions()
   7:  {
   8:      this.regionManager.RegisterViewWithRegion(RegionNames.MenuRegion, typeof(MenuView));
   9:      this.regionManager.RegisterViewWithRegion(RegionNames.StatusbarRegion, typeof(StatusbarView));
  10:  }


Update the MenuViewModel:


   1:  public class MenuViewModel : INotifyPropertyChanged
   2:  {
   3:      private readonly IRegionManager _regionManager;
   4:      private readonly IUnityContainer _container;
   6:      public MenuViewModel(IRegionManager regionManager,IUnityContainer container)
   7:      {
   8:          this._regionManager = regionManager;
   9:          this._container = container;
  10:          this.LoadViewCommand = new DelegateCommand<object>(this.LoadView, this.CanLoad);
  12:      }
  14:      #region PropertyChanged
  15:      public event PropertyChangedEventHandler PropertyChanged;
  17:      private void OnPropertyChanged(string propertyName)
  18:      {
  19:          PropertyChangedEventHandler handler = this.PropertyChanged;
  20:          if (handler != null)
  21:          {
  22:              handler(this, new PropertyChangedEventArgs(propertyName));
  23:          }
  24:      }
  25:      #endregion
  27:      #region LoadViewCommand
  28:      public DelegateCommand<object> LoadViewCommand { get; private set; }
  29:      public event EventHandler<DataEventArgs<string>> LoadedView;
  31:      private bool CanLoad(object arg)
  32:      {
  33:          return true;
  34:      }
  36:      private void LoadView(object obj)
  37:      {
  38:          IRegion mainRegion = this._regionManager.Regions[RegionNames.MainRegion];
  39:          string viewName = obj.ToString() + "View";
  40:          var view = this._container.Resolve<IView>(viewName);
  41:          mainRegion.Add(view,viewName);
  42:          mainRegion.Activate(view);
  43:          this.OnLoadView(new DataEventArgs<string>(obj.ToString()));
  44:      }
  46:      private void OnLoadView(DataEventArgs<string> e)
  47:      {
  48:          EventHandler<DataEventArgs<string>> loadHandler = this.LoadedView;
  49:          if (loadHandler != null)
  50:          {
  51:              loadHandler(this, e);
  52:          }
  53:      }
  54:      #endregion
  55:  }


Bind the LoadViewCommand in our MenuItem.xaml:


   1:  <Menu Name="menu1">
   2:      <MenuItem Header="File">
   3:          <MenuItem Header="New"  CommandParameter="CreateFile" Command="{Binding Path=LoadViewCommand}"/>
   4:          <MenuItem Header="Folder"  CommandParameter="CreateFolder" Command="{Binding Path=LoadViewCommand}" />
   5:      </MenuItem>
   6:  </Menu>




You should be able to run the application and when you click the menu File, you should see :




This end the Walkthrough series.  In these 4 parts we setup the foundation of our client application implementing the MVVM pattern and learned how to use Prism to create a modular architecture.  


In the following posts I’ll provide a complete application build on the architecture described in part 0 -> (WPF/WCF/EntityFramework).   The application extends this basic design and provide an example on how to use the asynchronous behavior of web services to create responsive applications.



kick it on