In Silverlight we have two models of .xaml controls, with and without code files. Loading plain xaml files is easy, however when you try and load code-backed xaml using the XamlReader it errors saying "does not support x:Class". Goggling I couldn't find any listed ways out, but I found a way though it - which is by loading it as xml first, then extracting the class name and finally instantiating it. There is the assumption of no arguments in my code, but if you have the type it can be resolved and in cases where you don't know if it is xClass based you can open the file with the xml reader check for that specifically. This might be a bit hacky but it works, have a look..

const string RESOURCE_PATH = "/{0};component/{1}";   // the format is ==> /AssemblyName;component/ResourceFilePathName

public UIElement LoadXaml(string assemblyFullyQualifiedName, string xamlPathFileName, bool xClassType)
{

    // and we try and load thew resource
    var _uri = new Uri(
        string.Format(RESOURCE_PATH, GetAssemblyName(assemblyFullyQualifiedName), xamlPathFileName), UriKind.Relative);
    var _streamResourceInfo = Application.GetResourceStream(_uri);

    using (var _stream = _streamResourceInfo.Stream)
    {

        return (xClassType ? XamlXClassLoader(_stream, assemblyFullyQualifiedName) : XamlLoader(_stream)) as UIElement;

    }

}

Object XamlLoader(Stream stream)
{
    using (var _reader = new StreamReader(stream))
    {
        return XamlReader.Load(_reader.ReadToEnd());
    }
}
    
Object XamlXClassLoader(Stream stream, string assemblyName)
{

    // we load the content as xml
    using (var _xmlReader = XmlReader.Create(stream))
    {
        // the control should be the root element
        if (_xmlReader.Read())
        {

            // we get the x:Class attribute's value
            var _classTypeName = _xmlReader.GetAttribute("Class", "http://schemas.microsoft.com/winfx/2006/xaml");

            // assembly name is required, else we take the assumption it is the application's assembly
            var _assemblyName = !string.IsNullOrEmpty(assemblyName)
                ? assemblyName : Application.Current.GetType().Assembly.FullName;

            // we load the class type defined in the x:Class attribute
            var _type = Type.GetType(_classTypeName + "," + _assemblyName, false, true);

            // we load the type
            if (_type != null)
            {
                var _xamlControl = Activator.CreateInstance(_type);     // note, the assumption of no args

                // and we return
                return _xamlControl;
            }

        }
    }

    // else
    return null;

}

string GetAssemblyName(string assemblyFullyQualifiedName)
{
    return assemblyFullyQualifiedName.Substring(0, assemblyFullyQualifiedName.IndexOf(','));
}

This surely applies to SL2, maybe in SL3 their might be a way to get xaml controls directly, as they have baked in a navigation framework that seemingly instantiates existing xaml controls via it's relative file path - have to check though.

Posted by Rishi on 22-Mar-09 9:32 AM, 25 Comments

Categories: Silverlight, Code

Here's a little look at my little program "shown off" at Mix 09.


Please view this in full screen mode (by double clicking the video), because of the small text and high-res recording.

So here is a little background on the "Couch Guide"; well I had been off programming for a long long time, having return early this year I wanted to test my mantle with WPF and C# (I used to be a VB guy). In hand I had a practical problem, which was that the cable I have at home has a lot of good channels, but I used to just keep missing what I wanted to see time and again.

Now, the problem was with one our, cable provider doesn't have EPG, their are lot of channels to keep track off, and and obviously partly me forgetting. Plus, in some cases even though the content is in English, the introductions and timing information were in other languages - like we have a fabulous channels bouquet from Turkey (DigiTurk) that uses Turkish for it's non-content info but unfortunately I can't get the head or tail what they are saying. Further, if you look hard all the channels info is online, but to keep tabs of 40-50 websites for schedules is crazy if not impractical. Anyway so having decided this is an "information problem", paved the way for Couch Guide as an aggregator of schedules.

CouchGuide1 This a great channel from Turkey, but see the movie "Poor Boys Game" becomes "Hayatla Mac" in Turkish.. at least the album art helps..

After a couple of day I got it working but the thing was very inelastic for a lack of a better word, so I created a provider model to dynamically look for the providers and hook in the channels. And slowly by slowly refactored the thing to a clean, mean model. And it is quite alright, I have written 5 providers than give me 630 channels from all over the world. Some providers are just 100 lines, using a base class. The main thing is to parse into the required model, the rest is taken care of for you.

CouchGuide3   You can bookmark your favourite channels, and for those channels it keeps seven days of schedules ahead of time.

Now I want to open the provider model and the code for everyone, but as of now I think the model needs a bit of work. There are a lot of bits and pieces that come with schedules' information (which I never knew or considered), and I want to encapsulate it properly so that we don't have to tinker it time and again. Also, I am integrating it with twitter, facebook, and other social media so that we can have a rich consumption of a somewhat pretty generic data. Look forward to reading twitters from your friends how cool 24 was this week or not.

CouchGuide2
Here you can get an overview of your favourite channels schedules for a given day; also hit the play button and the needle tracks what's playing now through the day, radio style - pretty old school..

Also, I've tried to give the program a visual flair, and as you can see Aero Glass works wonders (be sure to click on the pictures). What I love is that the glass see through effect gives the program a non-static texture and tonal quality - which to me is very engaging and visually refreshing. Anyone with Windows 7 will enjoy this even more with the rotating backgrounds, the tinted-glass, and personalization themes. 

Hope you guys like it, and I'll try to have it out asap.

Posted by Rishi on 19-Mar-09 2:53 PM, 13 Comments

Categories: Cool, Personal

The la MVC routing framework I showed last week, well I have decided to call it "nRoute" (pronounced enroute). With "n" being ambiguous for either any or .net, which by some coincidence carries the suggestion to route anything or routing for .net ;)

So now that it has a name badge, let see what's under the hood:

  1. Routing Services

    The routing service is almost a direct port of the asp.net MVC routing engine. However, in this case it is relatively more generic and has a more forthright request-reply semantics. Also, we only do play with relative URLs here, that said you normally wouldn't have to interface with this directly. This falls under the Routing namespace.

  2. Navigation Services

    This builds directly atop the routing services, but offers its own set of APIs to handle navigation functionality. The interesting thing (and what I wacked my brain around a lot for) is that you can navigate against a handler (as in saying you want this thing to handle the navigation for this URL) or directly consume the navigation reply. That flexibility befits a lot of edge-cases scenarios, yet is very simple. This falls under the Navigation namespace.

  3. Navigation Containers

    I like to think navigation containers represent models for consuming navigation in different ways. They ultimately manifest as UI controls, but what they represent is different ways to navigate like a browsing with back-forward capabilities or vanilla navigating without any trace. In WPF you have something similar, but it is inherently very opaque and inflexible in this case it is relatively simple to cook up a custom container. However, you can do without them entirely. They fall under the Navigation.Containers namespace.

  4. Application-Level Integration

    One of the most wanted features in RIA apps is deep-linking, and that requires hooking with (at the application-level) a navigation container to handle URL requests. For that purpose, I want to provide a specialized Application class with accompanying navigation events, and maybe a Visual Studio template to shrink-wrap it. Also, I have modelled an asp.net like Site Map API, again for application level consumption. This is work in progress. 

  5. RoutingCommand Services

    The idea is to use URLs as signifiers of commands, kinda like the commanding pattern in WPF. I am still working on the details but I think it might useful in application-wide commanding scenarios, especially since it is loose-coupling through URLs, and like elsewhere we can also pass-in name-value parameters. Further, I am looking to support event type multi-casting, but it is still entirely on the drawing board.

  6. Re-routing Services

    The idea here to have some kind of built-in re-routing capabilities that allows you to change the URL without breaking existing links and the apps. This is just a future-proofing initiative, as it might be useful in cases where you have many independent / modular components and links need to be changed. Also work in progress.

That's a 10,000 ft overview; I hope you enjoyed the flight and the pilot informs me the code will be landing soon on Codeplex (too cheesy?)

Anyway, I am well aware that possibly by next week this could all be an elaborate road-kill courtesy Silverlight 3, but I am holding the fort till then. In any case, SL 3 will definitely have an application-level navigation framework, but my understanding is that it will be more akin to asp.net type mapping with real folder/file-path mapped one-on-one with relative URLs. Thus, the contrast it might have with nRoute will be in the same order that MVC routing has to asp.net file mapping; lets see how it figures.

One other thing is even though nRoute offers a somewhat different paradigm for application flow, it doesn't pre-empt the use for frameworks like Prism or Caliburn. In fact I would rather this be used in hand with the mentioned frameworks.

Posted by Rishi on 15-Mar-09 12:48 PM, 13 Comments

Categories: Architecture, Silverlight

(Real World + Semantic Knowledge + Internet) * Cool Technology = Awesomeness, have a look..

I love these broad concepts of the semantic knowledge, communal knowledge, user-empowerment all mixed with the web and real-world using "human-oriented" technologies.. It's the future, and we are already on that road with things like twitter (chatter), touch, wikis, semantic-web, xml, google etc. What is also interesting and relevant is how we are gonna bridge the gap between structured and un-structured information. It is all so fascinating stuff, but for now let me unceremoniously put it under the "cool" tag..

Posted by Rishi on 15-Mar-09 1:37 AM, 20 Comments

Tags: ,
Categories: Technology, Cool

In a lot of things that MVC brought (besides reminding me how much I hate classic asp) what I loved the most was the routing engine. The routing feature was beautiful because it provided for loose-coupling, whilst being structured and rich enough to be actionable. Given that, and for structural and development modularity purposes I adopted the .NET 3.5sp1 routing engine for an URL based-navigation framework for Silverlight.

Basically it works pretty much like MVC/asp.net routing, you set up the routes to yields UI Objects. In this case we pass in a relative url (like "Customer/EditOrder/39/") along with an optional name-value collection (a dictionary basically) as request parameters. You can think of the request parameters as QueryString's collection or Form's input-value collection. What you get out from the routing engine is a "NavigationResponse" type, that contains a UI Page (basically a FrameworkElement) and another name-value collection. The name-value collection in the response is a merged collection of the request name-values, plus what it parsed from the URL and any defaults name-values you had set up with the route.

The other thing I've tried is to marry navigation with the routing, particularly because Silverlight controls aren't inherently statefull as pertinent to navigation - think html pages, like when browsing a web-form and you click back, the page is rendered in a state you left it in, with some exceptions to the rule.  How we achieve this "statefulness" is with the following interfaces.

PageState

Mostly we just use the IPageNavigator interface that brings together the two base interfaces, along with a title property. Hopefully it should be self-descriptive, but IPageInitializer interface is called to initialize a page pre-displaying it. The InitializePage method takes in a name-value collection, which as you can guess comes from the routing engine's response. The IPageState interface is used to extract and inject state into a page, so when we browse forward or back the UI get's a name-value collection to help it restore it's state. It's kind of like the viewstate in concept, but you have to put the relevant state in and out yourself as the controls themselves don't collude in state management. Also one of the thing we want with M-V-VM pattern, is to manage the state in the ViewModel - these interface helps with that by separating the state management. Additionally, the routing engine is geared to take this into consideration, so in the code to plug in routes we register a route handler with the following constructor.

public NavigationRouteHandler(
	Func<ParametersDictionary, FrameworkElement> pageResolver,
	Func<FrameworkElement, IPageNavigator> navigatorResolver) 
{ 
	... 
}

Basically, it takes in two handlers, one to get a FrameworkElement for displaying in the UI and the other to get the page navigator (IPageNavigator) out for helping with the navigation.  This separation of the FrameworkElement and IPageNavigation is in recognition of the ViewModel, but it doesn't force you - so, if you don't need a IPageNavigator or don't implement the interface just pass in null. Or if your page itself implements the IPageNavigator, then return the page. All the three scenarios are shown below, which also shows how to register routes, defaults and constrains:

void SetupRoutes()
{
	// we can pass in default values in routes
    var _defaults = new ParametersDictionary();
    _defaults.Add("OrderId", -1);

	// we can also pass in constraints 
    var _constraints = new ParametersDictionary();
    _constraints.Add("OrderId", "\\w{2}");

	// here we register a route with no IPageNavigator
    RouteTable.Routes.Add("Sample1", 
		new Route("Customer/NewOrder", null,
        new NavigationRouteHandler(p => new DummyControl1(), null)));

	// here we register a route, with the page itself implementing 
	// the IPageNavigator and it also has default values passed in
    RouteTable.Routes.Add("Sample2", 
		new Route("Customer/EditOrder/{OrderId}/", _defaults,
        new NavigationRouteHandler(
			p => new DummyControl2(), u => (IPageNavigator)u)));

	// here we register a route with the page's ViewModel implementing the 
	// IPageNavigator via the DataContext and we also have constraints set
    RouteTable.Routes.Add("Sample3", 
		new Route("Customer/DeleteOrder/{OrderId}/", null, _constraints,
        new NavigationRouteHandler(
			p => new DummyControl3(), u => (IPageNavigator)(u.DataContext))));

}

This is very similar to asp.net or MVC routing, the difference being we have a custom route handler for Silverlight / WPF that implements the IRouteHandler. And if you don't like it or your setup is hooked up differently, just create your own IRouteHandler implementation and you are good to go. Essentially it has the same extensibility semantics that MVC has, and the workflow is geared towards a request-response type of setup. I hope you did notice the {OrderId} parameters in the route URL, they are parsed and included in the response's name-value collection. One omission for Silverlight is that we can't pass in anonymous types to set up constraints or default values because we can't reflect on them outside the declaring assembly.

Like I said earlier I have tried to marry routing and navigation, and so we have something called navigation containers. The containers are simply interfaces that imply a navigation model, and I have two of them build-in - one is a simple navigation container which you pass in a URL and it just returns the UI but doesn't store any history or anything. Another one is called BrowsingContainer that stores history, caches the state, and can browse forward or back. Just like everything else you can create you own containers to implement say roles-based validation on URls or extend them for deep-linking within the browser.

NavigationContainers

A benefit with these interfaces is that you can expose them through a dependency injection container, and thus loosely couple the "pages" within the app. Another important point to remember is that you route against or rather navigate in a container even though the routes are registered statically/globally - this means we can have two or more navigation containers controls (think WPF BrowserControl) and each will work with all the routes registered. I also use these interfaces as ViewModels for navigation container controls, so you can easily create your own custom skins with all the glitter and jazz you want - I just sampled one with the Silverlight.FX transitions. It's quite easy.

There is a lot more to say, but for now lets keep it for the future - however I am working on integrating this with Prism 2 and creating an asp.net like site map control. In the sample below do notice that the pages keep their state during back/forward navigation and their memory consumption is constrained to the loaded page (plus the saved states).  I'll put up the code later on CodePlex, it needs some scrubbing, Cheers.

Get Microsoft Silverlight

PS: I wanted to mention and thank this excellent series on MVC routing.

Posted by Rishi on 10-Mar-09 5:39 AM, 18 Comments

Update: The ICommand implementation in this post was designed for Silverlight 2, for Silverlight 3 I've put out some new ideas in library called nRoute.Toolkit (download at Codeplex). Related to ICommand the toolkit contains:

- Two ICommand implementations including both generic and parameter-less versions
- ICommand extensions that allow you explicitly define execution-state dependencies (i.e. for CanExecute)
- A Blend based behaviour to use ICommands, that is both bindable to your ViewModel and can manage the state of the control it is applied to

Read full details about the above in my Introducing nRoute.Toolkit (Part 2) post.

The M-V-VM pattern (click here for M-V-VM intro) is perhaps the flavour of the season, it seems to be getting a lot of attention in the SL/WPF community. And rightfully so, because it goes very well with WPF/SL's databinding and data template feature sets. However, in Silverlight ICommand is there in name only, it's not inherently supported by the core-controls (which is a royal pain), but there are a number of reasonable workarounds till Silverlight 3 I suppose.

Anyway, just as a lot of developers I too created a non-event-routing based ICommand implementation for M-V-VM (specifically for SL but can equally be used for WPF). My implementation adds couple of things, let me enumerate:

  • It adds a CommandParameter Property; what this allows is to implicitly bind any UI based property to the parameter that is passed into ICommand's execution. So basically if you pass in a null in ICommand's Execute method it would substitute it with the CommandParameter's value.
  • Also, I've added an IsEnabled property, which is used to logically disable the command, as it "ands" the CanExecute result. I find this really useful, like say we are already executing a search and we don't want to get any more commands in, just say IsEnabled = false. This ties into the UI too, because changing it's value raises the CanExecuteChanged event.
  • Thirdly, the command class implements the INotifyPropertyChanged property, which goes with the two properties I've mentioned above. And like I said, when you disable the command or when the CommadParameter Property's value changes, it triggers the CanExecuteChanged event, that in turn ties into the UI.
  • I've also added a read-only bool property called IsExecutable, this again is mainly to bind to the UI as SL doesn't listen to the changes in CanExecuteChanged. So whenever CanExecuteChanged is raised we also raise IsExecutable's PropertyChanged event. This way you can say bind a button's IsEnabled Property to the IsExecutable Property, and it will automatically enable/disable the button. Notably, you can bind this to multiple UI element's, you are not limited to one UI element.
  • And because we get the value of the parameter for ICommand using the binding on CommandParameter Property we can just call Execute() or CanExecute() without passing in a parameter.

I am note sure if I got the benefits across, but essentially what this design helps is to better control the state of the command and it's consumption by the UI - particularly in Silverlight. Rather than having to expose two/three more properties, we can just use the command's properties notably with INotifyPropertyChanged Interface.

<TextBox Text="{Binding SearchCommand.CommandParameter, Mode=TwoWay}" />
<Button Content="Search" cal:Click.Command="{Binding SearchCommand}"
	IsEnabled="{Binding SearchCommand.IsExecutable, Mode=OneWay}" />

In the xaml above we bind the textbox's text property to the command's parameter value, and button is tied to the command. Also, I am using the Prism 2's attached properties for the click event consumption, you don't need one in WPF. And below is how you set up the command in the ViewModel.

_searchCommand = new ParameterCommand<string>(
    v => Search(v), v => !string.IsNullOrEmpty(v), string.Empty, true
);

public ParameterCommand<string> SearchCommand 
{
	get { return _searchCommand; }
}

void Search(string value)
{
    _searchCommand.IsEnabled = false;
    // do search.. 
    // show results 
    _searchCommand.IsEnabled = true;
}

For initializing the ICommand, I am passing in an execute handler, a canExecute lambda handler that checks the string is not empty, a empty string for the default value of the CommadParameter and true as in by default the command is enabled. When doing the search you disable the command and enable it back when done, and the UI part is handled with hook-ups shown earlier.

ParameterCommand

As for the structure, I have two base classes that are helpful when you don't wanna use the CommadParameter Property. The ActionCommand is mainly useful when you don't use a parameter, just an action like save or close. The delegate command is pretty much like Prism's but with IsEnabled rather than IsActive, however IsEnabled is tied in with INotifyPropertyChanged so it helps with UI consumption.  And the read-only IsExecutable Property checks both with the CanExecute method and IsEnabled property, and is also tied in with INotifyPropertyChanged.

Hope this helps, I'll have a running sample up soon, the complete code is below.

using System;
using System.Windows.Input;
using System.ComponentModel;

namespace Orkpad.Samples
{
    public class ActionCommand<T> : ICommand, INotifyPropertyChanged
    {

        protected const string ERROR_CANNOT_EXEC = "Cannot execute command {0}, invalid execution state or parameter.";
        protected const string ERROR_EXPECTED_TYPE = "Expected parameter for command ({0}) must be of {1} type.";

        Action<T> _executeHandler;
        bool _isEnabled;                 

        public ActionCommand(Action<T> executeHandler) : this(executeHandler, true) { }

        public ActionCommand(Action<T> executeHandler, bool isEnabled)
        {
            // basic check
            if (executeHandler == null) throw new ArgumentNullException("executeHandler");

            // we save
            _executeHandler = executeHandler;
            _isEnabled = isEnabled;

            // we also add an event handler which allows, anything binding to IsExecutable 
            //this.CanExecuteChanged += (s, e) => RaisePropertyChanged("IsExecutable");
        }

#region Additions

        //public virtual bool IsExecutable
        //{
        //    get
        //    {
        //        return IsEnabled;
        //    }
        //}

        public bool IsEnabled
        {
            get
            {
                return _isEnabled;
            }
            set
            {
                if (_isEnabled != value)
                {
                    _isEnabled = value;
                    RaiseCanExecuteChanged();
                    RaisePropertyChanged("IsEnabled");
                }
            }
        }

        public bool CanExecute(T parameter)
        {
            return OnCanExecute(parameter);
        }

        public void Execute(T parameter)
        {
            OnExecuteCommand(parameter);
        }

        public void RaiseCanExecuteChanged()
        {
            if (CanExecuteChanged != null) CanExecuteChanged(this, new EventArgs());
        }

#endregion

#region ICommand Members

        public event EventHandler CanExecuteChanged;

        public bool CanExecute(object parameter)
        {
            // basic checks
            CheckParameterType(parameter);

            return OnCanExecute((T)parameter);
        }

        public virtual void Execute(object parameter)
        {

            // basic checks
            CheckParameterType(parameter);

            OnExecuteCommand((T)parameter);
        }

#endregion

#region INotifyPropertyChanged Related

        public event PropertyChangedEventHandler PropertyChanged;

        protected void RaisePropertyChanged(string propertyName)
        {
            // basic check
            if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

#endregion

#region Internal

        protected virtual bool OnCanExecute(T value)
        {
            return IsEnabled; 
        }

        protected virtual void OnExecuteCommand(T parameter)
        {

			// I've changed this to not throw an exception, as failure to execute should fail gracefully
            if (!OnCanExecute(parameter)) return;
            //    throw new InvalidOperationException(string.Format(ERROR_CANNOT_EXEC, this.GetType().FullName));

            // we execute
           _executeHandler(parameter);

        }

        protected void CheckParameterType(Object parameter)
        {
            if (parameter == null) return;
            if (! typeof(T).IsAssignableFrom(parameter.GetType())) 
                throw new ArgumentException(string.Format(ERROR_EXPECTED_TYPE, this.GetType().FullName, typeof(T).FullName));
        }

#endregion

    }

    public class DelegateCommand<T> : ActionCommand<T>
    {

        Func<T, bool> _canExecuteHandler;

        public DelegateCommand(Action<T> executeHandler) : this(executeHandler, null, true) { }

        public DelegateCommand(Action<T> executeHandler, Func<T, bool> canExecuteHandler)
            : this(executeHandler, canExecuteHandler, true) { }

        public DelegateCommand(Action<T> executeHandler, Func<T, bool> canExecuteHandler, bool isEnabled)
            : base(executeHandler, isEnabled)
        {
            _canExecuteHandler = canExecuteHandler;
        }

        #region Helpers

        protected override bool OnCanExecute(T value)
        {

            // basic check
            CheckParameterType(value);

            // we execute, note the base checks 
            return (_canExecuteHandler != null) ? (base.OnCanExecute(value) && _canExecuteHandler(value)) : base.OnCanExecute(value);

        }

        #endregion

    }

     public class ParameterCommand<T> : DelegateCommand<T>
    {

#region Cosntants & Variables

        T _commandParameter;

#endregion

#region Constructors

        public ParameterCommand(Action<T> executeHandler) : this(executeHandler, null, default(T), true) { }

        public ParameterCommand(Action<T> executeHandler, T commandParameterDefaultValue) 
            : this(executeHandler, null, commandParameterDefaultValue, true) { }

        public ParameterCommand(Action<T> executeHandler, bool isEnabled)
            : this(executeHandler, null, default(T), isEnabled) { }

        public ParameterCommand(Action<T> executeHandler, Func<T, bool> canExecuteHandler)
            : this(executeHandler, canExecuteHandler, default(T), true) { }

        public ParameterCommand(Action<T> executeHandler, Func<T, bool> canExecuteHandler, bool isEnabled)
            : this(executeHandler, canExecuteHandler, default(T), isEnabled) { }

        public ParameterCommand(Action<T> executeHandler, Func<T, bool> canExecuteHandler, 
            T commandParameterDefaultValue, bool isEnabled) : base(executeHandler, canExecuteHandler, isEnabled)
        {

            // we save
            _commandParameter = commandParameterDefaultValue;

            // we also add an event handler which allows, anything binding to IsExecutable 
            this.CanExecuteChanged += (s, e) => RaisePropertyChanged("IsExecutable");

        }

#endregion

#region Additions

        public bool IsExecutable
        {
            get
            {
                // we check this here, because we can validate against the command parameter
                return this.CanExecute();
            }
        }

        public T CommandParameter
        {
            get
            {
                return _commandParameter;
            }
            set
            {
                if (!Object.Equals(_commandParameter, value))
                {
                    _commandParameter = value;
                    RaisePropertyChanged("CommandParameter");
                    RaiseCanExecuteChanged();
                }
            }
        }

        public bool CanExecute()
        {
            return OnCanExecute(this.CommandParameter);
        }

        public void Execute()
        {
            this.Execute(this.CommandParameter);
        }

#endregion

#region Helpers

        protected override void OnExecuteCommand(T parameter)
        {

            // we subsitute the 
            T _value = parameter != null ? parameter : this.CommandParameter;
            
            // we execute
            base.OnExecuteCommand(_value);

        }

#endregion

    }

}

UPDATE: I've got revised versions of all the three classes in nRoute, please visit http://nRoute.codeplex.com for the latest release and check out the demo app for examples on how to use these ICommand implementations.

One of the many things missing from the Silverlight API is a ReaderWriterLock implementation, though it is not a day-to-day requisite yet sometimes you really need it. The good news is, the underpinnings for it's implementation are all their, basically carried in-tact from the desktop counterpart.

I found a very good implementation by Vance Morrison, which I understand forms the basis of the ReaderWriterLockSlim in .NET 3.5 using spin locks.  Below is the Sliverlight version of the same, with some minute changes:

/// <summary>
/// A reader-writer lock implementation that is intended to be simple, yet very
/// efficient.  In particular only 1 interlocked operation is taken for any lock 
/// operation (we use spin locks to achieve this).  The spin lock is never held
/// for more than a few instructions (in particular, we never call event APIs
/// or in fact any non-trivial API while holding the spin lock).   
/// 
/// Currently this ReaderWriterLock does not support recurision, however it is 
/// not hard to add 
/// </summary>
/// <remarks>
/// By Vance Morrison
/// Taken from - http://blogs.msdn.com/vancem/archive/2006/03/28/563180.aspx
/// Code at - http://blogs.msdn.com/vancem/attachment/563180.ashx
/// </remarks>
public class ReaderWriterLock
{
    // Lock specifiation for myLock:  This lock protects exactly the local fields associted
    // instance of MyReaderWriterLock.  It does NOT protect the memory associted with the
    // the events that hang off this lock (eg writeEvent, readEvent upgradeEvent).
    int myLock;

    // Who owns the lock owners > 0 => readers
    // owners = -1 means there is one writer.  Owners must be >= -1.  
    int owners;

    // These variables allow use to avoid Setting events (which is expensive) if we don't have to. 
    uint numWriteWaiters;        // maximum number of threads that can be doing a WaitOne on the writeEvent 
    uint numReadWaiters;         // maximum number of threads that can be doing a WaitOne on the readEvent
    uint numUpgradeWaiters;      // maximum number of threads that can be doing a WaitOne on the upgradeEvent (at most 1). 

    // conditions we wait on. 
    EventWaitHandle writeEvent;    // threads waiting to aquire a write lock go here.
    EventWaitHandle readEvent;     // threads waiting to aquire a read lock go here (will be released in bulk)
    EventWaitHandle upgradeEvent;  // thread waiting to upgrade a read lock to a write lock go here (at most one)

    public ReaderWriterLock()
    {
        // All state can start out zeroed. 
    }

    public void AcquireReaderLock(int millisecondsTimeout)
    {
        EnterMyLock();
        for (; ; )
        {
            // We can enter a read lock if there are only read-locks have been given out
            // and a writer is not trying to get in.  
            if (owners >= 0 && numWriteWaiters == 0)
            {
                // Good case, there is no contention, we are basically done
                owners++;       // Indicate we have another reader
                break;
            }

            // Drat, we need to wait.  Mark that we have waiters and wait.  
            if (readEvent == null)      // Create the needed event 
            {
                LazyCreateEvent(ref readEvent, false);
                continue;   // since we left the lock, start over. 
            }

            WaitOnEvent(readEvent, ref numReadWaiters, millisecondsTimeout);
        }
        ExitMyLock();
    }

    public void AcquireWriterLock(int millisecondsTimeout)
    {
        EnterMyLock();
        for (; ; )
        {
            if (owners == 0)
            {
                // Good case, there is no contention, we are basically done
                owners = -1;    // indicate we have a writer.
                break;
            }

            // Drat, we need to wait.  Mark that we have waiters and wait.
            if (writeEvent == null)     // create the needed event.
            {
                LazyCreateEvent(ref writeEvent, true);
                continue;   // since we left the lock, start over. 
            }

            WaitOnEvent(writeEvent, ref numWriteWaiters, millisecondsTimeout);
        }
        ExitMyLock();
    }

    public void UpgradeToWriterLock(int millisecondsTimeout)
    {
        EnterMyLock();
        for (; ; )
        {
            Debug.Assert(owners > 0, "Upgrading when no reader lock held");
            if (owners == 1)
            {
                // Good case, there is no contention, we are basically done
                owners = -1;    // inidicate we have a writer. 
                break;
            }

            // Drat, we need to wait.  Mark that we have waiters and wait. 
            if (upgradeEvent == null)   // Create the needed event
            {
                LazyCreateEvent(ref upgradeEvent, false);
                continue;   // since we left the lock, start over. 
            }

            if (numUpgradeWaiters > 0)
            {
                ExitMyLock();
                throw new InvalidOperationException("UpgradeToWriterLock already in process.  Deadlock!");
            }

            WaitOnEvent(upgradeEvent, ref numUpgradeWaiters, millisecondsTimeout);
        }
        ExitMyLock();
    }

    public void ReleaseReaderLock()
    {
        EnterMyLock();
        Debug.Assert(owners > 0, "ReleasingReaderLock: releasing lock and no read lock taken");
        --owners;
        ExitAndWakeUpAppropriateWaiters();
    }

    public void ReleaseWriterLock()
    {
        EnterMyLock();
        Debug.Assert(owners == -1, "Calling ReleaseWriterLock when no write lock is held");
        Debug.Assert(numUpgradeWaiters > 0);
        owners++;
        ExitAndWakeUpAppropriateWaiters();
    }

    public void DowngradeToReaderLock()
    {
        EnterMyLock();
        Debug.Assert(owners == -1, "Downgrading when no writer lock held");
        owners = 1;
        ExitAndWakeUpAppropriateWaiters();
    }

    /// <summary>
    /// A routine for lazily creating a event outside the lock (so if errors
    /// happen they are outside the lock and that we don't do much work
    /// while holding a spin lock).  If all goes well, reenter the lock and
    /// set 'waitEvent' 
    /// </summary>
    private void LazyCreateEvent(ref EventWaitHandle waitEvent, bool makeAutoResetEvent)
    {
        Debug.Assert(MyLockHeld);
        Debug.Assert(waitEvent == null);

        ExitMyLock();
        EventWaitHandle newEvent;
        if (makeAutoResetEvent)
            newEvent = new AutoResetEvent(false);
        else
            newEvent = new ManualResetEvent(false);
        EnterMyLock();
        if (waitEvent == null)          // maybe someone snuck in. 
            waitEvent = newEvent;
    }

    /// <summary>
    /// Waits on 'waitEvent' with a timeout of 'millisceondsTimeout.  
    /// Before the wait 'numWaiters' is incremented and is restored before leaving this routine.
    /// </summary>
    private void WaitOnEvent(EventWaitHandle waitEvent, ref uint numWaiters, int millisecondsTimeout)
    {
        Debug.Assert(MyLockHeld);

        waitEvent.Reset();
        numWaiters++;

        bool waitSuccessful = false;
        ExitMyLock();      // Do the wait outside of any lock 
        try
        {
            if (!waitEvent.WaitOne(millisecondsTimeout))
                throw new InvalidOperationException("ReaderWriterLock timeout expired");
            waitSuccessful = true;
        }
        finally
        {
            EnterMyLock();
            --numWaiters;
            if (!waitSuccessful)        // We are going to throw for some reason.  Exit myLock. 
                ExitMyLock();
        }
    }

    /// <summary>
    /// Determines the appropriate events to set, leaves the locks, and sets the events. 
    /// </summary>
    private void ExitAndWakeUpAppropriateWaiters()
    {
        Debug.Assert(MyLockHeld);

        if (owners == 0 && numWriteWaiters > 0)
        {
            ExitMyLock();      // Exit before signaling to improve efficiency (wakee will need the lock)
            writeEvent.Set();   // release one writer. 
        }
        else if (owners == 1 && numUpgradeWaiters != 0)
        {
            ExitMyLock();          // Exit before signaling to improve efficiency (wakee will need the lock)
            upgradeEvent.Set();     // release all upgraders (however there can be at most one). 
            // two threads upgrading is a guarenteed deadlock, so we throw in that case. 
        }
        else if (owners >= 0 && numReadWaiters != 0)
        {
            ExitMyLock();    // Exit before signaling to improve efficiency (wakee will need the lock)
            readEvent.Set();  // release all readers. 
        }
        else
            ExitMyLock();
    }

    private void EnterMyLock()
    {
        if (Interlocked.CompareExchange(ref myLock, 1, 0) != 0)
            EnterMyLockSpin();
    }

    private void EnterMyLockSpin()
    {
        for (int i = 0; ; i++)
        {
            if (i < 3 && Environment.ProcessorCount > 1)
                Thread.SpinWait(20);    // Wait a few dozen instructions to let another processor release lock. 
            else
                Thread.Sleep(0);        // Give up my quantum.  

            if (Interlocked.CompareExchange(ref myLock, 1, 0) == 0)
                return;
        }
    }
    private void ExitMyLock()
    {
        Debug.Assert(myLock != 0, "Exiting spin lock that is not held");
        myLock = 0;
    }

    private bool MyLockHeld { get { return myLock != 0; } }

}

This implementation features both timeouts and upgrading to writer locks, however it does not support recursion or try enter lock usage. Also, it's relatively fast, in some basic testings I did it ran 3x-4x v/s Monitor Locks, which compares well to other less feature-rich implementations (see here) that run 8x-10x v/s the generic Monitor Locks.  And just as a resource, you can read more about locks in general from this entry by Jeff Moser on his blog.

Posted by Rishi on 08-Mar-09 5:20 AM, 20 Comments

Categories: Code, Silverlight