Up MVVM
DevForce 2010 Resource Center » Code samples » Additional code samples » MVVM » BookShelf: the PDC 2010 MVVM sample with DevForce (Silverlight)

BookShelf: the PDC 2010 MVVM sample with DevForce (Silverlight)

Last modified on November 28, 2011 19:42

John Papa unveiled the "BookShelf" (aka "BookClub") application at PDC 2010 in a talk titled Kung Fu Silverlight: Architectural Patterns and Practices with MVVM and RIA Services

The same application was featured prominently and repeatedly at the December 2010 Firestarter; every session was recorded and both John's and Dan Wahlin's sessions are worth watching.

John gives a thoughtful explanation and demonstration of the Model-View-ViewModel pattern in working code. He has a great teaching style that is intelligent, approachable, and not the least dogmatic. We urge you to watch either (or both) of his one hour videos if MVVM is new to you and if you want a guided tour of the "BookShelf" application.

John designed the application to be indifferent to the modeling and persistence framework. Almost all interactions with the "backend" are abstracted behind a "BookDataService". The UI layers sit "above" the persistence framework, relying upon the BookDataService to retrieve and save BookShelf data.


Problem

John built the demonstration application using the WCF RIA Services framework. We, at IdeaBlade, thought you’d like to see this application with DevForce under the hood instead.

Solution

C#

We migrated BookShelf to DevForce so you can compare RIA and DevForce in an MVVM setting. The application is tiny (3 screens, 4 entities) and simple but you can begin to see how DevForce makes it easier to build a full fledged, distributed Silverlight application. In the conversion process, we repaired some flaws and tidied up architectural details. We weren't trying to be picayune (it's a demo for Pete's sake). Mostly we wanted to create a little space to show some DevForce capabilities.

Here is a snapshot of the some of the improvements: 

  • Error handling added to the BookDataService API
  • The Edit and Submit buttons are disabled after logout
  • Cancelling the Book Editor rolls back changes to the current book
  • No more multiple confirmation dialogs that freeze the UI
  • The Book Editor is independent of the BookView and the BookViewModel
  • Book Editor launched directly, without Messenger involvement
  • Security rules applied in the ViewModels, not hidden in xaml resource binding
  • Less (sometimes nothing) in the View code-behind files
  • No DomainService to fail or maintain
  • Automated tests pave the way for future improvements with fewer regressions

Along with the demo you will find a document describing the steps to migrate incorporates these recommendations.

Ward Bell presented a talk on MVVM concepts and implementation at the Bay.Net Users Group on 12 January 2010 that referenced this Bookshelf application sample. Download the PowerPoint presentation.

VB

The VB version attempts to be a straightforward  translation of the C# version.  However, there are some differences:

  1. The iterator approach to batching asynchronous tasks is a popular choice in C# and is the approach used in the C# version of BookShelf. That choice is not available to Visual Basic.NET programmers because iterators aren't implemented in VB.NET. Fortunately, you can still use the DevForce Coroutine class in VB to manage a sequence of asynchronous tasks. Instead of writing an iterator to produce the sequence, you construct a list of functions that return INotifyCompleted and pass the list to the Coroutine.  Since, it is not possible to use the standarad coutines in VB, use function lists instead.  This the approach used in this solution.  For example, look at this code in "RegisterUserCore" which builds a List(Of Func(Of INotifyCompleted)) to register a new user:
    VB
    Private Function RegisterUserCore(ByVal coop As CoroutineOperation, ByVal user As RegistrationData, _
     ByVal password As String, ByVal loginRegisteredUser As Boolean) As IEnumerable(Of Func(Of INotifyCompleted))

     ' Set up a list of functions to perform async (and sync) activities.
     Dim operationList = New List(Of Func(Of INotifyCompleted))

     ' Create the user.
     Dim f1 As Func(Of INotifyCompleted) =
          Function()
           ' Call a server-side method.  Note type name must be fully-qualifed:  MyNamespace.MyClass, MyAssemblyName
           Dim typeName As String = "BookShelf.RegistrationServices, BookShelf.Web"
           Dim methodName As String = "CreateUser"
           Return Manager.InvokeServerMethodAsync(typeName, methodName, Nothing, Nothing, user, password)
         End Function
      operationList.Add(f1)

     ' Check the results from the first operation when it completes.
     Dim f2 As Func(Of INotifyCompleted) =
          Function()
           Dim baseOp = DirectCast(coop.Notifications.First(), InvokeServerMethodOperation)
           Dim result = TryCast(baseOp.Result, CreateUserResult)
           If result.Status <> CreateUserStatus.Success Then
             Return Coroutine.Fail(New RegistrationException(result))
           End If
           Return New NoOp()
         End Function
      operationList.Add(f2)

     ' Optionally login (after first logging out current user).
     If loginRegisteredUser Then
       Dim f3 As Func(Of INotifyCompleted) = Function() Manager.LogoutAsync()
        operationList.Add(f3)

       Dim f4 As Func(Of INotifyCompleted) = Function() Manager.LoginAsync(user.ToLoginCredential())
        operationList.Add(f4)
     End If

     Return operationList

    End Function
  2. VB has problems with "Optional" arguments (especially when used with the "Implements" key word). Accordingly, some of the methods in this application were modified to not use "Optional".
  3. The DevForce code generator will not generate a "Namespace" directive for a VB project. Therefore, in  order to keep the namespaces the same in the C# and VB solutions, it was necessary to break up the VB client and server projects that contained the generated code into two separate projects. In the C# solution, the "BookShelf.Web.Models" namespace is created using a "Namespace" directive in the BookClubModel.IB.Designer.cs file. In the VB solution, the "BookShelf.Web.Models" namespace is created by setting the root namespace in the BookShelf2 client and BookShelf.Web2 projects.

vbnamespace.png

Prerequisites

Both versions assume Silverlight 4 and .NET 4. Visual Studio is essential and Blend is highly recommended.
You must have installed DevForce 2010 version 6.0.7 or later (the free version is fine) to build and run BookShelfDF.

Created by DevForce on December 10, 2010 12:24

This wiki is licensed under a Creative Commons 2.0 license. XWiki Enterprise 3.2 - Documentation. Copyright © 2012 IdeaBlade