IObservable based Messaging Broker for Silverlight

Posted by Rishi on 12-Feb-10 2:51 AM - Comments (9)

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.

Creating and Porting applications to Cloud Light

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

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

Cloud Light SudokuSudoku running in Cloud Light

Declare and Define

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

IAppIAppMeta

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

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

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

I (Sudoku) App

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

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

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

Installing and Uninstall Apps

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

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

Summary

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

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

Introducing Cloud Light: a 10KB Application Runtime in Silverlight

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

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

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

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

Runtime Overview

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

Title Bar Overview

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

Applications Store Overview

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

InstallableApplications

Application Bar Overview

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

AppBar

Extensibility

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

InstallAppCommandLine

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

CloudLight3

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

Summary

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

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

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

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

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

Getting The Search Providers Results

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

SearchProviders

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

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

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

Getting The Search Providers Themselves

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

Step 1. Create the Metadata Class 

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

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

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

Step 2. Create the Resource Locator

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

SearchProviderLocator

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

Step 3. Create the Resource Mapping

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

MapSearchProviderAttribute

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

Earmarking and Consuming The Providers

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

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

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

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

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

ResourceCataloging

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

Dynamically Getting More Search Providers

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

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

Summary

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

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

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

nRoute Resource Locator Framework (Part I)

Posted by Rishi on 04-Jan-10 4:21 AM - Comments (3)

As the name Resource Locator Framework (RLF) suggests the idea is to locate resources and functionally it's like an IoC type registry. However, it is different from a traditional IoC containers in that it allows each type of resource to put in place its own resource materialization strategy, and two it is designed to be customizable and open-ended as opposed to being internalized and closed-looped. RLF forms the basis of many open-ended features in nRoute like Services, Modules, ViewServices, ViewModels etc - so it's quite extensively used and with this post we'll have an in-depth look at its workings. Additionally, we'll follow this up with a Part II that features an how-to create and use your own custom resources, complete with the source-code.

Resourcing

Like with every IoC registry, the first step is to catalog the resources - with RLF rather than creating a single master catalog, we create individual catalog for each type of resource. As shown in the class diagram below, a resource of type T is represented by a Resource<T> singleton class, which provides a static instance via the Catalog property. The idea with the per type catalog, is to minimize contention and give each and every type of resource maximum flexibility and control.
 ResourceLocators

Within a catalog each resource is represented by an IResourceLocator instance, along with a string-based unique identifier. An IResourceLocator, as seen above, identifies the resource's unique name (ResourceName property, which is also used as the identifier), stores meta-data associated with it (ResourceMeta property), and most importantly can provide an instance of the resource (GetResourceInstance method). Generally speaking, an IResourceLocator is kind of like an individual factory for an individual resource.

With regards to the RLF workings, IResourceLocator is the key abstraction by which each type of resource (or if you require even each individual resource) can provide its own materialization strategy - because when the RLF is asked for a resource it delegates to the IResourceLocator. And within the IResourceLocator you can customize the realization of a resource, so for example with Services in nRotue its locator provides lifetime management, whereas with ViewServices its locator can go through the Visual Tree and look for a resource's visual instance, or with ViewModel's locator it can inject the ViewModel in the View - that's the flexibility that sets the RLF apart from other locators/IoC containers. Also, one can use the IResourceLocator to lazily initialize resources, as using the provided API you can either request for the resource instance or it's representative IResourceLocator instance. Resource<T> catalog, in addition to storing a string-keyed dictionary of IResourceLocator, also implements INotifyPropertyChanged to which you can subscribe for notifications when the catalog changes. It also implements an IEnumerable<string> which enumerates (actually provides a snapshot of) the resource keys currently cataloged. The catalog is thread-safe, which is why the related API also provides a TryGetResource<T> and a IsResourceRegistered<T> checker methods. Also, the Default property in Resource<T>represents the concept of a default resource, which you can retrieve without providing a resource key. Also you can earmark any resource as default, and by convention if one has not been specified then the first registered resource is the considered the default instance; plus if there is no registered resource then the Default property returns a null value.

ResourceLocatorClass

The ResourceLocator static class helps you retrieve and check for any given resource, and it also features non-generic versions of all the resource-querying functions shown above. One other point to remember about resource locators in nRoute is that within a catalog, for any individual resource or entire resource-types, you can put in your custom IResourceLocator implementation it's not locked to any predefined types.

Mapping

Given the catalogs, the next task is to enlist resources into the catalogs - for that nRoute's preferred method is to use attributes to earmark or map resources. There is an assembly-based mapping component in nRoute (described ahead), using which we catalog all resources earmarked by any MapResourceBase derived attribute. The MapResourceBase based attributes are specifically picked up for mapping, and as shown below they yield IResourceLocator instances which are then cataloged.

MappingResources

Specifically, with the MapResourceBase attribute we ask for four things - one, give us the type of resource represented by the attribute (GetResourceType method), two can we initialize the locator immediately (via the CanInitialize method, if not we put it in a pending queue and try it recursively), three is it the default resource (IsDefaultResource property), and lastly help us with an IResourceLocator instance (GetResourceLocator method). Once we have the IResourceLocator instance and resource type, we register it with the specified resource type's catalog (Resource<T>.Catalog).

MapResources

As show above, in nRoute we have various derived mapping attributes for thing like Services, Modules, View-ViewModels etc. By having more specific mapping attributes, we also capture meta-data information so for example with the MapViewService attribute we also gather the lifetime and initialization settings, and that is encapsulated into a ViewServiceMeta class which can be accessed via the IResourceLocator's ResourceMeta property. Having the metadata available within the IResourceLocator, also enables the resource locators to effect the materialization of resources.

Further, just like the many MapResourceBase derived attributes shown above, you can also create your own custom mapping attributes for any resource type. In Part II, we'll go through a step-by-step process of creating a custom mapping attribute. Additionally, as a point of extensibility you can choose to extend, replace or ignore the available mapping-attributes in nRoute and have your custom mapping attributes in play - and this should work with all existing infrastructure without change.

Cataloging

In order to catalog the mapped/earmarked resources we have an AssemblyMapper component, which when given an assembly informs (via an Observable Channel) to all interested components that an assembly is available for mapping - the interested parties can then query for specific attributes against the assembly and act upon them as they please. This is how the MapResourceBase derived attributes are mapped as soon as any assembly is passed-to the AssemblyMapper. Further, the AssemblyMapper keeps a listing of assemblies it has mapped, this way if you choose to selectively check and map resources. Also note normally you don't need to be concerned by the AssemblyMapper, as you will normally just deal with MapResourceBase based mappings.

AssemblyMapperLoader

In addition to the AssemblyMapper we also have a RemoteResourceLoader component that can download and map any DLL or XAP packaged resource - this allows you to resolve and avail remote resources at runtime. Further, like the AssemblyMapper it also keeps track of the remote resources it has loaded or is loading. Note that when a remote resource is downloaded by the RemoteResourceLoader it is automatically subjected to mapping by the AssemblyMapper.

MEF'ed in the Future

For those who know Managed Extensibility Framework (MEF) the similarities with RLF are pretty apparent, especially as MEF targets the same sweet-spot of extensible/open-ended use. However, this is incidental as RLF was made independent of MEF and indeed predates MEF's presence in Silverlight. Nonetheless, for SL4 release I am looking into an update path whereby we can carry forward most of the functionality of what is available in nRoute today, but having swapped the underpinnings to MEF. There is a lot that MEF can add in terms of features, like implicit composition, automatic re-composition and resolving of hierarchal dependencies. However, RLF and MEF don't quite functionally reconcile, specifically because RLF's capability of realizing each resource or resource-type in a custom-to-self manner.

Apart from MEF, it is possible to enhance Resource Locators to play nice with any type of IoC containers - so anything resolved by the locators will go through your specified IoC container. However, this will be one-way traffic as you wouldn't be able to resolve RLF registered resources via your IoC container (circular-dependency issues).

Summary

To sum it up I'll just recap point-wise the basics of RLF:

  • For every resource type, an individual catalog is automatically created (Resource<T>.Catalog)
  • Within a catalog, for each resource we register a representative resource locators (IResourceLocator)
  • IResourceLocator instances capture resource name, resource meta-data and also realize resource instances
  • Using MapResourceBase derived attributes, we can capture all earmarked resource locators using the built-in mapping component
  • You can create your custom MapResourceBase derived mapping attributes
  • And using the RemoteResourceLoader class you can download, resolve and avail remote resources at runtime

And in Part II, we'll put the above into practice - which I think will better enlighten the value of RLF, so do check back.

Update: Part II is up.

Introducing Silverlight Console

Posted by Rishi on 29-Dec-09 6:15 AM - Comments (8)

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.

Pseudo Multi-Binding in Silverlight using Relays

Posted by Rishi on 11-Nov-09 2:01 PM - Comments (2)

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.

Web Xcel Demo: View Services in nRoute

Posted by Rishi on 23-Oct-09 5:56 AM - Comments (4)

ViewServices in nRoute are basically UI implemented functionality exposed as services for non-visual consumption - think a Status-Bar as IStatusInfo service. The underlying idea is separation of concerns, so that non-visual components like ViewModels don't have to take dependency on View-based controls or on platform specific contraptions. Now, there is nothing radical about this concept, but with nRoute we get first-class API support to specifically identify, implement and consume "ViewServices" and that's what is discussed in this post.

To demonstrate ViewServices I've put up a small demo called Web Xcel - it replicates the Office Web look and feel for a spreadsheet type application. However, it is no spreadsheet; I've just used the feel of a potentially real application to show how we can integrate and consume ViewServices in an application's flow as it were. Below are some screenshots:

Web Xcel

Web Xcel

You can view the Web Xcel demo app here.

ViewServices - The Basics

Before we get to some examples of ViewServices let me just briefly recap how to define and consume ViewServices - for a proper introduction see the introductory post to nRoute.Toolkit. Firstly, the functionality that a ViewService exposes is encapsulated in a contact i.e. an interface. The defined interface, is then implemented onto a control/object which we earmark with a MapViewService attribute along with some related options. So for example, in Web Xcel demo we have this IConfirmMessageViewService contract that allows us to confirm "something" from the user, the interface definition looks like:

   1: public interface IConfirmMessageViewService
   2: {
   3:     string Title { get; set; }
   4:     string Message { get; set; }
   5:     IDisposable Confirm(Action<bool?> confirmationCallback);
   6: }

This contract basically takes in a title, message and a callback that returns the response from the user - we'll get to the details ahead. However, this contract's implementing class is decorated with the MapViewService attribute as shown below:

   1: [MapViewService(typeof(IConfirmMessageViewService), 
   2:     Lifetime=ViewServiceLifetime.PerInstance)]
   3: public class ConfirmationViewService
   4:     : IConfirmMessageViewService
   5: {
   6:     // implementation 
   7: }

Now, the only notable thing with MapViewService attribute is the Lifetime option which tells nRoute how/when to instantiate/serve a request of the IConfirmMessageViewService - and in this case, it is going to instantiate a new instance per request. You have other lifetime management options namely singleton, weak singleton, discovered instance and self-registered instance. Singleton obviously means a single instance for all requests and the weak singleton option serves a single instance around as long one or more consumers are using it, once it is out of use it's GC'ed. The discovered instance in interesting, as it goes through the VisualTree to find the first implementing instance and returns what it finds. And the self-registered ViewService relies on an implementing control to register an instance of itself when available and unregister when going dark. The important thing to remember with these non per-instance options is the effect on state-management of having potentially multiple concurrent consumers as opposed to each consumer having their own instance.

To resolve a ViewService, we can make use of the ViewServiceLocator helper class that like any IoC component returns an instance. Also in cases where we have more that one implementation of a ViewService we can name each implementation and resolve the same by identifying its name. Now, to use the IConfirmMessageViewService we do something like:

   1: // set up the service
   2: var _showMessageVS = ViewServiceLocator.GetViewService<IConfirmMessageViewService>();
   3: _showMessageVS.Title = MODIFIED_WORKSHEET;
   4: _showMessageVS.Message = CONFIRM_WORKSHEET;
   5:  
   6: // we get the user's response
   7: return _showMessageVS.Confirm(confirmationCallback);

The idea behind the use above is to confirm from the User as to if we save the active worksheet, which has pending changes, before we open or create another worksheet. The visual implementation uses a dialog, as shown below, which confirms for the ViewModel how to proceed. 

Confirmation Child Window

The larger point to ViewServices is that your ViewModel is not concerned about how the visually-implemented functionality is rendered or responded to. It disconnects the implementation from its consumption, so for example you could change or put up a totally new visual implementation, and your ViewModel will be none-the-wiser but more importantly it won't have to be changed.

Web Xcel Demo's ViewServices

I'm not going to go through the full details of the ViewServices in the demo app (you have the code for that), but I'll just describe them and highlight some of the more interesting parts.

IOpenFileViewService

This ViewService is part of the toolkit itself, and as it self-suggests it opens a file dialog that returns a file stream. It is really simple, except the notable instruction is that that its use has to be instantiated directly by a user action such as a key press or a click event. Secondly, this is also very important, we can't open two back-to-back dialogs with a single user-interaction - so we can't save a file and follow it by a open file dialog, this manifests in an interesting solution in the demo app.

ISaveFileViewService

This ViewService does as it reads, and is also pre-packaged in the toolkit. One important distinction I'd like to make with this ViewService is that, it is not an "integrated-visual" in a sense that a Status-Bar is. It, like with other dialogs and ChildWindows, is extraordinary in the sense that it somehow appears from sky as opposed to being part of the VisualTree. This distinction makes a difference in how an instance of the specific ViewService is initialized, instantiated and returned - so a Status-Bar in the VisualTree may need to be registered/discovered whereas a Save File Dialog can be new'ed up.

IConfirmMessageViewService

I've already described this ViewService above, and as duly noted it makes use of a ChildWindow. The interesting part of this ViewService is that it takes in a delegate-based callback and returns an IDisposable. The IDisposable is like a token that be used to dispose the dialog - so in some cases when you want to say draw-down the dialog (from your ViewModel) before the user has addressed it, you can call the dispose method on the token. This pattern is also useful in cases when you want to show information-based dialogs like "Uploading" that users can cancel or when finished it can be disposed via your ViewModel. Again, note this an example of non-integrated visual - it falls from the sky.

IStatusViewService

This ViewService is used to update the current "status" of the application, basically visualized via the Status-Bar (so it's an example of an integrated ViewService). The defining interface to this ViewService is very simple, have a look:

   1: public interface IStatusViewService
   2: {
   3:     IDisposable UpdateStatus(string status);
   4: }

Again like the confirmation ViewService this ViewService returns an IDisposable token that can be used to call-off your status update. So for example, when done saving you can trigger the dispose on the token and the status-bar will revert to its default message. However, if another update has been received post yours, the dispose is auto-magically called for you by the status-bar itself - so in that case the token wouldn't do anything. In this way, it can support multiple updates to the status whilst having only one retractable-update active. As a side-note, you have to be careful about the given implementation in the Demo as it can lead to memory-leaks if you indefinitely hold onto the token - so always dispose them or change the implementation to a weakly-referenced one.

IDocumentInfoViewService 

The Web Xcel is like an example of a Single Document Interface (SDI), and to abet that this ViewService helps with updating the title and 'IsDirty' status of the working document. Obviously the implementation of this is very simple here, but the point made is how a ViewModel that that manages the active worksheet can visually reflect the status in the Shell. Secondly, this ViewService (like the IStatusViewService) is directly implemented in the code-behind of the MainPage.xaml (i.e. the Shell also the RootVisual). I am not sure if the MVVM cops would like this, but to me this a UI detail and it can be implemented in the View itself.

Balloon Notification ITimeoutNotificationViewService

This ViewService is implemented as a notification balloon, as shown in the screenshot. It has two main features, one that it supports a timeout of your notifications - so basically it shows the balloon for the given period of time and then closes it. Secondly, it also supports queuing of notifications - so whilst a single notification is being shown it queues the the others and plays them one-by-one in a first-register-first-shown manner. Now, this ViewService is implemented as a control, which I find to be a reasonable way to component'ize and expose ViewServices .

IInteractiveNotificaitonViewService

This ViewService like it suggests allows for a visual notification with an interactive capability in that if the user "interacts" with it, a callback notifying the same is raised. As far as the consumer (like a ViewModel) is concerned the "interaction" is an implementation detail - which in Demo's case happens to be a click on a header-type panel.

  Header Notification

So above, if the User happens to click on the yellow header bar - it would raise a callback saying the user interacted with the message and so do your thing. On the other hand, if the close button is pressed the callback would return saying that the user did not "interact" so do the other thing. Also, because this ViewService is practically a single-instanced (it self-registers itself) service that potentially serves multiple concurrent-consumers, the notifications are queued in a FIFO manner to ensure User's individual viewership for each and ever notification.

ViewServices - Not There Yet

So in this post and accompanying demo we've covered how ViewServices help us to abstract, expose, and consume visually-implemented functionality. This in my experience is an important and often ignored piece of the MVVM puzzle, which I hope by semantically capturing in a ViewService implementation provides for a better handle. However, there are lots of other aspects to this, especially in relation to View-Composition and that is something that needs more work. For example, how can we get contextual tabs integrated into the ribbon when a User is say editing a cell - obviously, you can do it (with something like Prism regions), but what is needed (or what I want) is to keep the View-composition logic out of the ViewModel/Modules and have a XAML-based way to dynamically integrate/compose bits and pieces of the UI together.

Also, some of the other things I want to provide is a generic modal-dialog strap-up that fuse nicely with ViewModels akin to what Nikhil Kothari showed in his post, but for a broader spectrum of uses such as Wizards. Now, some of the solutions would require the full nRoute which avails the routing engine and view-composition capabilities - obviously because the wheel has already been invented there. Other than that, currently we're not doing dependency injection which is big-problem and I want to address it quickly - there are some tricky problem to it making it play nice.

In many ways, a lot of these things are still fresh from the oven - so going forward I'd like to have more scenarios-covered with better formalization of the View-ViewModel interaction.

View the Web Xcel Demo here.
Download the demo app source-code and the nRoute.Toolkit from Codeplex
(note you require the accompanying nRoute.Toolkit dll)

Icons in the demo app are from the Silk Icon collection by Mark James (Thanks).

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.
 

TRUE: Weak Eventing & Listening for .NET/Silverlight

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

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

The Idea : Wrap'em

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

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

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

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

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

The Implementation

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

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

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

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

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

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

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

The Variants

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

EventHandlers

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

Performance

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

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

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

Listeners

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

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

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

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

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

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

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

There is More

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

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

Download Code (updated for Silverlight use)

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