One of the challenges with modern application development is loosely-coupled communication between various independent components within an application; by and large it is not a technical problem, but one of having a common denominator and ensuring that parties to the communication don't entangle each other with dependencies. To this challenge in nRoute we have a messaging framework that decouples application-wide communication using a mediator, against which you can both publish and subscribe without creating direct dependencies. It works much like other mediators such as Prism's Event Aggregator and MVVM Light Toolkit's Messenger, however here the core concept is based around the observer pattern.

Rx's Observer Pattern

As just mentioned nRoute's messaging broker is based on the observer pattern, or more specifically on the Rx-framework's interpretation of the observer pattern vis-a-vie their IObserver<T> and IObservable<T> interfaces. Within our use context, you can think of an Observable as being a publisher and the Observer being a consumer. When the consumer wants to consume, it subscribes to the publisher (via the Subscribe method) and thereon the publisher can do three specific things - push a series of values (of an agreed 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 use to opt-out/unsubscribe from the publisher's output.

ObservingProcess

The other notable thing about the observer setup is that the communication is all one-way, this allows it to multiplex a single published message to more than one subscriber. Now in our broker implementation, we augment the observable with the capability to be able take in a payload and send it to all registered subscribers.

Observable Channels

nRoute's messaging framework implementation uses a "channel" metaphor to describe its observable broker (IObservable<T>) implementation; and each channel is uniquely defined by the type of is payload (ie. type T in IObservable<T>) it carries, and against each channel you can both publish a payload and subscribe for one or more payloads. Code-wise, these channels are nothing more than generic singleton classes that implement the IObservable<T> interface along with a publish mechanism, which as I eluded pushes the payload to all the subscribed IObserver<T> type consumers.

ObservableChannels

As seen above, each channel is represented by the Channel<T> class, which implements IObservable<T> and inherits from the Channel base class, plus the Manager property gives access to the only instance of the singleton Channel<T> class. Further, as class definition shows a Channel<T> class allows for three things, publish a message of type T, publish asynchronously a message of type T, or subscribe to the channel which yields an IDisposable. The Channel base class gives you convenient access to the same three functions, however in both generic and non-generic ways. Note, you do not have to create any channel object yourself and the payload type of T must be a reference type i.e. a class object.

Publishing to any channel couldn't be any simpler, below we look at six ways to publish a log message of type LogInfo both synchronously and asynchronously:

   1: void PublishLog(LogInfo log)
   2: {
   3:     // using the Channel<T> singleton class
   4:     Channel<LogInfo>.Manager.Publish(log);
   5:     Channel<LogInfo>.Manager.PublishAsync(log);
   6:  
   7:     // using the Channel class generic methods (note the generic type is inferred)
   8:     Channel.Publish(log);
   9:     Channel.PublishAsync(log);
  10:  
  11:     // using the Channel class's weakly-typed methods
  12:     Channel.Publish(typeof(LogInfo), log);
  13:     Channel.PublishAsync(typeof(LogInfo), log);
  14: }

The code above should be self-explanatory, with the main take-away being that communication is done via channels, which themselves are defined by the type of the payload they carry. One other notable is that using an observable channel you cannot currently publish an exception (receivable via the OnError method), or indicate the channel is completed (receivable via the OnCompleted method) as a channel remains open through the application's lifespan.

Disposable Subscribers

Given the IObservable<T> channels the subscribers need to be of IObserver<T> type, and build-into nRoute for ease of use sake is an IObserver<T> implementing ChannelObserver<T> class. ChannelObserversThe ChannelObserver<T> basically helps maintain subscription for a channel of type T, and accordingly it has an IsSubscribed property, along with Subscribe and Unsubscribe methods. Also the channel observer class implements IDisposable, so when you are through with it you can just call the Dispose method on it and it will unsubscribe from the channel if required. Additionally the ChannelObserver<T> class also surfaces some additional options like the subscription thread option, or if you would like to have a strongly-referenced subscription (by default all subscriptions are weakly-referenced) and also allows you to optionally provision a delegate-based filter. Below is a simple use snippet, note that you have to explicitly call the Subscribe method to start observing a channel.

   1: // create the observer
   2: var _observer = new ChannelObserver<LogInfo>((l) => ProcessLog(l));
   3:  
   4: // subscribe on the UI Thread
   5: _observer.Subscribe(ThreadOption.UIThread);
   6:  
   7: // and unsubscribe
   8: _observer.Unsubscribe();

I hope the code speaks for itself, as we basically create the channel observer by providing a lambda to handle any incoming log info, and subscribe and unsubscribe as need be. Note, you can subscribe and unsubscribe multiple times using the same observer, as long as you have not disposed the observer. Also, understand that the ChannelObserver<T> class is just a candy-implementation of IObservable<T> which for convenience-sake manages the IDisposable token internally, however you can alternatively furnish any custom implementation of IObserver<T>, so for example:

   1: // subscribe to channel
   2: var _unsubscribeToken = Channel<LogInfo>.Manager.Subscribe((l) => ProcessLog(l));
   3:  
   4: // and to unsubscribe
   5: _unsubscribeToken.Dispose();

Here we are using the Subscribe extension method in nRoute to subscribe by passing in lambda handler, which yields a disposable token that can be used to unsubscribe from the channel. Now if you wanted to subscribe with say threading options, you just need to pass in the observer explicitly as shown below

   1: // create the observer
   2: var _observer = new RelayObserver<LogInfo>((l) => ProcessLog(l), null, null);
   3:  
   4: // subscribe
   5: var _token = Channel<LogInfo>.Manager.Subscribe(_observer, ThreadOption.UIThread);
   6:  
   7: // and to unsubscribe
   8: _token.Dispose();

RelayObserver<T> is a generic implementation of IObserver<T> in nRoute that takes in three delegates for handling a payload, an exception and a notification of completion. And a complementary RelayObservable<T> implementation of IObservable<T> also exists in nRoute, which helps manage one or more IObserver<T> subscribers.

Dedicated Subscribers

In addition to the disposable subscribers, you can also create dedicated subscribers that automatically subscribe and work without any direct user interaction (kind of like services) - and this is sometimes useful when you want to create dedicated sinks for a channel. Lets look at a simple logging example:

   1: [MapChannelObserver(typeof(LogInfo), "IsolatedLogger",
   2:     InitializationMode=InitializationMode.WhenAvaliable,
   3:     Lifetime=InstanceLifetime.Singleton)]
   4: public class IsolatedLoggerSink : IObserver<LogInfo>
   5: {
   6:  
   7: #region IObserver<LogInfo> Members
   8:  
   9:     public void OnCompleted() { .. }
  10:  
  11:     public void OnError(Exception exception) { .. }
  12:  
  13:     public void OnNext(LogInfo value) { .. }
  14:  
  15: #endregion
  16:  
  17: }

So above, just like any subscriber to the LogInfo type channel the IsolatedLoggerSink class implements IObserver<LogInfo>, and additionally we just decorate it with the MapChannelObserver attribute. The mapping attribute is based on the Resource Locator Framework, and it automatically registers an instance of the class as a subscriber to the channel, and also helps manage the lifetime and initialization work - in the case above, we've set the initialization to be done as soon as the resource is available and the lifetime is set to be singleton.

MapChannelObserver

Now normally once you have decorated the class with the MapChannelObserver attribute you don't have to deal with the subscription issue, however incases where you want manual control you can use the ChannelObserverLocator static class shown above - with it you can resolve any registered instance and explicitly consume it.

Threads, Async and Weak-Reference Issues

One of the features of nRoute's messaging framework is that it allows you to publish either on the publisher's working thread or asynchronously on a background thread, and on the subscribers end you can either consume on the publisher's thread, or on a background thread, or on the main UI thread (see the ThreadOption enum type). By default all subscribers use the publisher's thread, and in most cases this works fine but you have to careful (by manually specifying the TheadOption) in cases where the subscriber updates or effects UI controls as it can lead to cross-threading exceptions.  Also when you are consuming or publishing asynchronously there is a non-trivial provisioning overhead associated with sending and receiving the payload asynchronously to each subscriber - so use it selectively, preferably with coarse-grained operations. 

ChannelsThreading

One of the other important notables is that by default internal references to all the subscribers are weakly-referenced, which ensures that if the subscriber falls out of scope/use its subscription is automatically removed on the next publishing cycle. Now, for most cases this has a negligible effect on performance, however in some cases for performance reasons or otherwise you can choose to have a non weakly-reference held, in which case you must explicitly unsubscribe else the subscriber's reference will be indefinitely held by the channel potentially creating memory leaks. In any case, the best practice is to always unsubscribe from a channel when done.

Future Enhancements

In the next drop of nRoute, I'm looking to put in place two main enhancements - first to allow explicit publishing of exceptions, so just as we can publish a payload in a channel we will be able to publish an exception through the same channel. This gels with our normal understanding than any operation can have two possible outcomes, one as defined by the operation's contract and the other being an exception passed through the call-stack. And so in the same vein, in our decoupled pub/sub type of communication we should be able to specifically "raise" (i.e. send) an error explicitly to all the channel's subscribers. The second improvement I seek is to allow "private channels" that can be uniquely indentified and consumed using a shared key, and unlike the public channels, private channels will be temporal so their owners can close them as required. Private channels will functionally be similar to public channels, except they will have to be addressed using their shared key.

Owing to the ongoing development of the Rx-framework, nRoute currently does not have a binary dependency on the Rx-framework, although we have their equivalent IObservable<T> and IObserver<T> definitions present. However, as the Rx-framework stabilizes future iterations of nRoute will take a direct dependency on it, which quite beneficially will bring into play all the operators and observer constructs from Rx.

Summary

So in this post I've covered the ins and out of the nRoute's messaging framework, with the basic outline being it can help decouple your inter-component communication by playing an intermediary role. Now, to press the point further in my next post I'll put an example how in a MVVM setup such mediated communications can play an important role to keep things sane.

Posted by Rishi on 12-Feb-10 2:51 AM, 37 Comments

Categories: nRoute, Silverlight

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.

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.

Posted by Rishi on 07-Jan-10 5:13 AM, 45 Comments

Categories: nRoute, Code

Consoles are a unique animal in this day and age of multi-touch user interfaces - they stand productively tall despite all the enhancements in user-interaction over the years. And as Silverlight grows into a more rounded and generalized platform, there is a case for Command Line Interface tooling - so here is an attempt at a relatively simple implementation of a Silverlight based Console that includes a Console Window Control and a matching set of extensible Commands Framework that allows for executable commands (called script-actions) vocabulary.

SilverlightConsole3

View the demo application here.
Note, the demo application only supports a limited set of commands, type "help" for listing of available commands, for some examples try "setwallpaper -url:http://adsoftheworld.net/download/windows7/winwall7057_17large.jpg"  or "countdown 00:00:10" or "beep" to make a beeping sound.

Console Window Control (Orktane.Console.dll)

In terms of user-interaction the console is a bit of peculiar control, it isn't exposed as a directly usable control but rather is accessible only through a singular static Console class. For the purposes of the Silverlight Console, I've encapsulated the Console class functionality into an IConsole interface, which in turn is visualized and exposed through a Console Window user-control. The idea of an IConsole interface, just like in Windows, is to enable visually-independent consumption of the console functionality, and at the same time also allow having multiple instances of consoles within a single Silverlight application. Now, Silverlight does have a System.Console class but it is cocooned in the SecurityCritical attribute making it useless outside its internal uses.

ConsoleModel

The IConsole functionality above is much simplified compared to the Windows counterpart, we don't deal with screen-buffers, cursors, or position related settings. Also, though internally we do have In and Out streams they are not exposed, and rather than width-by-height buffer size we deal with a string length output buffer. The simplification is in part because the text-rendering functionality in Silverlight is basically all internal, so we are limited to Textbox or Textblock controls for text-based interaction. However with the RichTextArea control in Silverlight 4, it should enable a much richer experience (see Pose Console in WPF). Further, a solution based on column-by-row screen buffer would have been very resource-heavy for Silverlight, so instead we've used a string-based buffer - which you can set by using the SetOutBuffer method.

One other critical difference between the Windows counterpart is that Silverlight doesn't allow blocking calls, so returning values through ReadLine and ReadKey functionality isn't possible, hence ReadKey and ReadLine calls above return void. In place of returning values, both the ReadKey and ReadLine functionality take in an Action delegate which is used to yield the user input - the ReadKey takes in an Action of ConsoleKeyInfo (shown above) delegate and ReadLine takes an Action of String delegate. Now, whenever you set the ReadKey or the ReadLine delegate it switches the input mode between the two, and whenever you set the delegate it would keep sending the input to the same delegate for each input until changed.

Another issue with using the text-controls in Silverlight is that we have to manually disable input, for which you have to use the DisableInput property on the IConsole interface. This takes away the input Textbox, and if you choose you can display alternate text using the DisableInputText property - so for example below we have disabled the input whilst we are downloading in the background and erstwhile we are showing the progress info using the DisableInputText. Note the red indicator on the left of the text, which visually is a separate area (Textbox actually) from the console output area (also a disabled Textbox).

DisabledInputText 

Now to visually realize the IConsole we have the ConsoleWindow user-control that you can directly use, it has a Console property of type IConsole which allows for procedural use of the console. Internally, we have the console functionality separated from the visuals, a View-ViewModel kind of separation as shown below. You can potentially change the visuals or logic by changing either, or you can create your console-visuals using the ConsoleBase as a starting point.

ConsoleWindowModel

Note, since we are not using a cell based display, in the Console Window we use a fixed-width font, with the width pegged for 80 columns. This aspect is hard-coded, but it is consistent to the default Windows console.

Script-Actions Framework (Orktane.ScriptActions.dll)

By itself the ConsoleWindow implementation is dumb as a stick, it has no concept of executable commands, it just handles the input and output business. And so we have this Script Actions framework (or Commands framework), which basically extends the IConsole to allows execution of custom script-actions, where script-actions are executable commands (note, we don't use the word command because of the ICommand-related conation). In simpler terms you can think of script-actions as extensible vocabulary which is executable in a console. A

ScriptActionsModel

As seen above, we have two types of script-actions, one which can execute by itself (IScriptAction) and the other derivative (IConsoleScriptAction) that requires a console instance to execute. The Execute method takes in an Arguments-type parameter, which is a dictionary of parsed switches and command-line arguments. The command line parser is by Richard Lopes, with some additional word done by Jake Ginnivan. However, for a future release I am looking to port the Command Line Parser Library (by Jakub Malý), which allows for strongly-typed arguments and better structuring of script-actions.

Now, if your ScriptAction class implements the IConsoleScriptAction then the Console instance is passed in and the Initialize method is called prior to execution. And again because we don't have blocking calls in Silverlight you have to manually indicate as to when the script-action has finished its execution, for that you use the ExecutionCompleted event to flag the completion. The close method is called when you've finished, or earlier if the executing environment is itself closing. Further, you can also handle a cancel request (called using the Ctrl+C pairing) by listening to the IConsole's CancelKeyPress event. On the other hand, the IScriptAction based script-action are executed without any indication in the Console (note that is different from when a request command is not found), and once the execution has been called the console returns to an empty console prompt.

On of the features in nRoute, is a MEF like composition component called the Resource Locator - it basically allows you to earmark specific resources and have them cataloged. So based on that, we have a MapScriptAction attribute that flags an implementation of IScriptAction for use in a console; as an example consider:

   1: [MapScriptAction("GC", "GC Memory", 
   2:     ShortDescription = "Forces an immediate garbage collection.",
   3:     Lifetime = InstanceLifetime.PerInstance, UnListed = true)]
   4: public class GCScriptAction : IScriptAction
   5: {
   6:     public void Execute(Arguments args) { 
   7:         GC.Collect();
   8:     }
   9: }

Above, we an IScriptAction implementation that forces an immediate garbage collection on execution, and we have earmarked it with a MapScriptAction attribute. The attribute takes in couple of settings like a unique and callable command-name, a title for the script-action and other options like short-description, a lifetime setting indicating how to handle instantiation, and lastly an option as to if the command is not listed in the help listings. Using the attributes based composition of script-actions makes it painless to have commands availed at runtime or dynamically resourced, for more information please see Introduction to nRoute.Toolkit posts.

Lastly, once we have the script-actions we need to enable their use from within an IConsole instance, for that we have a behavior called ScriptActionConsoleBehavior that attaches to any IConsoleHost implementing (also must be a FrameworkElement) instance. The xaml for that looks like:

   1: <console:ConsoleWindow x:Name="consoleWindow">
   2:     <i:Interaction.Behaviors>
   3:         <scriptActions:ScriptActionConsoleBehavior/>
   4:     </i:Interaction.Behaviors>
   5: </console:ConsoleWindow>

As seen above, the separation of concerns in terms of the console's working-logic and the visuals allows you to plug-in your own custom logic or visual implementation. So for example you could have MEF composed script-actions, or bring Powershell scripts into Silverlight and hook them into a ConsoleWindow. Remember the pairing is necessary, as by itself the Console Window control is dumb-as-a-stick.

Summary

So what we have here is a two-piece solution, one an IConsole based visual control, and two a complimentary console-executable vocabulary of script-actions. And though the solution is not true to the Windows version, it within the limitations of Silverlight a very usable tool. Finally, if you have suggestions or ideas to enhance what's here please do let me know.

Source-code and binaries are available on Codeplex
and you can view the Console Demo Application here.

Posted by Rishi on 29-Dec-09 6:15 AM, 19 Comments

Today I saw a cool article on Code Project on how to do multi-binding in Silverlight using attached properties and a specialized type of value-converter. I though we could do the same thing with Value Converter Relays in nRoute.Toolkit without requiring additional classes/converters. So in this post we'll cover how to easily address multi-binding scenarios (as when you have multiple inputs, but one required output) using value-converter relays in Silverlight.

The Use-Case

The use-case is very simple, we have this form (shown below) that takes in a Person object with three properties namely Surname, First Name and Age - and as you enter them into the form, it updates the title of form with the full name derived from what you have entered. Nothing fancy, but the idea is that we should be able to consume two or more fields through one binding (as in multi-bind).

MultiBindingForm

Value-Converter Relays

Just to reiterate, a relay is like a facade to an actual implementation that can be specified elsewhere such as your code-behind or your ViewModel. In this case, we'll use a code-behind implementation as the requirement is essentially to turn two inputs into a formatted string, and that really is a view-level detail so it should stay there. All the same, if you wanted to use a ViewModel driven implementation then you can use a behaviour named  "BridgeValueConverterBehavior", which as you can guess "bridges" the relay with an implementation from your ViewModel (using bindings).

How-To Steps: Declare, Define and Use

Step 1, we declare the value-converter relay in our UserControl's resources collection, just like any static resource:

   1: <nComponents:ValueConverterRelay x:Key="TitleConverter"/>

Step 2, once we have the relay declared we define it in our code-behind. Here we are using an extension method available in nRoute.Components namespace that allows us to define the value-converter functionality using a lambda statement. Note, it is important to set this before we set the data-context, obviously because it is needed once the data-context is available.

   1: this.SetRelayConverter<Person, string>("TitleConverter", 
   2:     (p) => string.Format("{0}, {1}", p.Surname, p.Forename));

Step 3, to use the formatted string, we just bind to the data-context (which is the Person object) whilst using our value-converter relay:

   1: <TextBlock Text="{Binding Converter={StaticResource TitleConverter}, Mode=OneWay}"/>

And that's it we are done, we have our fake multi-binding in SL using value-converters. However, note there is one niggle, because we are directly setting the Person as our data-context, we have to manually update the data-context on the TextBlock whenever the property changes. This could be avoided by using ViewModels or INotifyPropertyChanged notifications, but since the original sample didn't I've avoided it too.

More Relays

Now that you've see the ValueConverterRelay in action, I'll just mention that we have two other types of relays in nRoute - one called Command Relay and another Value Relay. You can see a Command Relay in action in my recent ICommands related post, and the Value Relay is put to good use in my Web Xcel demo - there I've used it to "pseudo bind" to both a non-dependency property and also to another read-only dependency property. And so to sum it up, consider the use of relays for lot of sticky-stuff like pseudo multi-binding use, binding to data-templates, consuming read-only properties etc. and though it's not pretty it gets the job done.

You can download the value-converter relay project's source code,
note it requires the nRoute.Toolkit which is available on Codeplex,
and the original article on Multi-binding with source is available on Code Project.

Posted by Rishi on 11-Nov-09 2:01 PM, 12 Comments

Categories: nRoute, Silverlight

In a MVVM architecture ICommands are the primary abstractions that formalize the exposing and consumption of ViewModel defined functionality for use by its View. However, unlike WPF, Silverlight features no build-in ICommand implementations, supporting infrastructure or out-of-box integration with Controls. So, with this post I'll cover the ICommand-related infrastructure present in nRoute.Toolkit and go-over various aspects related to exposing, consumption and using ICommands in Silverlight.

1. Defining ICommands

Included in the nRoute.Toolkit are two ICommand implementations called ActionCommand<T> and ActionableCommand<T>, they both basically take in a delegate that handles the execution of the command. However, the difference between an ActionCommand<T> and the ActionableCommand<T> is simply that the latter allows you to define a delegated-based predicate that can determine as to if the command is currently executable. Also for convenience sake included are two non-generic versions of the same commands, that specifically relieve you of handling a command parameter.

ICommands

Also as shown above, the featured ICommand implementations provides you with an IsActive property using which you can enable or disable the command. Further, the RequeryCanExecute method allows you to re-evaluate as to if the current command is executable for its consumers. Further, to demonstrate a somewhat realistic use of an ICommand, we'll go-through a scenario from my Web Xcel demo app (shown below), whose code you can actually download from Codeplex.

WebXcel

For our use-case we are going to focus on a "Save Worksheet" functionality that is exposed as an ICommand via a property on the ViewModel. And the basic use-context is that we have this Worksheet Object (visualized as a Grid), which when changed can be saved by calling the "SaveWorksheet" Command, through the "Save Worksheet" Hyperlink Button (shown in the "Document Helper" panel above). Now, in the ViewModel code the SaveWorksheetCommand is declared and instanciated as follows:

   1: // Declare Command
   2: public ActionableCommand SaveWorksheetCommand { get; private set; }
   3:  
   4: // Define Command
   5: SaveWorksheetCommand = new ActionableCommand(() =>
   6: {
   7:     // basic check
   8:     if (this.Worksheet == null || !IsDirty) return;
   9:  
  10:     // update the status
  11:     var _token = StatusViewService.UpdateStatus(SAVING_WORKSHEET_STATUS);
  12:     SaveWorksheet();
  13:     _token.Dispose();
  14:    
  15: }, () => this.Worksheet != null && this.IsDirty)
  16: .RequeryOnCommandExecuted(OpenWorksheetCommand)
  17: .RequeryOnCommandExecuted(NewWorksheetCommand)
  18: .RequeryOnPropertyChanged(this, () => IsDirty);

In line 2, we declare a SaveWorksheetCommand property of type ActionableCommand, note it is the non-generic version and thus takes in no ICommand parameter. On initialization of the ViewModel, the ICommand implementation is instantiated as shown in Line 5. The constructor for the ActionableCommand takes in two parameters, one to define the execute functionality and second to define a predicated as to if the command is currently executable. So with Line 6-to-14 the execution handler basically updates the Status-Bar message (Line 11), then saves the active Worksheet via a helper method called "SaveWorksheet" (Line 12) and then retract the Status-Bar update (Line 13) by disposing the given token. Internally, the SaveWorksheet method serializes the Worksheet Object to a xml file and allows the user to save by showing a Save File Dialog. 

Also you can see in Line 8, we pre-check that the Active Worksheet to save is not null and that it has one or more pending changes (i.e. is dirty). That pre-check logic is basically the same logic that defines as to if we can execute the Save Worksheet command, and so in Line 15 the lambda statement defines the exactly same logic as the second parameter to the ActionableCommand constructor.

2. Defining ICommand Dependencies

As I hope is apparent, creating ICommands in your ViewModel is very straightforward but there is one aspect to that is rather cumbersome - the problem is that a command's execution is subject to a number of direct and indirect dependencies, and so whenever a dependency changes we must re-evaluated the current execution status of the command. In practical terms this means that dependencies should use the "RaiseQueryCommand" method to effect a CanExecuteChanged event, which tells an ICommand's consumers to check the executable status vis-a-vie the CanExecute method on the ICommand.

As you can image this is not only cumbersome but it also leads you to implicitly-defined ICommand dependencies throughout your code. So, with the nRoute.Toolkit's ICommand implementations we have a set of extension methods that you can use to explicitly define the dependencies, and using the same it also automatically updates any changes to the executable state of the ICommand. If this sounds fancy, it is not - lets look at our SaveWorksheetCommand example. In Lines 16-18 we explicitly define three cases that say re-query the executable status of the command whenever either of the OpenWorksheetCommand or NewWorksheetCommand commands are executed (because if we have just created or opened a Worksheet then there is nothing to save). And the third statement says that also re-query whenever the IsDirty property on "this" ViewModel changes (if Worksheet is Dirty, then the save status must have changed). So, now with these three extension methods the command's execution status is automatically re-evaluated, whenever either of the three explicit conditions occur.

Below is the list of the five included extension methods that help define dependencies on ICommands - however, do note you can write your own similar extension methods too (for more information, please see this post).

  • RequeryWhenExecuted - this methods basically says that whenever the command itself executes then re-query it's execution state.
  • RequeryOnCommandExecuted - as shown above, this one re-queries the command whenever some other command is executed
  • RequeryOnCommandCanExecuteChanged - this extension method says whenever the executable status of a another specified command changes then do a re-query
  • RequeryOnCollectionChanged - this pegs the re-query on a given collection changing, wherein the collection implements INotifyCollectionChanged
  • RequeryOnPropertyChanged - this extension as we have seen, begets a re-query when a INotifyPropertyChanged implementing object's property changes

ExecuteCommandBehavior 3. Consuming ICommands

As far as consuming ICommands is concerned, we are thoroughly-thoroughly covered by a so-named ExecuteCommandAction behaviour in the nRoute.Toolkit. And if you are wondering as why it is double-so-thorough, well because of three reasons besides the simple fact that it can execute commands. Reason one, even though the Silverlight framework itself does not support binding to Dependency Properties, with the ExecuteCommandBehavior you can bind to commands defined in your ViewModel - just remember you have to use the Binding post-fixed properties as shown in the Blend screenshot above. To know more about this so-called dual-property binding for Silverlight, please see my earlier post introducing nRoute.Toolkit. Similarly, you can also bind the parameter by using ParameterBinding property or alternatively statistically specify the parameter using the Parameter property.

Reason two, the execute command behaviour is implemented as a TriggerAction - what does that mean, it simply means you can pair it with any kind of Trigger (note, the Trigger and TriggerAction are from the Blend SDK). So the pairing can be done with an Event Trigger or a MouseWheel Trigger or a Gesture Trigger, in fact you can create your own trigger - like say one that responds to Voice Input. The benefit to all this Trigger-TriggerAction separation is that your use of a command is not limited to certain a set of pre-defined use-cases, which I think helps with both reusability and flexibility. So for example, with the SaveWorksheetCommand I've used the ExecuteCommandAction with two types of triggers.

   1: <!-- ICOMMAND WITH KEY STROKES -->
   2: <i:Interaction.Triggers>
   3:     <nTriggers:KeyTrigger WithControlModifier="True" Key="S" WithShiftModifier="True">
   4:         <nBehaviors:ExecuteCommandAction CommandBinding="{Binding SaveWorksheetCommand}"/>
   5:     </nTriggers:KeyTrigger>
   6: </i:Interaction.Triggers>

Above, we are pairing the KeyTrigger (for key-set Ctrl+Shift+S) with the ExecuteCommandAction behaviour that triggers the SaveWorksheetCommand in our ViewModel. And below we are pairing the same command behaviour with an EventTrigger to raise the command on a click event of a Hyperlink Button. Now, the XAML might look dreadful, but don't worry all this can be done visually in Blend - which will spit out the same XAML you see below.

   1: <!-- ICOMMAND WITH Click EVENT  -->
   2: <HyperlinkButton Content="Save Worksheet">
   3:     <i:Interaction.Triggers>
   4:         <i:EventTrigger EventName="Click">
   5:             <nBehaviors:ExecuteCommandAction ManageEnableState="True"
   6:                 CommandBinding="{Binding SaveWorksheetCommand, Mode=OneWay}" />
   7:         </i:EventTrigger>
   8:     </i:Interaction.Triggers>
   9: </HyperlinkButton>

4. Managing ICommand Control States

The third reason as to why the ExecuteCommandAction is thorough is that it allows you to control the enabled/interactivity state of the control it is applied on - by using the "ManageEnabledState" option (see the Blend screenshot above). What does that mean, it simply means that if the command's not executable it will disable the control for you - so for example in our SavewWorksheetCommand example, if there is no Active Worksheet or if the Active Worksheet is not dirty the Hyperlink Button will be disabled (see Line 5 in the XAML snippet above that enables this scenario by setting the ManageEnabledState to true).

WithPendingChanges NoPendingChangess

The picture on the left shows the Hyperlink Button disabled when there are no pending changes to the Active Worksheet, whereas the picture on the right shows an enabled Hyperlink Button when there are pending changes - the same is also indicated by the asterisks in the title. The enabling/disabling is done for you automatically (once you opt in the ManageEnabledState option), as the behaviour listens for changes in command's executable status and evaluates its use status against the command. Further, the ExecuteCommandAction behaviour also also plays nice with controls that don't have an IsEnabled (ie. non-Control type derived controls) property by taking away their interactivity. In the screenshot below, the Border Control doesn't support an IsEnabled property, however when the attached command is not executable the Border Control is dimed down and its interactivity is taken away.

ButtonVsBorderControl

5. Relaying ICommands

Now one of the other common problem you will find with ICommands is related to consuming it with templated controls like ItemsControl or ListBox Controls in Silverlight. The underlying issue is that from within a DataTemplate you can't access the ViewModel and hence the ICommands are not addressable. The reason is simple, because a DataTemplate's DataContext is set to the item being enumerated - so if a customer item is being enumerated, then that would be set as the active DataContext. So how do we solve this problem, the answer is simple - we first create a command relay as a resource in our View and then bridge the relay with an actual implementation from our ViewModel. Note, the command relay will be a static resource and thus can be "binded" as such.

Lets consider a simple example, lets say we have a ItemsControl that lists Customers collection from our ViewModel - it uses a DataTemplate that needs to consume an EMailCustomerCommand which is also defined in our ViewModel. So here is what we do, we first define an EMailCustomerCommandRelay in our View's resources collection and then use a BridgeCommand behaviour to source the relay from our ViewModel via Binding. Below is the relevant XAML:

   1: <!-- DECLARE RELAY -->
   2: <UserControl.Resources>
   3:     <nComponents:CommandRelay x:Key="EMailCustomerCommandRelay" />
   4: </UserControl.Resources>
   5:  
   6: <!-- BRIDGE THE RELAY FROM THE VIEWMODEL -->
   7: <i:Interaction.Behaviors>
   8:     <nBehaviors:BridgeCommandBehavior 
   9:         CommandRelay="{StaticResource EMailCustomerCommandRelay}"
  10:         CommandSourceBinding="{Binding EMailCustomerCommand, Mode=OneWay}"/>
  11: </i:Interaction.Behaviors>

Once we have done this, all we need to do is to use the CommandRelay in our DataTemplate as a StaticResource (see below). Also note we are passing the Active DataContext (which would be the Customer Object) as the Parameter to the ICommand:

   1: <DataTemplate x:Key="CustomerDataTemplate">
   2:     <StackPanel>
   3:         <TextBlock Text="{Binding CustomerName, Mode=OneWay}"/>
   4:         <Button Content="E-Mail Customer">
   5:             <i:Interaction.Triggers>
   6:                 <i:EventTrigger EventName="Click">
   7:                     <nBehaviors:ExecuteCommandAction 
   8:                         Command="{StaticResource EMailCustomerCommandRelay}"
   9:                         ParameterBinding="{Binding Mode=OneWay}"/>
  10:                 </i:EventTrigger>
  11:             </i:Interaction.Triggers>
  12:         </Button>
  13:     </StackPanel>
  14: </DataTemplate>

Now, remember this is all doable in Blend, so it's really quite simple once you get past declaring the relay and bridging the ICommand steps. For our sample scenario discussed above, you can download the Blend Project including the ViewModel part that is consumed by the CommandRelay.

Relay Commands in Blend

Summary

In summary, I've show how the ICommand related infrastructure in nRoute.Toolkit helps you to define, consume, manage and use ICommands in Silverlight. Further, given how central ICommands are to MVVM we have a feature-rich implementation that helps with both View and ViewModel sides of the divide, and also overcomes most of the platform-level shortcomings in Silverlight.

Download the nRoute.Toolkit from Codeplex
Download the Relay Command Project Source (note, require the toolkit dll)

Posted by Rishi on 03-Nov-09 8:28 AM, 26 Comments

Categories: nRoute, nRoute

In the first part I introduced nRoute.Toolkit as nRoute vNext sans Navigation and Composition components - whilst it lacks two of the key features, it introduces a boat-load of new features including Bindable Dependency Objects, Bindable Triggers, Actions and Behaviours for Blend, an IObservable-based Messaging Framework, Services component, View Services component, Modules component, ViewModel component and more. Extending that feature-set, in this post I'll cover some of the other more component-oriented features in the toolkit, like ICommand implementations, ICommand extensions, Weak Eventing handlers, Eventing extensions, and various Relays.

Action(able) ICommands

With regards to MVVM in Silverlight, I believe two interfaces carry a disproportionate share of the "architectural burden"  - with the two interface being ICommand and INotifyPropertyChanged. Both these interfaces bridge the chasm between the View and the ViewModel - one signifies an action occurrence, and the other signals a value change. Now, as far as the ICommand related functionality is concerned, they are well represented in the toolkit by two implementations named ActionCommand<T> and ActionableCommand<T>. Both of these implementations are actually refinements of what was earlier available in nRoute, however now they derive from a common interface called IActionCommand.

IActionCommands

With reference to the IActionCommand interface, the 'IsActive' property allows you to enable or disable the command, whereas the 'RequeryCanExecute' method allows you re-evaluate as to if the command can be executed, and CommandExecuted event is, well, quite self-explanatory. Both the ActionCommand<T> and ActionableCommand<T> support strongly-type parameters, and take in an Action<T> delegate to handle the command execution. The difference between Action and Actionable Commands is that the latter allows you to designate another delegate to determine as to if the command can be executed. Here's a simple example:

   1: // declared
   2: public ActionableCommand<string> SearchCommand { get; private set; }
   3:  
   4: // defined
   5: SearchCommand = new ActionableCommand<string>((s) => Repository.Search(s),
   6:                 (s) => !string.IsNullOrEmpty(s));

In the example above, we have defined a command that can take in a string value and uses it to search some repository. The command also defines a delegate that ensures that the search string is not null or empty before executing the command.

Now, as show in the class diagram, we also have non-generic versions of these commands that not only drop the generic parameter but also relieve you from having to process the same - so they ask for an Action delegate as opposed to Action<T>. I was surprised how useful these non-generic versions are, in my own use scenarios nowadays almost 95% of all of my commands are of the parameter-less variety.

Command Extensions

Very often you will find that a command's execution is dependent on some other factor, for example a delete command might be dependent on having something selected or like above a search command is dependent on the search-string being not null and not empty. Given a set of dependencies, a single change in any dependency requires us to manually re-evaluate a possibility of change in the executable-status of the command - specifically, with the IActionCommand interface, this is done via its RequeryCanExecute method (which inturn suggests this by raising its CanExecuteChanged event).

So, the point of the command extensions is to explicitly define dependencies which then can automatically trigger the possibility of a change in the executable-state of a command. I think the concept is easier described in code, have a look:

   1: var DeleteCommand = new ActionableCommand(
   2:     () => Repository.Delete(this.ActiveItem),
   3:     () => this.ActiveItem != null
   4: ).RequeryOnPropertyChanged(this, () => ActiveItem);

In the snippet above, the delete command allows us to delete the active item, where an active item is something that has been say selected in a ListBox. And the constrain on the execution of this command is that the ActiveItem property is not null, as shown in line 3. Now every time the selection of the ActiveItem changes, we must re-query the command's executable state - this intent is made explicit with the extension method shown in line 4. Here, the extension method exploits an INotifyPropertyChanged capable ViewModel (this) and listens for 'ActiveItem' property changes, which when changed triggers a re-query of the command's executable-state. Another version of this extension method exists that doesn't require a property name, as it listens to any/all property changes.

Similarly, we have another extension method that re-evaluates the executable-state after the command is executed. In the example below, the command's task is to set the count value to zero and therefore is only executable when the count is not zero. By using the RequeryWhenExecuted extension method we ensure that whenever the command is executed it's state is re-evaluated.

   1: var SetCountZeroCommand = new ActionableCommand(
   2:     () => this.Count = 0, 
   3:     () => this.Count != 0);
   4: SetCountZeroCommand.RequeryWhenExecuted();

There is another similar extension method called RequeryOnCommandExecuted which re-evaluates a command's status when another command is executed. So for example:

   1: // two commands
   2: SubscribeCommand = new ActionableCommand(() => { ... };
   3: UnsubscribeCommand = new ActionableCommand(() => { ... };
   4:  
   5: // explict dependencies
   6: UnsubscribeCommand.RequeryOnCommandExecuted(SubscribeCommand);
   7: SubscribeCommand.RequeryOnCommandExecuted(UnsubscribeCommand);

In the case above, the subscribe and unsubscribe commands' execution-states are re-evaluated when any of the other command is executed. Their respective execution-state is dependent on the whether or not a subject is subscribed or not. Another extension method called RequeryOnCommandCanExecuteChanged can re-evaluate a command by listening to another command's CanExecuteChanged event. However, you must be careful to not peg this extension method onto two commands re-querying against each other, as you will create an infinite loop between the two.

   1: // Declared
   2: public ActionableCommand CreateItemCommand { get; private set; }
   3:  
   4: public ActionCommand UndoCommand { get; private set; }
   5:  
   6: // Dependency Defined
   7: UndoCommand.RequeryOnCommandCanExecuteChanged(CreateItemCommand);

Lastly, we also have a RequeryOnCollectionChanged extension method, that can re-query a command when an INotifyCollectionChanged implementing collection changes. For example below, the command's execution status is dependent on the messages' collection having one or more messages, and so we make that explicit:

   1: ClearCommand = new ActionableCommand(() => Messages.Clear(),
   2:     () => Messages.Count > 0).RequeryOnCollectionChanged(Messages);

These extension methods work by pinging against the IWeakEventListener implementation that both ActionCommand<T> and ActionableCommand<T> support. Basically, the commands uses the ReceiveWeakEvent method to listen to any external suggestions that the command's execution-state might have changed, and so when pinged they raises the CanExecuteChange event to tell others to check their execution-status against the command. And as the interface name suggests, this is weakly/indirectly-referenced so you don't create leaking dependencies. Further, you can also use the same technique to attach explicit dependencies, using custom extension methods or just by making the command listen to any relevant event.

ExecuteCommandBehavior Execute Command Behavior

The ExecuteCommandBehavior does as it reads - with two notable features, one that both the command and command parameter are bindable. And second that it can enable/disable the usage of the associated element if ManageEnableState option is selected (see right).

The ManageEnableState option basically enables or disables a Control-type derived element, based on whether or not the command is executable. It listens to the CanExecuteChanged event and can re-evaluate the execution state of the command. Now, in the case where the element attached to the behaviour is not a Control-type derivative, it enables/disables the "interactivity" of the element - the interactivity concept is the same as one I mentioned in part one except here when the element is disabled we set the opacity to 50% (which might not be appropriate in all cases).

ManageEnableStateOption

The snapshot above shows the effect of the ExecuteCommandBehavior managing the enable state for you. The "Button Command" reading element is a button control (which is derived from the Control type), whereas as the "Border Command" reading element is a border element (not deriving from the Control type). In both the cases when the command cannot execute, they are non-responsive to user input - however as I've mentioned before there are limitations to how far the the interactivity approach will take you.

Weak / Event Handling

In another previous post I had detailed some of my ideas around weak eventing, with the crux of the idea being that by wrapping event handlers we could make the eventing infrastructure smarter without having to re-imagine the consumption or creation of events. And smarts give us the ability to weakly-reference the consumers, which makes the event consumer's lifetime independent of the event producers. Here's the how-to:

   1: source.SomethingHappened += new WeakHandler(Handle_Something, 
   2:     (h) => source.SomethingHappended -= h);  

In the snippet above rather than using an EventHandler delegate, we are using the WeakHandler class to handle the SomethingHappened event on the source object. The WeakHandler class implicitly creates the event handler, whilst lifting itself into the handler - and so it sits between the consumer and producer of event. By virtue of having a go-between we can do a lot of interesting things (as we'll see ahead), and so we also provide wrappers for normal handling (ie. non-weak) of the events. Secondly, by having this go-between we also gain the capability to allow consumption of events for non-delegate consumers - specifically, for IWeakEventListener and IObserver<Event<T>> based consumers. Consider:

   1: // using Listeners
   2: source.SomethingHappened += new WeakListener(weakEventListenerObj, 
   3:     (h) => source.SomethingHappended -= h);  
   4:  
   5: // using Observers
   6: source.SomethingHappened += new ObserverHandler(weakObserverHanderObj, 
   7:     (h) => source.SomethingHappended -= h);  

Also the IActiveCommand component mentioned above that makes uses of the WeakListener handler, similarly the Rx Framework makes use of Event to IObserver<Event<T>> translation for all its magic. Now, I'm not going to go into the depth of the eventing infrastructure, but basically there are six main classes - which allow for handling, listening, and observing of events in both strongly-referenced and weakly-referenced manners.

EventHandling

In all the classes above the type E generic parameter is an EventArg derivative associated with the event handler delegate of type H - for example to handle a size changed event for a Window the parameter E would be SizeChangedEventArgs and the associated parameter H would be SizeChangedEventHandler. To save you some time, there are some pre-defined wrappers available to handle common events based on EventHandler, EventHandler<E>, RoutedEventHandler and PropertyChangedEventHandler delegates. Also note all the given handlers are disposable - so when a handler is called upon to dispose it unregisters from the event and clears all references to the consumer/producer paving the way to be GC'ed.

Eventing Extensions

Like I said earlier, the idea with event handling wrappers was to introduce smarts in the consumption of events - and we have a number of smarts (beyond weak handling) available in the form of extension methods. Now, a lot of this would look like the Rx Framework which is by both by inspiration and design, but functionally it is quite different - here we have a pipeline model as opposed to an event stream model. And it works by the wrapper having pre-handling, post-handling and predicate-type gateways to the actual handling of the event. Also you can use these extensions whilst consuming an event via handlers, listeners or observers.

Handle When

   1: this.MouseEnter += new Handler<MouseEventArgs, MouseEventHandler>(
   2:         (s, e) => StartDragging(e),
   3:         (h) => this.MouseEnter -= h).
   4:     When(
   5:         (e) => e.EventArgs.StylusDevice.DeviceType == TabletDeviceType.Touch);

The When extension is simply a predicate to handling the event, and so when true it handles the event else it ignores the event call.

Skip When

   1: this.MouseLeftButtonUp += new ObserverHandler<MouseButtonEventArgs, MouseButtonEventHandler>(
   2:         _mouseButtonObserver,
   3:         (h) => this.MouseLeftButtonUp -= h).
   4:     SkipWhen(
   5:         (e) => _flagged);

The SkipWhen extension is the simply a negated version of the When predicated, therefore when true it skips the handling else it handles the event.

Handle Once

   1: Button1.Click += new RoutedHandler(
   2:         (s, e) => ProcessQuotation(),
   3:         (h) => Button1.Click -= h).
   4:     HandleOnce();

As the name suggests the HandleOnce extension ensures that you handle the event once and only once, it disposes off the handler post the first event. This is quite useful especially when you knowingly will only handle the event once, as in the case of loading or initialization, and with this extension you don't have to worry about unregistering the handler.

Handle Exactly

   1: LoginButton.Click += new RoutedHandler(
   2:         (s, e) => LoginUser(),
   3:         (h) => LoginButton.Click -= h).
   4:     HandleExactly(5);

HandleExactly extension will only handle the event a given number of times, thereafter it will unregister and dispose off the handler.

Handle While

   1: AuthorizeButton.Click += new RoutedHandler(
   2:         (s, e) => Authorize(),
   3:         (h) => AuthorizeButton.Click -= h).
   4:     While(
   5:         (e) => User.Session.IsAlive);

Keeping to its name, the While extension method handles an event while the given condition is true. If the condition turns false, it will unregister and dispose off the handler.

Handle Until

   1: AuthorizeButton.Click += new RoutedHandler(
   2:         (s, e) => Authorize(),
   3:         (h) => Authorize.Click -= h).
   4:     Until(
   5:         (e) => User.Session.IsAlive);

The Until extension is basically similar to the While extension, except that it allows for at least handling the event once. The While/Until terminology is akin to similarly-named operators in Visual Basic.

Handle For

   1: _model.PropertyChanged += new PropertyChangedHandler(
   2:         (s, e) => OnCountChanged(),
   3:         (h) => _model.PropertyChanged -= h).
   4:     HandleFor(
   5:         () => _model.Count)
 
The HandleFor extension method is specifically meant for PropertyChanged event handlers, as it allows you to explicitly handle a property changed event for a given property. Like in the example above it only handles the event when the Count property changes.
 
Throttle Handling
   1: this.DecreaseButton.Click += new RoutedHandler(
   2:         (s, e) => _viewModel.DecreaseCount(),
   3:         (h) => this.DecreaseButton.Click -= h)
   4:     Throttle(
   5:         TimeSpan.FromSeconds(5d));

The Throttle extension limits the handling the event to once per the given duration, so in the example above the handler will only be allowed to be executed once every five seconds from the execution of last event - with other calls within the same period being ignored.

Handler Timeout

   1: this.ConfirmButton.Click += new RoutedHandler(
   2:         (s, e) => _viewModel.Confirmed(),
   3:         (h) => this.ConfirmButton.Click -= h).
   4:     Timeout(
   5:         TimeSpan.FromSeconds(120), () => ConfirmButton.IsEnabled = false);

The Timeout extension awaits for event to occur within the specified time span, failing which the event handler is deregistered and the handler disposed off. Also you can specify an Action to be executed when the timeout expires. One benefit to this extension is that it brings the timeout semantics to any/all types of event.

Recurring Timeout

   1: this.KeyUp += new WeakListenerHandler<KeyEventArgs, KeyEventHandler>(
   2:         _dharmaInitiativeListener,
   3:         (h) => this.KeyUp -= h).
   4:     RecurringTimeout(
   5:         TimeSpan.FromMinutes(108), () => BlowupLostIsland());

The RecurringTimeout extension is basically like the Timeout extension except that every time the event occurs it resets the timeout and starts counting down again. Similarly, if the timeout were to occur the event handler is deregistered and the handler is disposed off, plus you can also specify a timeout Action delegate.

Lastly, note you can apply one or more of these extensions to a single handler, and equally you can create your own extensions for use with the given handlers in the toolkit.

Relays

My earlier post on relays, introduced IValueConverter and ICommand relays - building on that, we now have a ValueRelays and binding support for all relays types. Simply put, the point of relays is to act as a statistically declared go-between the actual implementation or value that is specified at runtime. The scenarios where this is useful is when you need to delegate the actual implementation/value from some other source such as a ViewModel or into something like a DataTemplate.

Value Converter Relay

Basically you use the ValueConverterRelay as a statistically declared resource that fronts an IValueConverter implementation defined at runtime. Statically, declaring a relay is as simple as:

   1: <nComponents:ValueConverterRelay x:Key="DateStringRelayConverter" />
 
Once the declaration is set, there are multiple ways to set the backing implementation. A direct way to set the implementation is to get the resource in your code-behind and set the converter.
 
   1: ((ValueConverterRelay)this.Resources["DateStringRelayConverter"]).Converter =
   2:     new ValueConverter<DateTime, string>((d) => d.ToString("DD, MMMM"));
 
To make the code-behind scenario a bit easy to use there are a couple of extension methods in the toolkit that allow you to set the resource-based relay declared with any FrameworkElement. So in the example below, we are setting the relay defined in the root level element's (this) resource collection:
 
   1: this.SetRelayConverter<DateTime, string>("DateStringRelayConverter",
   2:     (d) => d.ToString("DD, MMMM"));
 
Now, this approach for declaring and creating value converters is not an all-purpose solution, however for many simple cases and where the conversion logic is local to your use this compact approach helps. The other benefit of using relays is you can change the implementation at runtime, or as shown below you can have the value-converter's logic rooted in the larger logic of your ViewModel.
 
BridgeViewConverterBehaviorThe other way of defining a backing implementation for a value-converter relay is to bind the relay by bridging it. To do this, you can use the generously-named BridgeValueConverterBehavior type behaviour, and have it bind to any implementation like say from your ViewModel.
 
In the screenshot on the right, we have the ValueConverterRelay statistically bound to a local resource (show by the green rectangle), and the converter source is being feed from the ViewModel via binding (show by the yellow rectangle). And back in your ViewModel you can define the value-converter using the generic ValueConverter<TIn, TOut> wrapper class found in the nRoute.Components namespace.
 
   1: // declare
   2: public ValueConverter<User, string> UserNameConverter { get; private set; } 
   3:  
   4: // define
   5: UserNameConverter = new ValueConverter<User, string>(
   6:     (u) => u.LastName.ToUpper() + ' / ' u.FirstName + ' ' + u.Title);
 
Above the UserNameConverter is just a property in your ViewModel, which is sourced via bridging and consumed indirectly via the relay. Also notable is the fact that Silverlight doesn't support multi-bindings, so using value-converters like above can come in real handy.
 
Command Relay
 
I hope the name gives it away, but the CommandRelay is the equivalent of ValueConverterRelay for use with an ICommand implementation. Functionally, using and declaring them is similar to value converter relays, consider:
 
   1: <!-- Declared as a Resource -->
   2: <nComponents:CommandRelay x:Key="UpdateTimeRelayCommand" />
 
And to define the implementation in the code-behind, we can use an extension method like:
 
   1: this.SetRelayCommand<object>("UpdateTimeRelayCommand", (o) => UpdateTime());
 
Alternatively, we can also define the implementation by bridging the command using a BridgeCommandBehavior type behaviour available in the toolkit (note, in Blend you will currently have to use xaml to define the source of the command).
 
   1: <i:Interaction.Behaviors>
   2:     <nBehaviors:BridgeCommandBehavior 
   3:         CommandRelay="{StaticResource UpdateTimeRelayCommand}" 
   4:         CommandSourceBinding="{Binding UpdateTimeCommand, Mode=OneWay}"/>
   5: </i:Interaction.Behaviors>
 
In the case above we are sourcing the implementation of the command from the ViewModel. And one of the primary use scenarios of relayed commands is with DataTemplates in an ItemsControl. Since data templates are statically declared they are impervious to the data context of the View, and moreover their data context is set to the item being enumerated. In such a case, having them trigger commands in the ViewModel can be achieved via relays - so for example with the sample UpdateUserRelayCommand declared and bridged above, we can use it within a DataTemplate as such:
 
   1: <!-- Data Template declared as a Resource -->
   2: <DataTemplate x:Key="TimeInfoTemplate">
   3:     <Grid>
   4:         <Button Content="Update Time">
   5:             <i:Interaction.Triggers>
   6:                 <i:EventTrigger EventName="Click">
   7:                     <nBehaviors:ExecuteCommandAction 
   8:                         Command="{StaticResource UpdateTimeRelayCommand}"/>
   9:                 </i:EventTrigger>
  10:             </i:Interaction.Triggers>
  11:         </Button>
  12:     </Grid>
  13: </DataTemplate>
 
The Button in the DataTemplate above is rigged to raise a command when clicked - and using the bridge the command is ultimately trigged in your ViewModel. Now, having to first declare, bridge and then use the command may seem burdensome, but that speaks more to the shortcoming of Silverlight than to the solution for it.
 
Value Relay
 
A ValueRelay is again like before a statically declared facade for a value sourced at runtime - and its declaration as a resource is a simple as ever:
 
   1: <nComponents:ValueRelay x:Key="CurrentTimeRelayValue" />
 
And to source the value from a code-behind can be done as such:
 
   1: this.SetRelayValue<DateTime>("CurrentTimeRelayValue", DateTime.Now);
 
BridgeValueBehavior For bridging the value we can make use of the BridgeValueBehaviour type behaviour. It takes in the relay and provides it with a value as defined by either the ValueSource or ValueSourceBinding property (see right).
 
The ValueRelay implements INotifyPropertyChanged, which ensures that its consumers are updated whenever the source of the value changes. Also, as with the relays earlier, you can use this to convey some value to a DataTemplate from your ViewModel - which at times can be a lifesaver.
 
Now, the binding syntax to consume the value through a ValueRelay is slightly different than earlier - the main change being that we need to access the Value property of the ValueRelay to get the underlying value.
 
   1: <TextBlock Text="{Binding Value, 
   2:     Source={StaticResource CurrentTimeRelayValue}, Mode=OneWay}" />
 
Also, all relays support an Initialize event which at times is required, because depending on the use-case the resource-based relay should be available during the parsing of xaml, in which case the Initialize event can be used to setup the value - a previous post on relays details this scenario.
 
What's Next
 
The first release of nRoute specialized in View-level composition and navigation using Url-based routing. Now, as highlighted with this toolkit release, I've tried to include features that provide for Application-level composition using building blocks such as modules, services, view-services, loosely-coupled messaging etc. Additionally, I've also put in lot of infrastructure-level building blocks that tackle some of the bigger shortcomings in the platform like binding support, weak-eventing, relays, data-triggers support etc. With all the three-levels of concerns, the underlying intention is to make nRoute a more wholesome platform that extends beyond the self-defined application-flow role, to more-of a LOB framework designed for MVVM-oriented applications.
 
Based on that idea, the main highlights of the next drop of nRoute are dynamic application composition using SiteMaps, support for navigation to remotely defined resources, and a much improved Url-based Action infrastructure. Also I've written some extensions to RIA services for use with nRoute, that makes RIA services much more MVVM friendly whilst raising the level of abstraction of the Models provided by RIA Services. Put together, it should hopefully be a good starting point for any LOB application.
 

Posted by Rishi on 10-Oct-09 11:33 AM, 29 Comments

nRoute Toolkit is basically a packaging of some components from the next drop of nRoute - I thought some of the components had merit beyond the nRoute framework, so I packaged them separately in a smallish 50K toolkit. The Silverlight only toolkit features Bindable Dependency Objects, Bindable Triggers, Actions and Behaviours for Blend, an IObservable-based Messaging Framework, a Resource Locator Framework, Module Components, Service Components, ViewModel Components, ViewService Components, Weak Eventing Handlers, Action ICommands and a number other bit and pieces useful for MVVM style development.

I hope to have this introductory post as a semi-documentation for the toolkit and its features, so please bear with me as it does get long. Secondly, the next drop of nRoute will essentially be a superset of what's in this toolkit - namespaces and all will remain the same, however the toolkit doesn't include any routing or navigation related features.

Bindable Dependency Objects

One of the biggest pain point with Silverlight, as of version 3, is that it only supports binding on FrameworkElement derived objects - which in effect limits binding to "visual components" - and therefore "inline" elements don't get the benefit of binding. Now, what I have here is not a perfect solution but a pretty workable one, and I refer to it as attached-bindings because it attaches the binding on any FrameworkElement derivatives (even non-hierarchically related).

The trick in play here is that you have to expose and consume the binding as a System.Windows.Data.Binding type. So for instance, say we have a Dependency Object derived class that has a ordinary "IsReady" dependency property; now, to make it bindable using attached bindings, we have to use what I call a dual-property pattern - wherein we expose the property "normally" but also have another property (post-fixed with the Binding word) of type Binding that is used to bind to the dependency property. Have a look below, note 'GetAttachedBinding' and 'SetAttachedBinding<T>' are extension methods:

   1: public bool IsReady
   2: {
   3:     get { return Convert.ToBoolean(this.GetValue(IsReadyProperty)); }
   4:     set { this.SetValue(IsReadyProperty, value); }
   5: }
   6:  
   7: public Binding IsReadyBinding
   8: {
   9:     get { return this.GetAttachedBinding(IsReadyProperty); }
  10:     set { this.SetAttachedBinding<bool>(_frameworkElement, IsReadyProperty, value); }
  11: }

Given the above, to bind we use the binding syntax against the 'IsReadyBinding' property, while to read the current value of we use 'IsReady' property. If you don't want to use bindings, the IsReady property works just as before and everything else remains the same. The critical part to enable attached bindings is to have a FrameworkElement derivative element to attach too, as represented above by the '_frameworkElement' variable - without this it wouldn't work. But once you have that you can have as many attached-bindings appended to it as you like, it doesn't matter. Secondly I understand having an additional property for each bindable property is not ideal, but it's a working solution and is kind of akin to the async post-fix we already use. Plus, with the extension methods shown above this is not that intrusive of a methodology, especially since you don't need do anything more than create an additional property declaration per dependency property.

Now there are a lot of uses for this, and using this infrastructure included in the toolkit are extensions to the Blend behaviours framework as we'll see right ahead - this also happens to be my favourite new feature in the toolkit.

Bindable Behaviors, Actions and Triggers 

In the first drop of nRoute I did a lot of work on behaviours, in fact I did create something very similar to what is available in Blend but didn't generalize it using triggers, rather per my preference of strong-typed stuff, I created many-many statically declared attached properties to expose/use behaviours. But part of the reason was also that inline dependency objects could not be bound in Silverlight, where as attached properties declared directly onto any FrameworkElement derivate could be. Now, with the binding infrastructure given above and fantastic tooling support in Blend, I choose to dump my behaviour's framework and extend the behaviours and triggers framework made available with the Blend SDK - essentially by making them bindable. This really makes for some fantastic possibilities, because we can now use and consume behaviours that are directly bound to our ViewModel or have them react to property changes through the richness of binding in Silverlight.

In the nRoute.Behaviors.Interactivity namespace you will find four classes that extend the behaviours, trigger actions and triggers in the Blend SDK, with bindable base classes.

BindableBehaviors

The binding-enhanced base classes (below the red-line) give you wrappers around the attached binding solution, and a very important capability to set bindings even when the "AssociatedObject" is not available (it stores and applies the binding to it when the object is attached). So for example, if we had the IsReady property sampled above exposed in any of the above behavior/trigger classes we would write the same as:

   1: public bool IsReady
   2: {
   3:     get { return Convert.ToBoolean(this.GetValue(IsReadyProperty)); }
   4:     set { this.SetValue(IsReadyProperty, value); }
   5: }
   6:  
   7: public Binding IsReadBinding
   8: {
   9:     get { return base.GetBinding(IsReadyProperty); }
  10:     set { base.SetBinding<bool>(IsReadyProperty, value); }
  11: }

As you can see in Line 9 and 10 we are using the base-class based GetBinding and SetBinding methods, they do the attach-binding business underneath. So quite simply, to make your behaviour/trigger/trigger-action property bindable you just need to additionally write something similar to lines 7 to 11 and that's it. Also, with this you can use all the UI facilities in Blend to set the bindings as usual, alternatively if you wanted to bind to static resources you would use the non-binding version (ie. IsReady and not IsReadyBinding). The binding-enhanced base classes are there for your own use, but I've also included some commonly needed behaviours, triggers, and trigger-actions some of which are detailed below.

Value Triggers

Value triggers are Blend-SDK based triggers that fire when a given property's value matches a given criteria - for example, you could use a ValueTrigger to show a special discount animation when when the total cart amount exceeds $1000 in your ViewModel. You can also use this with UI controls, like match some value in a text box and trigger a command in your ViewModel.

In many ways ValueTriggers are central to MVVM, because to my understanding in a MVVM architecture data changes are the primary ViewModel-based mechanism that effect changes in View, and for the other side of the equation data changes and ICommands are the two View-based mechanisms that effect changes in the ViewModel (see the diagram below). Events are not used, because they are a form of direct-coupling - and so there is a total reliance on the SL binding infrastructure for the loosely-coupled glue that makes it all possible. Further for me, this minimal scope of connections is both the beauty and the practical stick that keeps the ViewModel and View independent of each other despite the fact they are intimately interwoven.

ViewViewModelSignifiers

Given the concept above, the practical problem in SL today is consuming the data-changes to effect logical changes in your application, value changes in the controls such as text value is 100% supported but changing the logical state is not. And this is where the ValueTriggers come into play, by combining binding, triggers and trigger-action we can effect logical changes in the View such hiding something or moving something. Next, I'll go through the five value triggers available in the toolkit - just keep in mind you can pair this up with just about any trigger-action or behaviour.

ValueMatchTriggerValueMatchTrigger

Basically it allows you trigger an action when a given source's value equals to another specified value - in the example shown from Blend, the value must match the specified "nRoute" value and then only will it trigger the associated action. Also, the source binding is coming from a ViewModel and we're matching it against a static word but you could match it against anything bindable by using the ValueBinding property. Also note any changes in the Source Binding triggers a re-evaluation of the condition. Alternatively, if you require it not match the specified value then you can negate the result, by using the negate checkbox. The xaml for this example looks like:

   1: <nTriggers:ValueMatchTrigger SourceBinding="{Binding Key, Mode=OneWay}" Value="nRoute">
   2:     <nBehaviors:SetPropertyAction PropertyName="Foreground" Value="#FFFF0000"/>
   3: </nTriggers:ValueMatchTrigger>

Note, by default in Blend the Value property wouldn't be editable, in that case you might have to append it via xaml directly - I hope to create Blend designer extension soon to rectify this.

ValueNullTrigger

This is similar to the ValueMatchTrigger in that it exclusively looks to match the source value to a null. You can also negate this, so that it matches a non-null value. This is really useful when tracking asynchronously loaded data, for example when loaded items list in not null, we could visually effect the UI to indicate the availability of the data. Below is an example of this in xaml:

   1: <nTriggers:ValueNullTrigger SourceBinding="{Binding Key, Mode=OneWay}" Negate="True">
   2:     <nBehaviors:SetPropertyAction PropertyName="Foreground" Value="#FF23FF18"/>
   3: </nTriggers:ValueNullTrigger>

ValueCompareTriggerValueCompareTrigger

Most data comparisons boil down to equals to, greater than, less than or their negated comparisons - and so in addition to earlier mentioned triggers, the ValueCompare trigger allows you to value comparisons with >, >=, ==, !=, <, <= equality operations. For comparison purposes it relies on source value implementing the IComparable interface or you specifying an IComparer implementation.

In the screenshot from Blend show on the right, we compare some Source Value bound from a ViewModel being greater or equal to ten - which triggers the specified trigger action. In xaml the same thing would look like:

   1: <nTriggers:ValueCompareTrigger SourceBinding="{Binding Value, Mode=OneWay}"
   2:     Equality="GreaterThanOrEquals" Value="10">
   3:     <nBehaviors:SetPropertyAction PropertyName="Foreground" Value="#FFFF4321"/>
   4: </nTriggers:ValueCompareTrigger>

Note how dual properties pattern I mentioned earlier, makes everything bindable in Blend but in a bit more extraneous way than normal. Also note the possibility of negating the comparison result, with the negate option.

ValueChangedTrigger

As the name suggest this trigger executes every time its source value changes - which at times is all you need. The xaml example below triggers an animation whenever the value changes:

   1: <nTriggers:ValueChangedTrigger SourceBinding="{Binding Key, Mode=OneWay}">
   2:     <im:ControlStoryboardAction Storyboard="{StaticResource FlashTitleStoryboard}"/>
   3: </nTriggers:ValueChangedTrigger>

ValueSwitchTrigger

Just as in procedural code the switch-cases pairing allows you selectively trigger one or more actions if the Source value matches the Case value. Have a look at a xaml example, first:

   1: <nTriggers:ValueSwitchTrigger SourceBinding="{Binding Value, Mode=OneWay}">
   2:     <nBehaviors:SetPropertyAction nTriggers:ValueSwitchTrigger.CaseValue="1"
   3:         PropertyName="Foreground" Value="#FFFF4321"/>
   4:     <nBehaviors:SetPropertyAction  nTriggers:ValueSwitchTrigger.CaseValue="2"
   5:         PropertyName="Foreground" Value="#FF23FF18"/>
   6: </nTriggers:ValueSwitchTrigger>

In this example we are binding to some "Value" property from our ViewModel, and below are two actions each with a specified case value (using the ValueSwitchTrigger.CaseVale attached property). Now, if the value is one, the first trigger action will be activated, and if value is two the second trigger action will be used. I think it is really simple, yet very powerful and makes use of the all binding goodness in Silverlight.

KeyTrigger KeyTrigger

The KeyTigger is not part of the value-related triggers, all the same it a very useful trigger that responds to keyboard events. Now, I understand there is already an existing KeyTrigger in Blend, but before I found it I had already created this one and I've kept it because it helps with some advance scenarios.

More or less it is all self explanatory, except you can check for more than one modifiers - so a Control+Shift+V can be checked for. Also, you can negate the result to be everything except the keystrokes you have specified, and believe me this is useful. You can also throttle the key inputs by specifying a duration within which only a single key stroke will be processed - again this really useful and recently I had a situation where the UI couldn't keep up with keystrokes so I throttled the user's input and it worked like a charm. Lastly, you can also specify the max number of key strokes past which it will disable the triggering - useful for perhaps limiting baby smash torture.

MouseWheelTrigger.cs MouseWheelTrigger

The MouseWheelTrigger is not like a scrolling solution, it is a trigger which fires when the MouseWheel turns and you can then use it to invoke an action such as scrolling or index change. Also it passes through a delta value, which is factored by whatever you have specified in the DeltaFactor property (the default as shown is 120). And like the KeyTrigger you can throttle the mouse wheel events by defining a time-duration to allow-in a single wheel event.

Trigger Actions

SetPropertyAction I've only included four trigger-actions in this Toolkit, yet I've found them to remarkably useful particularly because they make of the of the binding.

The first of the four triggers is SetPropertyAction, which you've seen being used above - and as the name suggests, it is used to set a property value on the applied element with a specified value. Now, there is something similar already in Blend, but herein we get the possibility to set a binded value - which opens it up to your ViewModel's usage. In the blend screen grab on the right we are setting the text property to a value from our ViewModel, when the associate trigger invokes the action. Also if you just wanted to set the value statically use the non-binding Value property.

Quite similar to the SetPropertyAction is the TargetedSetPropertyAction, using which you set value on another element (ie. the target) as opposed to the declaring element itself. For example:

   1: <i:EventTrigger EventName="Click">
   2:     <nBehaviors:TargetedSetPropertyAction TargetName="BackgroundRectangle"
   3:          PropertyName="Fill">
   4:         <nBehaviors:TargetedSetPropertyAction.Value>
   5:             <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
   6:                 <GradientStop Color="#FFB8EBFF" Offset="0.762"/>
   7:                 <GradientStop Color="White"/>
   8:             </LinearGradientBrush>
   9:         </nBehaviors:TargetedSetPropertyAction.Value>
  10:     </nBehaviors:TargetedSetPropertyAction>                        
  11: </i:EventTrigger>

In the xaml above we are setting the "Fill" property on a Rectangle type element named "BackgroundRectangle" upon a click event. Again by using this with value triggers and binding you get a really powerful tool in your hand, and for the most part this is all Blendable. I will discuss the other two triggers action, in relation to other features because they are related.
 
Behaviours (or Behaviors if you prefer)

I've included four generalized behaviours, in addition to some feature specific ones, and they resolve around the idea of having an element viewable depending on the source being null or not null, or based on some true/false evaluation. This is really useful, in scenarios where you are loading data asynchronous and parts of UI are to be viewable per the availability of data.

So the first of these behaviours is called the BoolValueVisibilityBehavior, which make the targeted element visible if the given bool Value is true else the visibility is set to collapsed. You can negate this behaviour by using the negate option, like before. Similarly, the NullValueVisibilityBehavior sets the visibility to collapsed if the given value is null else it sets it to visible. This is again is negatable, and the value you evaluate against is bindable because it uses BindableBehavior<T> base class mentioned before.

For example, consider we have a search bar we don't want to show until some data is loaded into a ListBox, and so we could attach the following behaviour that tracks as to if the Items property from the ViewModel is null or not. And because we are using dependency properties we listen to data changes, so say if the data is re-loading then the toolbar will automatically hide and show-up when the data has been loaded again.

   1: <i:Interaction.Behaviors>
   2:     <nBehaviors:NullValueVisibilityBehavior ValueBinding="{Binding Items, Mode=OneWay}"/>
   3: </i:Interaction.Behaviors>

NullValueInteractivityBehavior I find the above very useful, but there is a very significant side-effect to setting the visibility to collapsed in that it "shutsdown" the element from processing visual changes. And so for example, if you were to put a NullValueVisibilityBehavior onto a ListBox and wanted to have it viewable once the ItemsSource is set - the items wouldn't show up because when collapsed it wouldn't have process any UI changes - and rightly so.

Now how do deal with that, well firstly we make an element non-viewable by setting its opacity to zero. However, the ListBox could still process mouse events, which is a problem especially if it unknowingly to the user triggers some changes and yet the element is not visible to the user. The second, step to rectify this is to set its IsHitTestVisible property to false - which makes the element non-interactive and yet the UI changes will be processed underneath.

Now, by combining the two solution above I've packaged them as interactivity altering behaviours called BoolValueInteractivityBehavior and NullValueInteractivityBehavior - which like their visibility counterpart, can used to make an element non-viewable though in this case they are capable of processing UI changes. However note this is not a perfect solution, because an element could still possibly handle keyboard triggered changes, if it had the focus. Nonetheless, in a lot of scenarios this works out just fine but be careful of the caveat. And just like before, you can inverse the workings of all these behaviours by using the negate option.

IObservable-based Messaging Framework

Recently, with the Silverlight Toolkit there was a hidden gem shipped by the name of Rx Framework, which you can read about extensively here. Basically, the idea behind it is that by using the observable pattern you can do "reactive programming", kind of like event handling. But the twist is that you can turn past, current and future "observed items" into a persuado data source, which opens it using LINQ to process, shape and consume the observed data. Think event stream processing, as opposed to a pipeline model - and the items are like an IEnumerable being pushed as opposed to being pulled. I am not gonna discuss the reactive framework here, but it is really cool and you should definitely check it out if you still haven't.

In relation to the Rx Framework, what I've done is used its interpretation of the observable pattern vis-e-vie their IObservable<T> and IObserver<T>interfaces (which I understand will be part of .NET 4 and hopefully SL4) and created so-called Observable Channels - which are basically singleton implementations of the IObservable<T> to which you can subscribe and publish. With the publish subscribe capabilities, it becomes a messaging framework kind of like Prism's EventBroker, but with a very easy to use API. 

MessagingFramework

As show above the Channel<T> class is the IObservable<T> implementation, to which any implementation of IObserver<T> can subscribe. Once subscribed, we return an IDisposable implementation based on the ChannelSubscriptionBase<T> class. In simpler terms you subscribe to a channel of Type T, whereby T can be any type you want to send and receive messages for, and on subscription you get a channel subscription token onto which you can call the Dispose method to get yourself unsubscribed.

Now, also provided is a generic IObserver<T> implementation predicatively called ChannelObserver<T>, and it makes it really easy to consume any channel's incoming data, as well Subscribe and Unsubscribe as required. Below is an example, for that:

   1: // declared
   2: ChannelObserver<ApplicationStateInfo> _observer;
   3:  
   4: // subscribe
   5: _observer = new ChannelObserver<ApplicationStateInfo>((s) => DoSomething(s.CurrentState));
   6: _observer.Subscribe(ThreadOption.UIThread);
   7:  
   8: // unsubscribe
   9: _observer.Unsubscribe();

Here we are tunning into the "ApplicationStateInfo" channel, which is one of the build in channel used by the Resource Locator Framework. It basically, publishes application lifetime state changes - which include starting, started, exiting, and exited states (this is based on IApplicationLifetimeAware callings). Note to subscribe one has to explicitly call for it, as shown in line 6, and the option we are excising there is to receive the subscription on the UI thread. Similarly to unsubscribe you need to call the Unsubscribe method and you can also check if you are currently subscribed via the IsSubscribed property. Further, once you have unsubscribed you can subscribe again, which makes it really easy to play/pause a subscription using the ChannelObserver.

By default, subscriptions are weakly referenced - which means that even if a subscriber that goes out-of-scope, were not to unsubscribe, it would still be available for GC (though you should always unsubscribe). On the flip side, if you wanted to ensure a non-weak referenced connection, for performance reasons or otherwise you could choose an option during subscription to keep the subscriber strongly-referenced.  Just as in Prism's Event Broker (whose API I've mimicked), you can subscribe to on the UI Thread, on the Publisher's Thread, or in a Background Thread. Also you have the option to publish asynchronously, however in this case you need to ensure the subscribers don't run into cross-threading exceptions. And keep in mind that, by design, a Channel always throw back any exception raised by a subscriber whilst receiving a payload.

Publishing to a channel is very straightforward, just use either the Channel or Channel<T> class to publish, there are also non-generic overloads available for publishing. Below is a straightforward example, of publishing a SearchQuery:

   1: // to publish a search query
   2: Channel.Publish<SearchQueryInfo>(new SearchQueryInfo("Silverlight"));
   3:  
   4: // to publish async search query
   5: Channel.PublishAsync<SearchQueryInfo>(new SearchQueryInfo("Silverlight"));

ChannelPublishActionAlso included is a trigger action which allows publishing to a channel directly from the UI. Because the ChannelPublishAction can bind the payload from the ViewModel, you could rig say a button 'click' to trigger the publishing. Also it can determine the channel by the type of payload set, however in cases it is expected to be null or based on derived types, you must set the ChannelType explicitly.

Coming back to the Rx Framework, because the channels are basically an IObservable implementation they are open to party on the IObservable-related LINQ operators available in the Rx Framework. And this is big deal, because you do a lot of intelligent processing on the client side (and I will try and show this separately with a post). However note, the current build doesn't take a dependency on the Rx Framework, but a separately compiled version is available if you require.

Resource Locator Framework

IResourceLocator The Resource Locator (RL) is basically a thread-safe register of resource locators, and a resource locator is an implementation of the IResourceLocator interface, which identifies any given resource by a unique name and can return an instance of that resource (see the interface on the right).

This really is not far off from IoC components, but the idea here is that any type of resource can register its own locator. And the locator's resource materialization strategy is its own business, and so when the RL is asked for a resource, it delegates to the locator. The core of this is really very simple, but around the resource registry are a number of utilities that really make it's consumption seamless and almost transparent from direct use. 

The RL is actually a generalization of what was there in the first drop of nRoute; in fact I had two separate implementations one for navigation and one for actions that did the same thing but in a more specific manner. If you have used nRoute you will know things like the MapNavigationContent, MapActionHandler attributes that when used with MapAssemblyRoutes or MapLoadedAssembliesActions static methods located all resources and fed them into the routing engine as routes. Here with the RL, we generalized that to not just produce routes (which themselves are actually locators in a way) but return IResourceLocator which is independent of any particular use.

Now the question is how do we feed locators into the RL registry, we could do it manually one by one, through a configuration file, or we could do using my preferred way by the means of an Assembly Mapper. The mapper basically looks for all MapResourceAttribute derivates in any given assembly, and yields an IResourceLocator implementation, which is then registered automatically.

Well, we have five feature implementations in the toolkit that make use of the RL, lets have a look at them individually.

Modules

The modules concept is straight out of Prism, but herein we use the RL with attribute-based mappings to locate and instantiate a module. For example:

   1: [MapModule("ContactsModule")]
   2: public class ContactsModule : IModule
   3: {
   4:     // .. implementation 
   5: }
 
Well, line 1 is all you need to have this module located and instantiated - we have also given the module a name by which you can locate it within the registry. The MapModule attribute takes two more parameters if you like, one an InitializationMode enumeration by which you can choose to have this instantiated when the application starts or alternatively as required. The other parameter is an optional array of strings declaring dependencies on other modules (by their names) - and the assembly mapper ensures that the module is not instantiated or registered until all the dependencies are resolved. 

Modules

Thanks to the RL, there is nothing much to the Modules concept, and the only important class is the IResourceLocator implementation which is registered into the RL by the MapModule attribute. And the ModuleLocator static class is just a candy wrapper around the ResourceLocator static class, but specifically geared for Modules-related info. Also by overriding the DefaultModulesLocator and MapModuleAttribute implementations you can add more features or change the internal workings to your requirements.

Services 

Again akin to Prism, services are essentially an implementation of some service contract (defined as an interface) which can then be located and realized.

   1: [MapService(typeof(IDateService))]
   2: public class DateService : IDateService
   3: {
   4:     // implementation of IDateService
   5: }

Here in Line 1, we are registering a Service of type IDateService which here is implemented by the DateService class - note the mapped class must implement that identified service contract. Now there are two more optional parameters to that attribute, which let you specify a name for the service, another one lets your list an array of other service types that the is dependent on. Also, you have three more named parameters, using which you can specify the lifetime of the service (see the InstanceLifetime Enum), initialization mode (see the InitializationMode Enum), and a boolean value specifying as to if it is the "default" service. Services

Like with the ModulesLocator static class, we also have a wrapper class for Services which helps with getting/checking for services. Also with services, actually with all types of resources, there is a concept of having a default resource - which is either a specifically designated resource (see the SetDefaultService<T> method above) or by default the first registered resource is considered the default service. So in the case of a default service, it can be retrieved without having to specify a name. So for example:

   1: // get the default service
   2: _dateTimeService1 = ServiceLocator.GetService<IDateTimeService>();
   3: // get a named service
   4: _dateTimeService2 = ServiceLocator.GetService<IDateTimeService>("GMT");

If you said this is just about like using any IoC component out there, well, I would agree with your - and feature-wise this implementation is not even that sophisticated. However the services as a concept has a lot of semantic value, which in this context is a non-visual building block for your application. Nonetheless if you wanted more smarts, you could "smartern" the locators up by creating a custom IResourceLocator implementation that uses an IoC component under the hood.

View Models

In the earlier release of nRoute we had this unfortunately named MapViewModelViewNavigation attribute, using which you could specify the View type, the ViewModel type and a Url to go with that - and what it did was when the Url was requested it instantiated the View in a Navigation Container, then create the ViewModel, which it injected into the View as its DataContext. Here with the toolkit, we don't have the composition capabilities of the nRoute Navigation component, but we have resource locators that can inject the ViewModel into a View using behaviours. Lets look at an example:

   1: [MapViewModel(typeof(Page4))]
   2: public class Page4ViewModel : ViewModelBase
   3: {
   4:     //..
   5: }
   6:  
   7: // OR - choose either way
   8:  
   9: [MapView(typeof(Page4ViewModel))]
  10: public class Page4 : UserControl
  11: {
  12:     //..
  13: }

BridgeViewModelBehaviorAbove we are defining the association between a View and a ViewModel, you could choose either of the two mapping mechanisms - either map the View and specify the ViewModel type or map the ViewModel and specify the View type. Once we have that all you need to do is drop the "BridgeViewModelBehavior" on the View's (at the root level).

This behaviour uses the RL to locate and instantiate a ViewModel instance and then injects it into the View's DataContext. Further, as you can see on the right, we can even bind some commands to the View's lifetime events - specifically for initialization, loading and unloading. Each command can pass in a parameter, and that too is bindable. Unfortunately, the unloading command was not firing so I've disabled it for now - it seems that the OnDetaching method on the behaviour is not being called.

We also a have specialized ViewModelLocator, if you like to use it procedurally.  ViewModelLocator

Also in the nRoute.ViewModels namespace you will also find a ViewModelBase class, which just implements the INotifyPropertyChanged interface and provides an helper to notify property changes. Note, its use is not required.

View Services

The idea of the ViewServices is that the ViewModel shouldn't have to take dependency on visually implemented controls or on platform specific contraptions - think notification balloons, save file dialog, etc. In practical terms, these are exposed just like services, where we have an interface defining the contact and an implementation that is transparent from its consumption. Now, build into the toolkit are four such services for opening files, saving files, showing messages and showing exceptions.
 ViewServicesContracts

To call upon any ViewService you can make use of the ViewServiceLocator static class, which just like the ServiceLocator requires the type of ViewService and optionally a name.

   1: IShowMessageViewService _messageBoxService;
   2:        
   3: // setup 
   4: _messageBoxService = ViewServiceLocator.GetViewService<IShowMessageViewService>();
   5: _messageBoxService.ButtonSetup = MessageBoxButton.OKCancel;
   6: _messageBoxService.Text = "Please confirm?";
   7:  
   8: // use 
   9: var _result = _messageBoxService.ShowMessage();

And similarly, declaring a ViewService is very much like everything else.

   1: [MapViewService(typeof(IShowMessageViewService), IsDefault=true)]
   2: public class NewShowMessageViewService
   3:    : IShowMessageViewService
   4: {
   5:     // IShowMessageViewService Implementation
   6: }

The MapViewService attribute requires that you specify the type of ViewService you implementing and optionally it can take in a name, you can also configure the lifetime and the initialization mode - very much like Services. Also you get a ViewSerivceLocator static class that helps you consume ViewServices.

ViewServices

Now, ViewServices are different from plain-jo services in two ways, one, it is semantically designated for View related functionality whereas ordinary Services, like with Prism, are more back-end providers. The second difference is a more practical one, you could define a ViewService directly within a UIElement or UserControl implementation - and this can then be the located by scanning the VisualTree. If you look at the ViewServiceLifetime enumeration, we have a DiscoveredInstance option which works by looking for the first instance of the ViewService in the VisualTree. Another, similar option is the SelfRegisteredInstance, wherein a UIElement or UserControl declares that it's a ViewService but will will self-register it's instance through the ViewServiceLocator when it is realized in the VisualTree.

In some ways if you look at Child Windows or MessageBox or File Dialogs they are like non-integrated visuals - they are not in the VisualTree per se, whereas if you have a status bar within the main UI  that can be called an integrated-visual. So the Discovered and Self-Registering instances option is to support these kind of integrated visuals, whose life-time you do not control directly, but yet they need to be addressable directly from some Service or ViewModel.

Consider, if we have a background-running "Stocks Watch Service" which finds-some abnormalities with your preferred stock, and it want to notify you - what does it do? Well, you could give it a ViewService contract, by which it can notify the user. This idea can be used further to componentized your visuals and avail them for without creating UI dependencies, so for example you could create a Bookmarks Panel ViewService, or Logged In/Logged Out controlling ViewService.

 Intergrated-Visual

I am not sure if this is very clear, but I will provide some samples showing how this can help to expose and consume visual components in a non-visual manner.

Channel Observers

Earlier I had shown an in-built IObserver<T> implementation, which really makes it easy to listen to any channel without having to implement the IObserver<T> interface; however in some cases you might want a dedicated listener - for example, a logging observer. In these cases you can implement the IObserver<T> interface onto a class and we can register and avail it though the RL. For that, we could do something like:

   1: [MapChannelObserver(typeof(ApplicationStateInfo), 
   2:     InitializationMode=InitializationMode.WhenAvaliable,
   3:     Lifetime=InstanceLifetime.Singleton)]
   4: public class ApplicationStateObserver : IObserver<ApplicationStateInfo>
   5: {
   6:     // IObserver<ApplicationStateInfo> Implementation
   7: }

Here we are mapping the ApplicationStateObserver class as an observer for the AppicationStateInfo Channel, we have set it to be realized as a singleton instance as soon as it is registered into the RL. Also when mapping you have the option to have it listen on a particular thread, see the ThredOption enumeration. Further, you can rely on the RL to instantiate the observer very early in the application lifetime, even before the RootVisual is created.  ChannelObservers.cs

And like before, we also have a static ChannelObserverLocator, using which you can locate your registered observers - though I am not sure how useful it is. Also, the IObserver<T> interface has three methods, the OnNext method is used to receive the channel payload, however the OnComplete is never called because a channel remains open for the lifetime of the application and I see no point executing the OnCompleted when the application is about existing. Lastly, the OnError method of the interface is also effectively not called because a Channel which implements the IObservable doesn't have the context of the publisher to generate an error - though I am mulling over the idea that any publisher can also publish an error. However, for now, just keep in mind that the workings of the channel-based messaging might change as my think evolves - and if you have any input on this, do share.

Locating Resources

One of the things with Resource Locator and it's preferred mechanism of using attributes to map resources, is that an assembly is the working currency - and indeed you could load an assembly and feed it to the AssemblyMapper static class to have any and all resources mapped. To aid this scenario, there is a RemoteResourceLoader class which helps you point to any url and load either a single dll or a xap file - in the later case it reads the xap's manifest and maps all included dlls. Here's how you can use it:

   1: // to load a dll
   2: var _loader1 = new RemoteResourceLoader();
   3: _loader1.AssemblyLoadComplete += Loader1_AssemblyLoadComplete;
   4: _loader1.LoadAssembly(new Uri("DynamicallyLoaded.dll", UriKind.Relative));
   5:  
   6: // to load a xap
   7: var _loader2 = new RemoteResourceLoader();
   8: _loader2.PackageLoadComplete += Loader2_PackageLoadComplete;
   9: _loader2.LoadPackage(new Uri("DynamicallyLoaded.xap", UriKind.Relative));

It really is very simple, and in the Assembly/Package LoadCompleted event you don't need to do anything to map the assemblies that is done for you once they are loaded, but if it was an error you will need to respond to it appropriately. Also the RemoteResourceLoader class has two static methods to check if any Uri is or has been used to load either a xap or dll.

In the attribute based mapping examples you have seen above, you have to tack the attribute on the mapped target - for example the MapModule attribute has to be tacked onto the IModule implementing type - however, this might not be possible sometimes or it may not gel with your preferences. So with toolkit there is another solution to this, a rather clean one, which allows you to "define", as oppose to "map", your resources. Have a look:

 AssemblyLevelDefines 

Here I created an empty cs fil, and added these assembly-level attributes - for all functional purposes, these attributes are the equivalent of the MapXX attributes described earlier. It works just as before, however when using the define version you need to specify the mapping target - for example with the DefineModule attribute you you have to specify the implementing type in addition to the name of the Module. Beyond the mater of personal tastes, the main benefit here is that rather than having mappings sprinkled all over the project, they located are in this one single location whilst still being strongly-typed. Also I hope the "Define" prefix as opposed to "Map" makes the intent clear here.

Quite obviously, the Resource Locator doesn't start by itself - you have to make it start and the recommended way to do that is to instantiate an nRouteApplicationService class into the Application's ApplicationLifetimeObjects collection.This can be simply done in your app.xaml file like this:

   1: <!-- declare the xml namespace -->
   2: xmlns:nRoute="clr-namespace:nRoute.ApplicationServices;assembly=nRoute.Toolkit"
   3:     
   4: <!-- and add it your application's LifetimeObjects collection -->
   5: <Application.ApplicationLifetimeObjects>
   6:     <nRoute:nRouteApplicationService />
   7: </Application.ApplicationLifetimeObjects>
 
This also happens to be the recommended way of creating "extension services" in Silverlight 3, plus it also helps to plug-into IApplicationService and IApplicationLifetimeAware related functionality. I've found this is easy to forget, but it is critical, so when there is a problem make sure your not tripping this.
 
Lastly, just as I have used the Resource Locator to created specific sets of locators you can do the same for custom locators - and it really is quite easy, just answer like six questions and you are in. I'm going to defer how to do to custom locators to a separate post, for which I have an example that shows how to dynamically collate "Search Providers" in a Silverlight app.
 
Break;
 
Because this post is already way-long, I'll have a part 2 which describes some of the other new features and what else is in store in the full-edition of nRoute. Also, please consider this as a pre-beta release, and I'll have a more polished release coming along with the full nRoute drop in a couple of weeks.
 
Download the toolkit from Codeplex.
 
Update: Part II is available here