Continuing with my efforts to showcase how to create end-to-end applications using nRoute, this time we have a Windows Phone 7 (WP7) based board game called Square Away. It is actually one game out of a multi-game application I’m creating for WP7, and is based on the “Bubble Breaker” theme. To create the game we’ll use the MVVM pattern, creating all the three triads and then use nRoute to bring together everything into one squarely game.

Squares

A word of caution, this is not a super optimized application and is clearly designed to showcase what nRoute has to offer rather than creating an end-user application.  More...

Posted by Rishi on 18-Jul-10 1:17 PM, 18 Comments

Couple of days ago I published a sample app in Silverlight that fronted Netflix’s oData API – well, now I’ve ported the same app into WPF again making use of nRoute Framework. It like before demonstrates how you can build an end-to-end application using nRoute’s navigation framework and MVVM related features-set on WPF. 
 nNetflix2
nNetflix1

As this is just a port, the preceding Silverlight based step-by-step guide is fully applicable here; besides templating and some implementation details the through-process is about equivalent – and so in this post I won't go through the nitty-gritty of designing the app, rather I’ll just discuss the broader ideas, issues I faced, and changes I had to make to up-port it to WPF. More...

Posted by Rishi on 11-Jul-10 11:48 AM, 22 Comments

Let me expand on the title, with this post we will build an iPhone-styled Sudoku Game application in Silverlight using nRoute Toolkit. In terms of the architecture we will make use of MVVM design techniques in having separate Model, ViewModel, View plus related Services - and we'll piece them together in a loosely-coupled manner. As a starting point, we'll make use of a Sudoku puzzle-generating engine from an existing Siverlight implementation by Lee Saunders, upon this we will build our MVVM friendly layers.

SudokuPreview the Sudoku Application here

Application Model

In Lee Saunders' Sudoku implementation the puzzle-generating engine asks for an expertise level, and in return it hands over two arrays of string type that represented the incomplete and completed puzzle. However for a proper MVVM design that is not adequate, and so we have to encapsulate the puzzle in a proper model that enables both binding and serialization of the puzzle. Post churning, the resulting Application Model, shown below, has two principle concepts - a "Game" which is the puzzle board as such, and the "Box" which is an individual playable square of the board. Each Box type is uniquely indentified using a row and column placement on the Board, and per the Sudoku concept each Box can either be a given or must be user specified - so accordingly we have the IsPredefined property and a SuggestedValue property that holds the user's input. The ExpectedValue property holds the required/correct value, and the possible Suggested and Expected values are constrained using the BoxValue enumeration. The GameLevel enumeration holds the user specified expertise level.

Application Model

 ViewModel (VM)

Given we have the Model part of MVVM, we proceed to the VM - the main thrust of the VM is two fold, one expose the Game data for UI consumption, and two expose the Game-related functionality as UI consumable ICommands. And we do both, as shown below, with our GameViewModel class. Note we are using nRoute Toolkit specific implementations of ICommands.

GameViewModel

In terms of the implementation, the first thing we do is earmark the GameViewModel class as being ViewModel of the GameView UserControl - see the MapViewModel attribute. Also note, the ViewModeBase is an optional helper class that just implements INotifyPropertyChanged and exposes a method to use the same. Next, we expose the Game model via the Game property in the VM - this provides us access to the Boxes that make up the board in the UI. Following that, we have a series of ICommands like NewGame, Reset, Hint, Confirm etc that basically mirror the functionality in the model. And we also enable saving and restoring of a game in the IsolatedStore via the SaveGame and RestoreGame commands. We also have one Reverse Command (which are basically ICommands that execute in the View and are triggered from the VM), the ViewBoardReverseCommand, that basically allows the VM to instruct the View to show the board visuals when required (a sample case is when we restore a Game from the IsolatedStore, the VM asks the View to show the board visuals immediately).

I'll also point out that the distinction between ActionCommand and ActionableCommand - the later allows us to specify a pre-condition to the execution of the ICommand. So for example, the SaveGame command is declared as follows:

   1: SaveGameCommand = new ActionableCommand(
   2:     () => IsolatedStore.SaveDataObject(Game, FILE_NAME), 
   3:     () => Game != null)
   4: .RequeryOnPropertyChanged(this, () => Game);

Line 2 is the execution handler of the ICommand, which in this cases saves the current Game in the IsolatedStore, and in Line 3 we specify a pre-condition to the execution which says that the Game should not be null - this as shown below has repercussion in the UI. And in Line 4 we use an extension method for ICommands to declare that whenever the Game property (of our INotifyPropertyChanged implementing) VM (i.e. this) changes, then re-evaluate the executable state of the command.

SaveGameView

View

For our View we have basically divided the functionality into two screens named Home Screen and Game Screen, these screens are implemented as Visual States of the User Control. Peppered on the screen are various functional elements that trigger various commands we have defined in our VM - for example the "Confirm" element corresponds to ConfirmCommand in the VM, similarly the "Easy" element triggers the NewGameCommand with an "GameLevel.Easy" enumerated parameter. Note, to keep things light and to my preference, all button like elements in UI are actually Border controls rather than Button controls, however you could change that if you like.

Two Screens

Now to automagically inject the appropriate VM we drop the BridgeViewModel behavior onto the UserControl (see below) and optionally, if we wanted, through the same behavior we could also specify some control-lifetime related commands against the VM (eg. command to trigger when the User Control is loaded).

States And BridgeViewModel Behavior

In the Game Screen, the 9x9 board is an ItemsControl bound to the Game.Board property from the VM, and the ItemsControl's ItemsPanelTemplate is a custom Grid control with 9 columns and 9 rows. Further, the ItemsControl's ItemTemplate shows either a Grey'ish Border (i.e. pre-defined value) or an interactive Blue'ish Border (i.e. user-defined value) control. We position each item in the grid using a custom "SetParentGridPos" behavior which binds the grid position to the Col and Row property of the Box Type from our Model. And to enable user specifying the Box value, we rig the Blue'ish Border control to trigger SetBoxValue command in our VM. However to enable the use of the command within the DataTemplate, we need to relay it from our VM - so we first we declare a static RelayCommand, and then bridge the relay from our VM, that is done using the BridgeCommandBehavior (again see the screenshot above).

ViewServices

You can think of ViewServices in nRoute as services that are implemented visually - and here we have two such ViewServices, one that shows messages and another one that get a user's input.

ViewServices

Above are the visual interpretations, but the VM actually uses something like this:

ViewServicesInterfaces

In our app, both these interfaces are implemented in the code-behind by the GameView type UserControl. Now there are many other ways to do this, but I am comfortable with what is essentially a visual implementation to be implemented within the View's code-behind. Also, because the VM doesn't take any hard-coded dependency on the View, you can change the visual implementation at any point as long as the defining contract remains the same.

   1: [MapViewService(typeof(IBoxValueViewService), 
   2:     Lifetime = ViewServiceLifetime.DiscoveredInstance)]
   3: [MapViewService(typeof(IMessageViewService), 
   4:     Lifetime = ViewServiceLifetime.DiscoveredInstance)]
   5: public partial class GameView 
   6:     : UserControl, IBoxValueViewService, IMessageViewService
   7: {
   8:     //  IBoxValueViewService and IMessageViewService implementations..
   9: }

Above we use the MapViewService attribute to earmark the GameView type as the concrete implementation of both ViewServices, also note we are setting the ViewService's Lifetime to be "DiscoveredInstance", which means nRoute will look for the implementation in the VisualTree at runtime. And in terms of using the ViewServices in the VM, we use the ViewServiceLocator static class as such:

   1: var _messageViewService = ViewServiceLocator.GetViewService<IMessageViewService>();
   2: _messageViewService.ShowMessage(message);

Bootstrapping

One last point, to use nRoute you need to bootstrap it by adding it to the application's ApplicationLifetimeObjects collection, so in App.xaml we need to something like this:

   1: <Application  ...
   2:     xmlns:nRoute="clr-namespace:nRoute.ApplicationServices;assembly=nRoute.Toolkit">
   3:     <Application.ApplicationLifetimeObjects>
   4:         <nRoute:nRouteApplicationService />    <!-- BOOTSTRAP nRoute -->
   5:     </Application.ApplicationLifetimeObjects>
   6: </Application>

Summary

So here what we've got is an end-to-end example of using nRoute to develop a MVVM type application, right from the ApplicationModel to the ViewServices. Further, by cleanly delineating the various application parts and using nRoute to bring them together we usefully get a loosely-coupled but cohesive application.

You can view the Sudoku Application here,
and download the source code from Codeplex

Update (24-1-2010):

I updated the application to show a waiting indicator (by Chris Anderson) when creating the puzzle, as it was taking an inordinate amount of time. I also moved the new game generation code into a separate service (see IGenerateGameService), which makes use of a background worker thread so the UI should be a bit more responsive.

Following up on Part I which described the workings of the Resource Locator Framework (RLF), in this post we will create a search application that uses the RLF to collate search results from various RSS-feed providers. The RFL will be used to earmark and resolve (at runtime) all the various providers, and results from which will be displayed in a tabular format using a MVVM type solution. Additionally, we'll make use of Rx-framework like Observables to asynchronously gather and compose search results.

ResourceLocatorSampleSmall  View the sample application here and the source code is also available at Codeplex.

Getting The Search Providers Results

In our sample application the provides are essentially search-engines that output results in RSS-feed format, and within our application they are represented by an ISearchProvider interface (shown below). The search results are materialized into the SearchResult type, which corresponds to an RSS-feed item and has Title, Description, Dated and Url fields. Further, for searching a provider takes the search keywords, and returns an IObservable - using which we can have the results asynchronously pushed to us.

SearchProviders

The IObservable/IObserver pairing is also very simple, just to recap for those unfamiliar - you can think of the Observable as the publisher and Observer as the consumer. When the consumer wants to consume, it subscribes to the publisher and the publisher can do three specific things - push a series of values (of an agreed type i.e. type T, via the OnNext method), indicate that it is done (via the OnCompleted method) or if an error were to occur relay that (using the OnError method, which also stops the process). Further, when we subscribe we get an invoke-able token (IDisposable type) which the consumer can (prior to completion) use to opt-out/unsubscribe from the publisher's output.

ObservingProcess 
Now in our case, the ISearchProvider is the publisher, which when asked (using search keywords) publishes a series of search results to which we subscribe. And in our sample we have realized the publishing-consuming using nRoute's build-in IObservable<T> and IObserver<T> implementations called RelayObservable<T> and RelayObserver<T> classes. Below is the outline of ISearchProvider's Search method's implementation which pushes the WebClient's response to the RelayObserver<T>'s  subscribers.

   1: var _observable = new RelayObservable<SearchResult>();
   2: ...
   3: _webClient.DownloadStringCompleted += (s, e) => 
   4: { 
   5:     if (e.Error != null)                      // incase of an error
   6:         _observable.OnError(e.Error);
   7:     else if (e.Cancelled)                     // if cancelled we indicate completed
   8:        _observable.OnCompleted();            
   9:     else {                                    // else, we parse and push the results
  10:         ParseAndPushResults(e.Results, _observable.OnNext); 
  11:         _observable.OnCompleted();            // we also indicate we are done
  12:     }
  13: }
  14: ...
  15: return _observable;                           // return the observable
 
On the other end of the stick, when we want to consume the output of the publisher above we have to subscribe - and for that we can either use a RelayObserver<T> or equally use the Subscribe extension method on any IObservable<T>. So below we are subscribing to the ISearchProvider's Observable and thereon we handle the three possible return cases. Also note the cancellation token (IDisposable) variable which we keep around incase we want to cancel. 
 
   1: var _cancellationToken = _searchProvider.Search(SearchText).Subscribe<SearchResult>(
   2:             (r) => _results.Add(r),                 // on result
   3:             (e) => ShowError(e),                    // on error
   4:             () => _isLoading = false);              // on completed
 
And that's it - we have a bona fide asynchronous communication archetype to handle search results in our ViewModel. The rest of the job just involves monkey code to marshal the results to the UI. Also note, because Silverlight can't directly access web-based RSS-feeds (unless the sources opt-in), we have got local ASP.NET proxies to go with the providers.

Getting The Search Providers Themselves

Given we know how to get the search results, our next step is get the providers themselves - and for that we'll create a specific mapping which locates ISearchProvider resources/providers. With the RLF, my general practice to create explicit mappings in a three step process - first create a meta-data class (if needed), create the IResourceLocator, and third create the mapping attributes. We'll cover these steps point-by-point:

Step 1. Create the Metadata Class 

The metadata is many-times optional but in this case we want to get a Title for the search provider and an Icon (path) to go with that. Plus, for ease of use we also store the name of the provider and the implementation type in the meta-class itself.

   1: public class SearchProviderMeta
   2: {
   3:     public SearchProviderMeta(Type providerType, string name, 
   4:         string title, string iconPath) { ... }
   5:  
   6:     public Type ProviderType { get; private set; }
   7:  
   8:     public string Name { get; private set; }
   9:  
  10:     public string Title { get; private set; }
  11:  
  12:     public string IconPath { get; private set; }
  13: }

I think that was painlessly-simple, but the idea is you should be able to use the meta in a strongly-typed fashion.

Step 2. Create the Resource Locator

As you know a resource locator is just an implementation of IResourceLocator interface, and here we have a very straightforward implementation for the search providers.

SearchProviderLocator

Our search provider's IResourceLocator implementation (DefaultSearchProviderLocator class) shown above is quite simple, it returns an instance of the meta-class we created earlier, it also provides the name of the resource, and by initializing the provider-type it can return instances of the provider. Here actually the implementation of IResourceLocator is numbingly-simple but in other cases the Resource Locator can do all kinds of fuzzy things - it's an abstraction that allows each type of resource or even each individual resource to have its own realization strategy. To give you an example of the fuzziness, the default View Services locator in nRoute can look into the Visual Tree and provide you an instance from there or if applicable a resource can opt to register/unregister an instance of itself as it sees fit (see this post for more info).

Step 3. Create the Resource Mapping

The third and final step is to create an attribute that earmarks the resource as being a search provider, for this we have to derive from the MapResourceBase attribute.

MapSearchProviderAttribute

Above our MapSearchProvider attribute in its constructor takes in the name, title and icon path information, using which it creates the meta-class from Step 1. Next, from the base class we override the GetResourceType method which tells the RLF as to which type of resource we are mapping - the answer of course is ISearchProvider type here. Note, the targetType parameter tells us onto which type this attribute is applied on - which in this case has to be our provider type and we duly check for that. We also override the GetResourceLocator to which we return our DefaultSearchProviderLocator from Step 2 - and this then resides in the Resource catalog for ISearchProvider type. I think it is fairly simple, despite the explicit steps involved - however. if you wanted something more ready-to-eat in that case you can use the MapResource attribute or MapService attribute and forge custom mapping.

Earmarking and Consuming The Providers

We've now got the requisite resource mapping and locating functionality in place, and we can just tack the MapSearchProvider attribute and be off to business, so for example:

   1: [MapSearchProvider("BingProvider", "Bing Search", 
   2:         "/nRoute.Samples.SearchProviders;Component/BingLogo.jpg")]
   3: public class BingProvider : ISearchProvider 
   4: {
   5:     ...
   6: }

Now to individually retrieve the BingProvider instance or its locator you can use the following code, note "BingProvider" is the resource identifier name:

   1: // Gets the resource
   2: ResourceLocator.GetResource<ISearchProvider>("BingProvider");
   3: // Gets the resource locator
   4: ResourceLocator.GetResourceLocator<ISearchProvider>("BingProvider");

However, for use in our ViewModel we are interested in getting all the ISearchProvider types registered - not just one. For that we can access the resource catalog (note, the RLF creates individual catalogs per resource type), and we can also listen to any changes as the catalog implements INotifyCollectionChanged. The Resource<T> is a singleton class that holds the catalog, and the ResourceLocator static class helps with resolving, checking for individual resources or their representative locators.

ResourceCataloging

Using the two classes above we get hold of all the locators, and then rig up columns per-provider to show the results - we make use of the metadata held by the locator to display the icon and title of each provider. The locator also acts like a factory for ISearchProvider instances (per search), which we use to get the search results.

Dynamically Getting More Search Providers

The point of mapping using the RLF is that all the resources are discovered and cataloged at runtime, however the fun doesn't have to stop there. RLF also supports dynamically downloading and mapping all earmarked resources within a DLL or XAP file. To demonstrate that with our sample app, we have a two providers housed in an external DLL which on-demand downloaded and mapped - and because the ViewModel is listening changes to the catalog it is immediately reflected in the UI (try the "+ Provider" button). So to download and automatically map resources we use the RemoteResourceLocator class, have a look:

   1: var _remoteResourceUri = new Uri("nRoute.Samples.SearchProvidersEx.dll", UriKind.Relative);
   2: var _resourceLoader = new RemoteResourceLoader();
   3: _resourceLoader.LoadResource(_remoteResourceUri);
 
Alternatively, you can download assemblies/xap-packages yourself and map each assembly (which is the unit of mapping, as it were) using the AssemblyMapper static class. Note, when we map we not only map the Search Providers but all kinds of earmarked resources like Services, Modules, ViewModels, ViewServices etc.

Summary

The point of this sample application was to show how you can at runtime discover and resolve resources using the RLF. Further, by creating custom resource mapping/locators, we were able to precisely materialize resources along with the metadata associated with each individual resource. The process of creating custom mappings involved creating a meta-class, followed by a resource locator (which owns the materialization strategy), and lastly a mapping attribute which brings together the two. We also have the ability to dynamically load remote resources using the build-in loaders, and any earmarked resources therein are automatically registered.

You can view the Sample App here.
and you can download the Sample App source-code here.

Note, for the sample project be sure to build the nRoute.Samples.SearchProvidersEx before running the project (it sends the DLL to the Web Project) and set the Web Project as your startup project.

Posted by Rishi on 04-Jan-10 10:01 AM, 10 Comments

Categories: nRoute, Code, Silverlight