Creating and Porting applications to Cloud Light

Posted by Rishi on 25-Jan-10 11:43 PM - Comments (2)

Cloud Light as you know is a small Silverlight-based runtime that hosts, manages and runs cloud-based applications - and with this post we'll look at how you can either create or port existing Silverlight application to run on Cloud Light. Technically there is not much of a difference between a normal Silverlight application and one that runs in Cloud Light, the main divergence is around around how we "declare" and "define" an application. In Cloud Light all application packages (xap files) are first downloaded then probed for any "declared" applications, once found the corresponding application "definitions" are used initialize the application as required. This business of "declaring" and "defining" applications in Cloud Light is materialized via two interfaces, which is what we'll look into this post by porting the iPhone'ish Sudoku Application (from my previous post) to run in Cloud Light.

Cloud Light SudokuSudoku running in Cloud Light

Declare and Define

So the two interfaces to declare and define a Cloud Light application are IAppMeta and IApp - implementation wise, they are really quite simple, have a look:

IAppIAppMeta

IAppMeta implementation is like a declaration of an application - the Cloud Light runtime looks for IAppMeta implementations, which it then initializes and holds onto. These IAppMeta instances, provides two things, one meta-data info like Title, ShortTitle, and IconPath which is used in the UI (like in the ApplicationBar etc), and second it helps with instances of the application (see the CreateAppInstance method).

In similar vein to the Application class in Silverlight, IApp implementations are Cloud Light definition of an application. And again just like the Application class, it helps with the main visual of application (i.e. RootVisual) - note, in this case it has to be a FrameworkElement derivative. Further, the IApp interface also features call-in methods that are used to notify the application as to when it's starting or closing within Cloud Light (i.e. the AppStarting and AppClosing methods). And somewhat unconventionally, an IApp implementation is also delegated with the  task of showing/hiding the application itself (via the AppShow and AppHide methods) - this sort-of also helps when you want to customize the show/hide animation and when there are Child Windows involved.

Also its worth mentioning that owing to the 10KB limit for designing Cloud Light the application API here is quite minimalistic, for example there is no cancellable mechanism when shutting down an application. Further, application/runtime interaction is also limited, it's not quite feature-rich as you expect with a desktop sort-of an environment.

I (Sudoku) App

Now, given a Cloud Light application's requirements, we'll take the Sudoku application's source-code and in a step-by-step manner port it to Cloud Light (note you can download the source-code for the ported application, it's attached below):

  • Sudoku IconTo start with, we need to add reference to Orktane.AppModel.dll assembly, it contains both the IAppMeta and IApp interfaces. You can download it from the bottom of this post
  • Next, since we are not going to use App.xaml anymore we can just delete it
  • To represent the application in Cloud Light we need to have an icon for it - for this port I've created the one shown on the right. The minimum size required is 64x64 pixels, but you can have something larger as it would just scale down. Note the icon must be in PNG format, as that is the only image format that supports alpha transparency in Silverlight. Obviously, we need to add the icon image to the project, I've added it to a "Resources" folder
  • Now, to define our application we need to add an IApp implementation, for this port I've created one called SudokuApp - and within it we basically serve an instance of the MainPage,xaml as the RootVisual (just like the App.xaml) and when asked to show-hide the application we toggle the Visibility of our RootVisual
  • Next we add an IAppMeta implementation, for this port it's the SudokuAppMeta type - and within its implementation we provide a Title, Short Title, and an assembly-qualified Icon Image path (of the image we embedded), and when asked to create application instance we serve our IApp implementation (i.e. the SudokuApp type)
  • Now, there is one last step, and this is only applicable if you are using nRoute Toolkit (the Sudoku application does). So normally to use nRoute you need to bootstrap it when the Silverlight application starts, but in this case we can't as we don't control the host - to remedy this, I've created an nRoute Toolkit adapted which resides in nRoute.Toolkit.CloudLightAdapter.dll assembly (you can also download it from below), and it allows you to lazily initialize nRoute. However, with the adapter you are also required to individually "map" all the assemblies that make use of nRoute in your application. For example have a look at the SudokuAppMeta class's constructor:
   1: public class SudokuAppMeta : IAppMeta
   2: {
   3:     public SudokuAppMeta()
   4:     {
   5:         nRouteAdapter.Initialize();
   6:         nRouteAdapter.MapAssembly(typeof(SudokuAppMeta).Assembly);
   7:     }   
   8:     // IAppMeta implementation
   9: }

And that's it, we are done porting. Now in some cases depending on your application there might be some aesthetic changes you need/want to make, like for the Sudoku application I've removed the background and put the content in a ViewBox to allow scaling, however I've not added support for dragging the application. 

Installing and Uninstall Apps

Lastly, to install the application you need to use the Console Application, and issue a command like "installapp -url:http://www.orktane.com/Labs/CloudLight/Orktane.Samples.Sudoku.xap" - obviously, substitute the Url with one for your application, but do also remember that the Silverlight's cross-domain communications rules apply. Also if you've got an interesting Cloud Light application, please share it with me and I can put it on the Application-Store listing for everyone to use.

InstallSudoku
And to uninstall an application you can just Ctrl+Shift+Click on the application icon, alternatively you can also use an "uninstallapp" Console based command which takes in a Url just like "installapp" command - so to uninstall the Sudoku application you'll write "uninstallapp -url:http://www.orktane.com/Labs/CloudLight/Orktane.Samples.Sudoku.xap" and then refresh/restart Cloud Light.

Summary

So just to recap, to create/port an application for Cloud Light you need a Xap packaged application with IAppMeta and IApp implementations within it, along with an icon. IAppMeta is like a declaration of application, and IApp is the application definition similar to the Application Class in Silverlight.

Download IApp and IAppMeta assembly (Orktane.AppModel.dll),
Download nRoute Toolkit Adapter (nRoute.Toolkit.CloudLightAdapter.dll),
and Download the source-code for the ported Sudoku Application.

iPhone Sudoku in Silverlight using MVVM

Posted by Rishi on 23-Jan-10 9:27 AM - Comments (5)

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.

Introducing Cloud Light: a 10KB Application Runtime in Silverlight

Posted by Rishi on 13-Jan-10 7:38 PM - Comments (13)

Tags: , | Categories: .NET, Code, Silverlight, Technology

For the Mix10K smart coding challenge, I've create an application runtime that hosts, manages and runs cloud-based applications. The runtime is called Cloud Light, and per the rules of the Mix10K challenge the code and visuals weighs-in less than 10KB. The runtime environment also features an online application store from which you can download and install applications.

Cloud Light ScreenshotView the Cloud Light in the Mix 10K gallery and please vote for it.

Runtime Overview

  • Provides basic window management capabilities like opening, closing, activating, minimizing and restoring of windows
  • Allows you to install applications directly from the web
  • Installed applications information is persistent, with the applications themselves downloaded when the runtime starts
  • Allows you to uninstall applications with a single click
  • You can also install Cloud Light as a Silverlight Out-of-Browser Application (right click and choose "Install Cloud Light.." from the context menu)

Title Bar Overview

The Title Bar shows the active application's title and also show the current date-time. Additionally, it features four buttons on the top-right corner that enable full-screen toggling, showing/hiding of the application store, minimizing of the active application and closing of the active application.TopBar

Applications Store Overview

The online Application Store lists all currently available application in the Cloud. To install any application just click on the entry title, and the application is downloaded and installed - once installed, it should appear in the Application Bar. Going further, more applications will be available through the store.

InstallableApplications

Application Bar Overview

The Application Bar hosts all the currently installed applications, each application getting an icon for itself. The icon also with a highlight represents a running application, and each application can only have one instance running at a go. A single click to an application icon starts the application, if already running it activates it, if previously activated it minimizes it, and if minimized it maximizes and activates it - really simple, right. Also if an application is open, Shift+Clicking the icon closes it and by Ctrl+Shift+Clicking on the icon you can uninstall the application.

AppBar

Extensibility

Apart from the limited applications selection available in the Application Store, you can also create your own applications and install them using the Console application. In a separate post I will detail how you can create your own custom applications and install them.

InstallAppCommandLine

Another simple point of customization is setting the wallpapers, again through the console - so something like "setwallpaper -url:http://adsoftheworld.net/download/windows7/winwall7057_23large.jpg" will change the background into:

CloudLight3

And in addition to the built-in Commands, you can also create custom Console-based Script Commands, and have them automatically register with and be availed through the Console Application (see Silverlight Console).

Summary

So for 10KB worth of c# code and xaml, I think we have a surprising functional runtime that is both extensible and light thanks to Silverlight. It in some-ways can be seen as a prototype for a managed Cloud OS that relies on the Cloud but provides applications in the form we know them today. And in terms of the design it speaks to the simplicity and discoverability that iPhone brought, something that I think needs to be embraced in desktop-applications' designs.

View the Cloud Light in the Mix 10K gallery here
and please vote for it if you like it.

Acknowledgements
Default Grass Wallpaper by Radoslaw Rokita [vathanx@live.com]
Application Icons by Judge

Reverse ICommands for MVVM

Posted by Rishi on 07-Jan-10 5:13 AM - Comments (11)

One of the problems with MVVM designs is the inability of the ViewModel to singularly effect change(s) within the View; yes, you can use data-changes through data-binding as a crude-bludgeon, but I'd rather have the right tools for the right job. And that is where Reverse ICommands come in, they allow you to execute an ICommand in your ViewModel and have it trigger a set of specified action(s) in the View - the reverse taxonomy speaks to the fact that reverse ICommands targets your View rather than the ViewModel.

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

Design: Extends ICommand

In working terms reverse commands are ICommands that acknowledge when they execute - the acknowledgement gives us the ability to respond to them from within the View. Implementation wise, see the IReverseCommand interface, we only add a CommandExecuted event to the ICommand definition.

IReverseCommand

The other part to reverse commands is the ReverseCommandTrigger behavior, to which we can bind our reverse command and associate one or more Trigger Actions to invoke when the associated command is executed. For example, in the Silverlight Console Project the Console definition has a "Beep" method to which we have to make a beeping sound (obviously) - however, the beeping sound playing control lies in our View and we have to trigger it from our ViewModel. So using reverse commands, first in our ViewModel we declare the reverse command property, initialize it to do nothing in our ViewModel (though you can have it do something else), and execute it when asked to beep (the OnBeep method), have a look:

   1: // we define our reverse command as a property in our ViewModel
   2: public IReverseCommand BeepReverseCommand { get; private set; }
   3:  
   4: // and we set it up like this in our ViewModel
   5: BeepReverseCommand = new ActionCommand(() => { });
   6:  
   7: // we handle Beep call request in our ViewModel and Execute the reverse command
   8: protected override void OnBeep() {
   9:     BeepReverseCommand.Execute();
  10: }

Then in our View, the XAML features the Media Element control and a reverse command Trigger which plays the media:

   1: <!-- We define the sound playing Media Element -->
   2: <MediaElement x:Name="beepAudioMedia"
   3:     Source="/Resources/beep.wma" Volume="1" AutoPlay="False"/>
   4:  
   5: <!-- And we set up Reverse Command Trigger to play the media -->
   6: <nTriggers:ReverseCommandTrigger ReverseCommandBinding="{Binding BeepReverseCommand}">
   7:     <Behaviors:PlayMediaElementAction TargetName="beepAudioMedia"/>
   8: </nTriggers:ReverseCommandTrigger>

As you can see, the workflow of reverse commands is very similar to regular ICommands, except we reverse the receiver/sender roles - the ViewModel here explicitly triggers the Command by calling execute, and the View hooks up Actions to go with the execution of the Command. Also note, all the ICommand implementations in nRoute are reversible because they all implement IReverseCommand - so you can use them as regular and/or reversed commands.

Usage: An Example

The attached sample application is really very simple, it basically has three screens and we control the flow and interaction between them from our ViewModel using ICommands and IReverseCommands. The three screens are realized as Visual States on the View and, as shown below, the Home Screen helps get a user's response to a question, the Trailer Screen shows a movie trailer and the Message Screen self-descriptively shows a message.

 SampleAppViewViewModel

Within our ViewModel, the Home command navigates to the Home Screen, the PlayPause command toggles the pause-state of the trailer, the Response command gets the user's response from the Home Screen. The reverse commands help navigate between the screens by changing the Visual State of the View, and the play/pause reverse commands do as they suggest. The idea here is to show how from within the ViewModel we can, without direct dependencies, control the View - like when we navigate away from the Trailer Screen we pause the movie and when we enter into the Trailer Screen we resume the movie all from the ViewModel. Even the playing state of the trailer is kept within the ViewModel, similarly when we get the initial question's response the ViewModel decides which screen to navigate to, and if appropriate which message to show. All this builds on the separation of concerns principle, and though the functionality here is petty, the application of ICommands and IReverseCommands helps us manage the View-ViewModel interaction in both directions.

Summary: ICommands Reversed

ReverseCommandsModel

Per the principles of MVVM, in SL, we have two primary ways of communication between the View and the ViewModel - one, data-changes signifiers that rely on data-binding, and two, ICommands based invocation of actions from the View. Data-changes as a mechanism for inter-communication works for some cases, but in other cases it is too implicit and imprecise, and this is where ICommands weigh in - they are good for explicit, loosely-coupled, and strongly-typed invoking of actions. However ICommands are one-way creatures designed to be invoked from the View, and handled within the ViewModel.

On the other end, invoking of actions from the ViewModel-to-View is the functional gap that IReverseCommands fulfill, and just like ICommands they are explicit, precise and strongly-typed. Further, as with ICommands you also get ICommands-associated functionality like can-execute checks, enabling-disabling of ICommands, and explicitly defining of dependencies like in nRoute. Now, technically there might be many ways to achieve what reverse commands do but for me the fact that here we have a loosely-coupled setup which makes use of the binding infrastructure in SL and extends one the primary communication mechanism to work in reverse is a handsomely meriting solution.

You can view the Sample App here,
you can download the Sample App source-code here,
and read about the rich support for ICommands in nRoute here.

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.

Value Converter and Command Relays for Visuals-Related Logic

Posted by Rishi on 25-Aug-09 9:06 AM - Comments (4)

Tags: , , , | Categories: .NET, nRoute, Code

If you've done any amount of development with MVVM, one of the things you'll hate most is creating Value Converters and Commands for the smallest of things - especially for things like formatting, placement, visibility etc. And a lot of the times, these converters and commands are pertinent only to the View itself, but have to be declared on a module-wide basis. So as a solution, I've created "relays" for exposing IValueConverter and ICommand, which allow the logic to be defined in the code-behind (or ViewModel if you prefer), without having to create extraneous/individual classes.

Simple Example : Value Converter Relay

In one of my apps, I have a play/pause type of functionality which required a button to display either the play or pause sign, which is controlled by a "IsPlaying" property in the ViewModel. Now, the IsPlaying property is bool type, and we display the play/pause sign using the Webdings font in text. Normally, for this smallest of functionality, one would have to create an IValueConverter implementation and declare it in xaml, then consume it with binding. But with the relays we just declare a relay in xaml and then define the functionality in the code-behind, without having to create any specific class - have a look:

In XAML (with cmpnts being the xmlns declaration)

   1: <cmpnts:ValueConverterRelay x:Key="PlayPauseTextConverter" />

and in the code behind we write this

   1: this.SetResourceConverter<bool, string>("PlayPauseTextConverter", (b) => b ? ";" : "4");
 
and the button uses the converter, as usual
 
   1: <Button FontFamily="Webdings" Content="{Binding IsPlaying, 
   2:     Converter={StaticResource PlayPauseTextConverter}, Mode=OneWay}" />

Compared to the normal parade, this is much more immediate and compact - though for MVVM purists it might be polluting the code-behind. For my tastes, this works perfectly well and has a couple of advantages too - for one, it is strongly typed, allows lambdas/delegate based conversion, it enables referencing to and use of locally-scoped elements/variables and keeps the UI-related trickery close-by.

As far as the markup is concerned you declare every converter as ValueConverterRelay type, just with different keys. And then in the code-behind, using an extension method (on any FrameworkElement type, to which the resource belongs) or alternatively by directly setting the converter we specify the implementation logic. Note we can specify both "convert" and "convert back" IValueConverter calls equivalents using the SetResourseConverter extension method or equally specify a non-generic implementation.

Another Example : Command Relay

The companion to the converter relay, is the command relay type - and it is basically similar in declaration and use.

In XAML (with cmpnts being the xmlns declaration) we define a CommandRelay resource

   1: <cmpnts:CommandRelay x:Key="SelectContactCommand" />

and then in the code-behind something like

   1: this.SetResourceCommand<ContactInfo>("SelectContactCommand", (c) => OnSelectContact(c));

To consume the commands, as shown below, I'm making use of nRoute's attached behaviours to hook-in the commands to the user-control's MouseLeftButtonDown event

   1: <DataTemplate x:Key="ContactTemplate">
   2:    <view:ContactView cmd:MouseDown.Command="{StaticResource SelectContactCommand}"
   3:         cmd:MouseDown.CommandParameter="{Binding }"/>
   4: </DataTemplate>

Like before with the converter relay, we declare the command relay in the resources with a uniquely key which we then use to set the implementation in the code-behind - in this case using the SetResourceCommand extension method. Again note the command declaration is strongly typed, and makes use of the generic/delegate-based command implementations I had blogged about earlier.

As a side note, here I've purposely shown the command linking within a data template, because if you were to use a event handler hooked to the code-behind it could potentially leak memory - specially if the host control's life span outlasts that of the templated view (which is often the case, like when you are paging). And the difference in using attached behaviours, if designed properly, is that they hold a weak reference and should be GC'able.

One Complication

But then there is a twist; now, depending on how early in the control's lifecycle you make use of the converter/command, the relay might not be available immediately - particularly when the xaml is just parsed/initialized. And this is a big problem, because it means things would not work initially or worse they would "break" the databinding. In these cases we'll need to handle an "Initialize" event on the command or converter relay, during which we specify the implementation through the event argument - have a look:

In XAML, we hook up the Initialize event (and this shouldn't leak memory as resources normally last the entire lifetime of their hosts, unless you decide otherwise in which case you'll need to clear up any handlers)

   1: <cmpnts:ValueConverterRelay x:Key="CountToIndexConverter" 
   2:     Initalize="CountToIndexConverter_Initialize"/>

In the code-behind, we create and pass-back the converter through the event argument

   1: void CountToIndexConverter_Intitalize(object sender, ValueConverterInitializeEventArgs e)
   2: {
   3:    e.Converter = new ValueConverter<int, double>((i) => i == 0 ? 0d : i - 1);
   4: }

Obviously, this isn't ideal but as far as I know there is no precise way to interject between the resources creation and it's immediate use post-parsing of xaml - but resolving through an event handler works, and for the most part is more convenient than creating individual classes for each specific conversion or command you need.

Summary

So the basic idea here is to enable easy and compact defining and consumption of commands and value converters. However, it must be said, this is not a substitute for ViewModel based commands or general converters, rather my recommendation is to use it for consuming or manipulating visuals-related logic (as opposed to the business-related logic).

The code is attached below, and both these relays form part of the next drop of nRoute (which BTW has many new exciting ideas, stay tuned).

Download Code

A lot of the work I've been doing lately with .NET eventing and stuff comes down to the concept of resource-management - like how do we manage our resources' lifecycles without causing unintended negatives (like memory-leaks or performance issues). On the face of it resource-management is a problem of pluses and minuses, creating and releasing resources per their need - but the fact is, with frameworks like .NET there is so much resources creation and disposing going-on that we figuratively end up managing needles above a haystack.

The Idea: Take'em down with me

More to the point, I have this idea of managing the disposing of resources by creating a persuado supporter-dependent hierarchy of resources - sounds fancy but it is really simple. And the other part of the equation is having an API that isn't too intrusive - this is quite important to me, as I think with tiresome APIs the usefulness whether-away like a new-year's resolution.

In practical terms the disposing of resources is based around this single interface, called IDisposeRelated - which has the following make-up:

   1: public interface IDisposeRelated
   2: {
   3:     event EventHandler DisposeRelated;
   4: }

Basically, you introduce this interface on any object that wants to limit the lifespan of one or more dependent resources to no more than its own - so good candidates include user controls object or event handlers. For example we could, append the IDisposeRelated interface as such:

   1: public partial class Window1 : UserControl, IDisposeRelated   
   2: {   
   3:     public event EventHandler DisposeRelated;    // IDisposeRelated Members
   4:  
   5:     public Window1()   
   6:     {   
   7:         InitializeComponent();
   8:         this.Closing += (s, e) => 
   9:            {if (this.DisposeRelated != null) DisposeRelated(this, EventArgs.Empty);};
  10:     }
  11: }

 

 

All we are saying here is that when closing the user control raise the DisposeRelated event, indicating that you want dependent resources to be brought-down too. Do note, I don't use the word "dispose" in the strict sense as with the IDisposable interface, which relates it to releasing unmanaged resources.

Dependent Resources: Proactively com'n down

Once we have the IDisposeRelated resource defined, we indicate the dependency using (mainly) extension methods - consider two examples:

   1: this.Writer = new StreamWriter(_filePath).DisposeWith(this);
   2: // or
   3: ParentWindow.LostFocus += 
   4:     new RoutedEventHandler(ParentWindow_LostFocus).DisposeWith(this);

In line1 we are creating a new stream writer, to which we append the "DisposeWith" extension method to indicate that it should be disposed off when disposing "this". And "this" would/could be any object supporting the IDisposeRelated interface - so in other words, because the IDisposeRelated interface indicates as to when it wants to dispose related resources, we listen to that and take down any earmarked resources with it. And that's it.

The Take Down

Now, when I say "take-down" resources - the garbage collector would stare blankly first, but basically we know how to do certain stuff like with IDisposable objects we will call the Dispose method or with event handlers we can unregister it. For other stuff or when you want more control you can use another DisposeWith extension method definition that takes an action delegate (with the target passed in) to effect the "take-down" as you specify. For example:

   1: var _cache = new MemoryCache().DisposeWith(this, (c) => c.Clear());

In the case of the cache object above, the "take-down" concept in its context would mean clearing whatever is in the memory. The point being, if we can proactively add this instruction of how to redeem resources whilst creation (though you could still add these instructions later) we won't loose the proverbial needle in the haystack. Further, by earmarking resources by the "dispose with" instruction, we create this persuado supporter-dependent hierarchy.

Technically Speaking

Having specified "dispose with" for an object does not preclude you from disposing it earlier - just later if it hasn't been disposed then it will do it for you. Secondly, the "dispose with" instruction only holds a weak reference to its target, and so it doesn't itself become a memory leak source. Also, you could possibly have more than "dispose with" instructions against a resource and it will be fulfilled in a first-come first-serve basis. Further, the dispose with thing doesn't have to be based on a resource's parent's lifecycle, it could be based on a peer object or on some other domain context - which is why I said a persuado supporter-dependent relationship and not a parent-child one.

Performance-wise, I've not checked because I am still mulling over the validity of the idea. But, I don't think it would be too great of hit, because my current implementation is basically adding a weak handler against the "DisposeRelated" event. All the same, there are other ways to implement the same functionality, so we'll see about the performance.

This current implementation is very basic, possibly in the future, if it is worthy, we could add fancy features like LINQ based dependency evaluation or lazily attach it with a control's lifecycle. For now, it is something simple I am trying in my code, but like in a lot of cases ideas as these comes down to the usefulness v/s inconvenience of the feature.

TRUE: Weak Eventing & Listening for .NET/Silverlight

Posted by Rishi on 29-Jul-09 6:02 AM - Comments (7)

As part of the next drop of nRoute, I've been doing some work around events and listeners in .NET - the main issues have been around memory-leaks, selectively multi-casting events, performance and loose-coupling. Certainly, this is not something new and there are a number of solutions out there, but usability and performance have been the compromises which was something I wanted to avoid.

The Idea : Wrap'em

From my work on it, I take that we don't want the semantics of exposing and using events to change - so basically the the producer and consumer syntax should remains the same, however if the producers and consumers are dumb about it, I suppose we should make the messenger smarter. So here is what I'm mean:

   1: source.SomethingHappened += new WeakHandler((s, e)=>{ . });  
   2: //or 
   3: source.SomethingHappened += new WeakHandler(Handle_Something);  // delegates to a method

On the left the source exposes a "SomethingHappened" event using the EventHandler delegate, and on the right we have a custom class that handles the event - the use API is actually not far off from where we are today. We just changed the normal handlers with the "WeakHandler" class that wraps (not inherits) the actual handler and introduces the logic for weak delegation. In my solution I make use of closures and lifting .NET features to create "self-referencing" event-handler that are aware of their wrappers. It's not that hard, however the benefit is that we can make it do smart things such as respond to say a specific property change on a PropertyChanged event, consider:

   1: source.PropertyChanged += new WeakPropertyChangedHandler( 
   2:    ()=> SelectedItem,  
   3:    SelectedItem_PropertyChanged);

In this case the 'SelectedItem_PropertyChanged' method will only be called when the 'SelectedItem' property changes. And the best part is the listener or consumer is weakly referenced, so it can be available for garbage collection when it has no outstanding references (without having to remove the event handler itself). And if the listener has been disposed off, the handler will de-register itself and dispose off.

The Implementation

Like I said the event handling classes above, like WeakPropertyChangedHandler, are basically wrappers around the actual event handlers - however note, we don't need to create specific event handlers for each and every event type. We have a generic definition that can that can handle every type of event; its constructor signature is a follows:

   1: public class Handler<E, H> 
   2:        where E : EventArgs 
   3: { 
   4:     public Handler(Func<Action<Object, E>, H> createAction, Action<Object, E> action, 
   5:                 Action<H> removeAction) { .. } 
   6: }

The H type is supposed to be your handler type which unfortunately cannot be constrained. All the same, just like every event handler we need to be able to do four things, namely create the handler, attach the handler, handle the event and remove the handler. Now, if you look at the constructor we don't do the attaching part, that's up to the user but for the rest we take in delegates - so a full blown handler can be written as:

   1: Application.Current.MainWindow.SizeChanged += 
   2:     new Handler<SizeChangedEventArgs, SizeChangedEventHandler>( 
   3:     (a) => new SizeChangedEventHandler(a),    // How to create 
   4:     (s, e) => Console.WriteLine("Main Window Size Changed."),  // How to handle 
   5:     (h) => Application.Current.MainWindow.SizeChanged -= h);  // How to remove

I know that is somewhat verbose, however that's the full monty, whereas you have more specific implementations and additional constructors that can do the creation and removing part for you. The other important thing to realize is that the Handle<E,H> type can be paraded around as a named variable, consider:

   1: var _handler = new RoutedHandler((s, e) => MessageBox.Show("GotFocus"));
   2: this.GotFocus += _handler;
   3: // when done
   4: _handler.UnregisterHandler();

Here we create the handler variable, which when done can be specifically called to unregister. I specifically designed this  to call an unregister method rather than have to -= the handler.

The Variants

As you can probably tell we have many different types of handlers, which can generally be qualified into three separate categories (see below). First, we have types deriving from Handler<E,H>, which are basically like normal events wrappers that hold a direct reference to the event listener and have to be manually unregistered. The second category is based on the SingleHandler<E,H> type that only handle the first call and then recuses itself - which might seem strange, but actually they are very useful in handling things like Loaded, Initialized, Errors related events. They save memory, plus ensure you don't end up holding unnecessary references. Lastly, we have the WeakHandler<E,H>based types, which as the name suggests holds a weak reference to the listener and allow for its disposing independent of the event source. Also note, WeakHandler types also allow you to manually call the UnregisterHandler method to discontinue the event handling.

EventHandlers

As shown above, based on the three categories of handler wrappers we have specific types that handle EventHandler<E>, EventHandler, RoutedEventHandler and PropertyChangedEventHandler types of event delegates. They just allow for an easier to use API, however you could resort to the generic types if you wanted too.

Performance

Given the use syntax is very similar to the normal event handlers, the other important use tenant for me is the performance. Lets see how it fares (time in seconds):

Handler Type Action Type 1 Event 10 Events 1,000 Events 10,000 Events
System EventHandler Attach Event 0.0000059 0.0000272 0.0006216 0.0310925
  Raise Event 0.0000041 0.0000102 0.0248883 1.1368489
  Detach Event 0.0000065 0.0000254 0.0148008 0.8415036
Handler<E,H> Attach Event 0.0000852 0.0002054 0.0096227 0.0665443
  Raise Event 0.0000041 0.0000148 0.0522444 3.1837825
  Detach Event 0.0000071 0.0000272 0.0560088 2.7236017
SingleHandler<E,H> Attach Event 0.0000840 0.0001782 0.0098619 0.0592904
  Raise Event 0.0000059 0.0000201 0.0375098 2.2381572
  Detach Event 0.0000065 0.0000236 0.0530667 2.5753320
WeakHandler<E,H> Attach Event 0.00001415 0.0003268 0.0171803 0.1007618
  Raise Event 0.0000840 0.00003208 0.1420596 12.9617411
  Detach Event 0.0000065 0.0000272 0.0558754 2.7769959

Based on the table, the performance of the wrapped handlers have a disadvantage ranging from 1.5x-15x, primarily on the event raising front. Attaching is notably slower, however unless you are doing very processer intensive stuff, I think for most part these are within the range of "acceptable costs", especially for client-side apps like with Silverlight. Also, there are further optimizations to be had, as this is quite early stuff.

Listeners

Now if you like what you have seen, it gets better. Given some of the problems with eventing as it stands, the WPF team rolled out their own implementation based on the Weak Event Pattern. They essentially provided an event manager, a custom event definition wrapper, and a relative simple consumption interface - which all somewhat works like normal events. The consumption interface called IWeakEventListner has the following signature:

   1: public interface IWeakEventListener
   2: {
   3:     bool ReceiveWeakEvent(Type managerType, object sender, EventArgs e);
   4: }

The weak event pattern is performant, but the provider side requirements of obscure per-event setup, registration and the middle men solution are all a bit clumsy. So how about if we could attach IWeakEventListner implementation to normal event handler defined events, something like this:

   1: source.SomethingHappened += new WeakListener(weakEventListnerObj);
   2: // or 
   3: source.PropertyChanged += new WeakPropertyChangedListnerHandler(
   4:     () => Items,
   5:     weakEventListnerObj);
 
Here the "SomethingHappened" is a normal event defined by the EventHandler signature, and we attach a handler that directs the handling to the a class instance implementing IWeakEventListner. The use semantics are just about the same as with normal events, and you can also detach the same by using the UnregisterMethod. You need no special registration, event-definition class, or manager, just do as you always did but with the given handlers types and it works with every event out there.
 
The Variants
 
And just like the event wrappers above, we have three categories of listeners shown below:

Listeners
 
The use semantics are basically similar to what I showed earlier, the only difference being we need to pass in an instance of IWeakEventListener rather than a delegate to handle the event. Further, because Silverlight doesn't have an build-in IWeakEventListener interface, I've provided one to compile with Silverlight whereas in the full-blown .NET version you would/can use the WPF defined interface. Also since we don't have a "managerType" as specified by the RecieveWeakEvent method, we pass in the type of EventHandler - so for a property changed event you will get the PropertyChangedHandler type passed in as the managerType. Further, by returning false you can unregister from the event and the wrapper will dispose itself.
 
Performance
 
Listeners with event handlers numbers (in seconds):

Handler Type Action Type 1 Event 10 Events 1000 Events 10,000 Events
System EventHandler Attach Event 0.0000059 0.0000272 0.0006216 0.0310925
  Raise Event 0.0000041 0.0000082 0.0248883 1.1368489
  Detach Event 0.0000065 0.0000254 0.0148008 0.8415036
ListenerHandler<E,H> Attach Event 0.0000976 0.0001598 0.0101366 0.0606196
  Raise Event 0.0000059 0.0000142 0.0493853 3.6426401
  Detach Event 0.0000071 0.0000219 0.0460088 2.6254094
SingleListenerHandler<E,H> Attach Event 0.0000828 0.0001557 0.0102970 0.0610187
  Raise Event 0.0000102 0.0000159 0.0337023 2.4158356
  Detach Event 0.0000082 0.0000165 0.0435121 2.5886397
WeakListenerHandler<E,H> Attach Event 0.0001053 0.00001409 0.0115611 0.0699055
  Raise Event 0.0000106 0.0000224 0.099667 7.3137979
  Detach Event 0.0000082 0.0000266 0.0446755 2.7211488

Based on the figures above the build in handlers still have a distinct advantage, however it is less pronounced. And again from my perspective, the costs of using listeners with events are nominal. And, with respect to handlers performance listed earlier, listeners fare much better considering the conversions between delegate to interface based handling.

There is More

As I mentioned this is early work, so I have a couple of things in mind for improvements:
  • Possibly, implement IDisposable on all the handlers, not for reclaiming unmanaged resources use but more for user's remember-to-dispose considerations. I'm still thinking about this
  • Introducing -= operator, I personally prefer the use of the UnregisterHandler method
  • Introducing a common base class, with overridable methods
  • Because I'ved used a lot of lambda statements, I want to see if there is a way to increase performance. Also if I understand correctly in .NET 4 lambda statements can be compiled (as opposed to only expressions right now), which should help with performance
  • I also want to further squeeze performance out of the Weak handlers, I've used a number of techniques to ensure through-and-through performance, but I still think there might be better ways. I am looking at late-bound expression trees to see if they can help, if you know of any better way please let me know
  • I'm also looking for alternative and strongly-typed ways to create and remove handlers. What I have currently, it's quite performant but there might be a better way
  • Also I think with .NET 4.0's dynamic types we might be able to hopefully get some improvement in performance, especially since we will be able to rigorously match event defined signature with delegates
  • For Silverlight, there is an access limitation to only being able to call public methods and not private ones - I want to if there is an alternative to that (note this only effects the Weak Handlers types). If you know of any alternatives, do let me know

The code is attached below, it references the "WindowsBase" dll for the IWeakEventListener interface - but if you want to use this in non-WPF environments then just expose the interface and remove the RoutedHandlers related classes. Similarly, for use in Silverlight, just link/add the code to a Silverlight project and it should compile as is. 

Download Code (updated for Silverlight use)

Update: I re-did all the performance tests because they were highly skewed in favour of listeners - because earlier the handlers did not do any work. The new figures, better represent real-usage and reflect the expected costs of wrapping event handlers.

Step into nRoute "Office® 2010" Demo App

Posted by Rishi on 22-May-09 8:55 AM - Comments (10)

Tags: , , | Categories: .NET, nRoute, Code

In my recent post I went through various design aspects of nRoute Containers, albeit without a single line of code - as a counter, I showed a demo specifically for Containers dubbed Office® 2010 (or more correctly Officer 2010). In this post I'll go through the Officer demo app, and like with my previous "step in" post, I'll enumerate various items in a point-by-point fashion, relating them to Container related use and design concerns.

Note even though we are aping Microsoft Office 2010 visuals, the demo app is not designed to reproduce office type functionality - it is just an exercise in learning. Screenshot for Microsoft Excel 2010, below:

Microsoft Excel 2010 Screenshot

And below are the Silverlight 3 version screenshots, click here to run the demo app (requires Silverlight 3).

Officer 2010 Screenshot 
Officer 2010 Screenshot

Application Structure

Officer 2010 Solution StructureOne traditional but important type of "separation of concerns" is componentization, and assemblies are often the physical manifestation of such separation. Because the Officer app is rather shallow, there is no great story as far as componentization goes, still I've separated the app into three projects - shell, content and infrastructure related projects. The infrastructure is basically controls and components common to all, the shell is the silverlight "application" that hosts the root visual and styling content, and the content project quite self-descriptively houses the content. 

However the point of having three projects was to highlight the possibility of dependency-mitigation using the Url-based mediator. For example, apart from a single line of code there is no dependency between the shell and the content project. The single line of code (line  18, below), is just used to register the navigation mappings but can equally be rigged in multiple other non-dependent ways. For example, you could dynamically load the content assembly and then ask it register the mappings, or a better approach would be to use something like Prism which offers bootstrapping and module-based initialization entrapments within which you could set the mappings.

The Application Class

The application class as I have mentioned multiple times is conveniently hijacked in nRoute to host a so-called application-wide default container - which by definition handles any navigation without a specified handler. In this case we use the build-in StatefullApplication class, onto which we set the RootVisual and the NaivgationContainer properties as shown below.

public partial class App : nRoute.Navigation.Application.StatefullApplication
{
	private void OnStartup(object sender, StartupEventArgs e) 
	{
		// we create the shell
        var _shell = new Shell();
        this.RootVisual = _shell;

        // we set the default container and set the shell's data context
        this.NavigationContainer = _shell.PresistentContainer;
        _shell.DataContext = this.GetApplicationLinks();

        // we can customize this using deep-linking or something - but for now it is static
        _shell.LinksListBox.SelectedIndex = 1;  
        
        // and we map the assemblies - this is strongly typed, but you could do it many other ways
        ActionService.MapAssemblyActions(this.GetType().Assembly);
        NavigationService.MapAssemblyRoutes(typeof(Officer2010.Content.Views.NewDialog).Assembly);
	}
	// .. other code
}
The code above should be self-explanatory apart from the GetApplicationLinks call and setting index on a list box - which I'll get to below. Note, here we not enabling deep-linking or browser-shell integration, both of which are normally setup at the application class level - though it is perfectly doable.

Navigation Structure

Navigation Structure If you look at the navigation control (shown on the right), it has a set of primary nodes which are both navigable and selectable. However a bit unusual is that it also headlines a couple of links that seemingly are functional and not navigational in nature - like save or open. To represent this structure, I just created two POCO classes, with the primary nodes (Link class type) mapped to navigation Urls and its children (of LinkAction class type) mapped to action Urls. Further, a list of the primary nodes, yielded by in the GetApplicationLinks method in the App class, is set as the DataContext of the root visual (Line 11 above).

The navigation controls is just itself a common ListBox, with a custom ItemTemplate and importantly a customized ItemContainerStyle. And since we know the binding structure, the templates bind to the relevant properties, they also make use of nRoute behaviours attach the navigation and action Urls (see LinksListResources.xaml). Just as a side point, the ItemContainerStyle holds the Lists control's template for the mouse-over and selected visuals, though customizing it is a bit inaccessible in Blend - to customize use the Object > Edit Other Styles > Edit Item Container > . menu hierarchy.

The Shell Structure

The structure of Shell.xaml is really simple, it is basically 3x3 grid with basically a left-anchored list box, a flexible-width container, and a persuado back button up-top. The image below outlines the layout structure:

Click to Open

Custom Containers

With this demo app I wanted to highlight two customization points with Containers, styling and state-management. Because containers by definition model their state related behaviours, I wanted to create a container that could persist its state in Isolated Storage on exit and resurrect it on start - however that was not to be simply because in SL we can't arbitrarily serialize objects, so in a future release I'll do the necessary tinkering with the state management classes to hopefully get this scenario working (however this in entirely possible in WPF). Nonetheless, in the code you'll see how we can still use the isolated storage to persist data, however on a page-by-page basis.

The styling customization was easy pickings; firstly I wanted to put in place some navigation-induced transition effects for which I created a custom control-template that wrapped the presenter in Silverlight Toolkit's transition control, you could also easily use other libraries such as Silverlight FX.

<!-- TRANSITION CONTENT CONTROL WRAPPER -->
<toolkit:TransitioningContentControl RestartTransitionOnContentChange="True">
    <ContentPresenter/>    
</toolkit:TransitioningContentControl>
The other visual tweak I did was to use the SL3 specific child window for highlighting navigation failures, this has much better aesthetics than the MessageBox approach used earlier - try clicking the "Back" button. Lastly, one stupidity I've done with the Containers API is to expose ICommand based properties to trigger navigation, which ensured very clumsily use semantics; so in the custom container I've somewhat correct that by exposing a simple Url property that triggers navigation when changed.

Sub-Containers

One of the common user-cases involve having container like regions within a page, which itself is hosted in a container - that is nothing special really, but with nRoute you get nice-clean and loosely-coupled contraption to play such scenarios out. For example in the NewDialog.xaml page (shown below) we have two lists of document templates (highlighted with yellow diagonal boxes); selecting any item on either of the two ListBoxes triggers a command in the ViewModel, which in turn causes navigation in the sub-container (shown with red stripes) - that then shows the selected document template's details page. The commands are exposed as properties on the ViewModel, and bound to the ListBoxes' SelectionChanged event using nRoute behaviours, and the sub-container is bound to an "ActiveTemplate" property of the ViewModel.

Click for Larger Picture

One of the other useful aspects to sub-containers is that the DataContext of the "host page" flows in the sub-container and any of it's active content, unless specified otherwise. I've used this DataContext inheritance behaviour in OptionsDialog.xaml (shown below); the options page displays Common and Advanced Settings in a sub-container. To hold the settings data I create two POCO classes (the CommonSettings and AdvancedSettings types) and exposed these on the host page's ViewModel as properties. As these two properties "flowed" into the sub-pages, they were used to bind the settings on various UI controls - which really helped, as I didn't have to create extra ViewModels or manage extraneous data exchanges. Also, the POCO classes were earmarked with the DataContract and DataMemeber attributes to enable persistence using the Isolated store in SL, which enables your custom settings to survive multiple disconnected sessions - try it. 

ContainerDataContext

Fishing not the fish

In summary, I hope I've shown the use, design, and customization aspects of Navigation Containers - because they really help in logically breaking-down your application and compose it together as a loosely-couple but cohesive unit. So the real take-away should be how you model your application's visuals using containers as a fundamental building-block - in wiser words the fishing as opposed to the fish itself.

To run the Officer® 2010 app, click here (requires Silverlight 3 runtime).
To get nRoute and Officer® 2010 source code, click here.

PS: The detailed Officer demo app is not a showpiece for architecture or coding practices - it was specifically designed around highlighting certain nRoute concepts. Also, you will be pleased to know no code-behind was harmed in the making of this demo.

Update: Recompiled and updated the source for SL3 RTM version

I just read an article by Micheal Sync about implementing property changed notifications with Expression Tree, I liked what I saw but didn't appreciate the inheritance requirement (as always). So I quickly whipped up three alternate way using extension methods, have a look:

using System;
using System.ComponentModel;
using System.Linq.Expressions;

namespace Orkpad.Samples
{
    public static class NotifyPropertyChangedExtensions
    {

        public static void NotifyPropertyChanged<TValue>(this Object target, 
            Expression<Func<TValue>> propertySelector, Action<string> notifier)
        {
            if (notifier != null)
            {
                var memberExpression = propertySelector.Body as MemberExpression;
                if (memberExpression != null)
                {
                    notifier(memberExpression.Member.Name);
                }
            }

        }

        public static void Notify<TValue>(this Action<string> notifier, 
            Expression<Func<TValue>> propertySelector)
        {

            if (notifier != null)
            {
                var memberExpression = propertySelector.Body as MemberExpression;
                if (memberExpression != null)
                {
                    notifier(memberExpression.Member.Name);
                }
            }

        }

        public static void Raise<TValue>(this PropertyChangedEventHandler handler, Expression<Func<TValue>> propertySelector)
        {

            if (handler != null)
            {
                var memberExpression = propertySelector.Body as MemberExpression;
                if (memberExpression != null)
                {
                    var _sender = ((ConstantExpression)memberExpression.Expression).Value;
                    handler(_sender, new PropertyChangedEventArgs(memberExpression.Member.Name));
                }
            }

        }

    }

    // I've tested this in Silverlight it works fine, should work in WPF too.
    public class NameValuePair : INotifyPropertyChanged
    {

        string _name;
        string _value;

        public string Name
        {
            get
            {
                return _name;
            }
            set
            {
                _name = value;
                this.NotifyPropertyChanged(()=> this.Name, RaisePropertyChanged);
                // I don't like to new up, but this is also usable
                //new Action<string>(RaisePropertyChanged).Notify(() => this.Value);
            }
        }

        public string Value
        {
            get
            {
                return _value;
            }
            set
            {
                _value = value;
                PropertyChanged.Raise(() => this.Value);
            }
        }


#region INotifyPropertyChanged Members

        void RaisePropertyChanged(string name)
        {
            if (string.IsNullOrEmpty(name)) throw new ArgumentNullException("name");
            if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(name));
        }

        public event PropertyChangedEventHandler PropertyChanged;

#endregion

    }
}

Of the three ways I've show, I like the last one using the PropertyChangedEventHandler best - it's quite compact and tidy. In fact, we can use similar extension-method "pattern" to call/raise handlers in various other scenarios. The other two ways are also useful if you don't have direct access to the event, like in cases of inheritance or where you have to go through a wrapper. Now, I can't speak to the performance of either solution - though, if someone can show figures on performance especially relative to the "normal way" that would be super!

// Recap

// Way 1
this.NotifyPropertyChanged(() => this.Name, RaisePropertyChanged);
// Way 2
new Action<string>(RaisePropertyChanged).Notify(() => this.Name);
// Way 3
PropertyChanged.Raise(() => this.Name);