Architecting UI plug-ins for PRISM applications

It often happens that a particular feature of an application is not used very often, but when you need it you would like it to be accessible easily and without hassle: think calculator in an order entry program. Surely the user can live without it and use the calculator provided with the OS, but what if he could access a simple calculator within a click or two inside the application itself? I could give you more examples like this, but they all fall under the same umbrella of add-ons or plug-ins. Things you surely could live without but having them handy makes the work so much easier.

As it happens I have recently built similar functionality into a PRISM application and the rest of the post describes how to do it in a (hopefully) more less generic fashion.

The plan

I envisioned a plug-in to be  visual “gadget” which the user could access through a window hosting all the plug-ins available in an application in a fashion similar to Visual Studio’s Toolbox. The important thing here is the fact that each plug-in would need to provide it’s own UI: at the end of the day the application cannot up-front provide UI for plug-ins which have not yet been written. Given these requirement I came up with the following plan:

  1. The application’s main window would provide screen estate for displaying all the plug-ins in form of a PRISM’s view region
  2. The plug-ins view region would be filled by a PluginsView containing an ItemsControl which would wrap each individual plug-in into expander
  3. Underlying View Model would simply expose a collection of IPlugin elements which could be bound to the view’s item control

The Plugin

Each of the plug-ins is required to implement IPlugin interface which first of all allows it to be discovered by the PluginHost and secondly forces the plug-in to expose a “View” of sorts which can be displayed to the user. As we’re in the PRISM world here, I would expect the View to be also injected into plug-in, but it is not strictly speaking required. Each plug-in also needs to provide user readable name which will be displayed in the UI.

/// <summary>
/// Common interface for all plugins
/// </summary>
public interface IPlugin
{
    /// <summary>
    /// Gets the name of the plugin.
    /// </summary>
    /// <value>The name.</value>
    string Name { get;  }

    /// <summary>
    /// Gets the UI representation of the plugin.
    /// </summary>
    /// <value>The view.</value>
    object View { get; }
}

All the plug-ins need to be registered with the IoC container and this, in case of PRISM applications is usually done during module initialization. One thing which has to be kept in mind in such case is to give unique “key” (name) to each plug-in during registration as there will be more than one implementation of IPlugin available:

public class PluginsModule : IModule
{
    private readonly IUnityContainer _unityContainer;

    public PluginsModule(IUnityContainer unityContainer)
    {
        _unityContainer = unityContainer;
    }

    public void Initialize()
    {
        _unityContainer.RegisterType<ICalculatorPluginView, CalculatorPluginView>();
        _unityContainer.RegisterType<INewsPluginView, NewsPluginView>();

        _unityContainer.RegisterType<IPlugin, CalculatorPlugin>("Calculator");
        _unityContainer.RegisterType<IPlugin, NewsPlugin>("News");
    }
}

 

The PluginHost

The role of the plug-in host is to simply consume all the implementations of IPlugin available in the application and expose them in a single collection. The simplest way to achieve that is to get them injected into the host by an IoC container. I was toying with the idea of using MEF for this purpose but at the end of the day settled for simplicity  and decided that Unity which is anyway used by PRISM will do the job as well. The following code fragment shows the inner workings of the host. As you can see the constructor gets all the implementations of IPlugin as an array which may seem a bit awkward, but this is what Unity expects out of the box. Having said that it is possible to inject an IEnumerable<IPlugin> which would seem more natural but it requires extra parameter when it comes to registering of the PluginHost with the container.

/// <summary>
/// Hosts all the plugins in the application
/// </summary>
public class PluginHost
{
    private readonly IPluginHostView _view;
    private readonly IPlugin[] _plugins;

    /// <summary>
    /// Initializes a new instance of the <see cref="PluginHost"/> class.
    /// </summary>
    /// <param name="view">The view.</param>
    /// <param name="plugins">The plugins.</param>
    public PluginHost(IPluginHostView view, IPlugin[] plugins)
    {
        _view = view;
        _plugins = plugins;
        _view.DataContext = this;
    }

    public IPluginHostView View
    {
        get { return _view; }
    }

    /// <summary>
    /// Gets the list of all the plugins available.
    /// </summary>
    /// <value>The plugins.</value>
    public IEnumerable<IPlugin> Plugins
    {
        get
        {
            return _plugins;
        }
    }
}

The PluginHostView

The purpose of the view is to show all the available plug-ins, each with his own specific UI. There is nothing magical about it apart from the fact that the item control uses item template which in turn uses plugin-provided UI as a content for the expander. I settled for the expander as I wanted to allow the user to collapse or expand them as and when required.

<Grid>
    <ItemsControl ItemsSource="{Binding Plugins}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Expander Margin="5,5,5,0"
                          Header="{Binding Name}"
                          Content="{Binding View}" />
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Grid>

 

Implementing a plug-in

Now given all the groundwork implementing a plug-in is a doodle. The code is fundamentally no different to any other view/view-model combo as the sample below illustrates:

public class NewsPlugin : IPlugin
{
    private readonly INewsPluginView _view;

    public NewsPlugin(INewsPluginView view)
    {
        _view = view;
        _view.DataContext = this;
    }

    /// <summary>
    /// Gets the name of the plugin.
    /// </summary>
    /// <value>The name.</value>
    public string Name
    {
        get { return "Latest News"; }
    }

    /// <summary>
    /// Gets the UI representation of the plugin.
    /// </summary>
    /// <value>The view.</value>
    public object View
    {
        get { return _view;  }
    }

    /// <summary>
    /// Gets the news.
    /// </summary>
    /// <value>The news.</value>
    public IEnumerable<string> News
    {
        get
        {
            return new[]
                       {
                           "Frogs Invade Pratt's Bottom...",
                           "Developer's bonuses set to triple in 2012",
                           "Read more..."
                       };
        }
    }
}

 

Wrapping it all up

The attached sample application illustrates how all the parts interact together. The full source code can be found here.

image

October 19 2010

Asynchronous WPF Commands

Programming applications for Windows has always been and event-driven affair: we’d place a control on a form, attach an event handler to it and whack some code behind to handle it. Job done. Unfortunately this approach is not very testable and as you’ve probably gathered by now, we’re very much interested in testability around here. There are couple of possible solutions to this problem and one of them (which works particularly well in WPF) is to replace event handlers with commands. This allows the view to be loosely coupled to the underlying “view model” and Darius Collins blogged about this approach using delegate WPF commands. There is also an excellent article by Josh Smith available on MSDN which discusses this pattern (Model-View-ViewModel) in detail.

To cut the long story short, the version of self-updateable DelegateCommand<T> (or RelayCommand<T> as Josh Smith calls it) is now part of the Sharpfellows.Toolkit but as it is being discussed extensively in the posts I have already mentioned I will not repeat myself here. Having said that, I feel I need to mention a minor deficiency of the UpdateableCommand<T> (as we call it): there are sadly some rare cases when the command does not work as expected when it comes to enabling/disabling the associated UI element. This is simply due to the RequerySuggested event is being raised in rather mysterious circumstances when the command manager “thinks” something may require refresh. This may not always work well with your app, so you may need to call CommandManager.InvalidaterequerySuggested() method to force it. Luckily the behaviour is repeatable and easy to spot so you do not have to worry about the app working erratically.

Asynchronous command

As it often happens, in order to keep the UI responsive, some of the commands need to execute the handler on a background thread. This is usually done using BackgroundWorker which provides convenient completion callback executing on the UI thread. There are however two major problems with this approach: first of all the threading code creates unnecessary and repeatable noise, cluttering the view model with “how” rather than letting it focus on the “what”, and secondly the multithreading introduces serious complexity into unit tests of the view model. To solve both of those issues I came up with UpdateableAsyncCommand<T> which, as the name implies, is capable of executing the command asynchronously. The clever bit about it is the fact that instead of directly using the threading API to execute the handler, the async command delegates the task of executing it to an object implementing IThreadingService interface (see below).

   1:  /// <summary>
   2:  /// Provides facilities for background tasks
   3:  /// </summary>
   4:  public interface IThreadingService
   5:  {
   6:      /// <summary>
   7:      /// Queues the execution of a task
   8:      /// </summary>
   9:      /// <param name="work"></param>
  10:      void QueueExecution(Action work);
  11:   
  12:      /// <summary>
  13:      /// Queues the execution of a task and calls back when it is complete
  14:      /// </summary>
  15:      /// <param name="work"></param>
  16:      /// <param name="completionCallback"></param>
  17:      void QueueExecution(Action work, Action completionCallback);
  18:   
  19:      /// <summary>
  20:      /// Queues the execution of a task with callback for successful completion and failure
  21:      /// </summary>
  22:      /// <param name="work"></param>
  23:      /// <param name="completionCallback"></param>
  24:      /// <param name="errorCallback"></param>
  25:      void QueueExecution(Action work, Action completionCallback, Action<Exception> errorCallback);
  26:  }

You may be wondering why on earth would we introduce an abstraction to be put on top of relatively simple threading API, but the reasons become clear when it comes to unit testing. UpdateableAsyncCommand<T> allows us to inject it with an implementation of the IThreadingService which executes the method synchronously. This fake implementation (provided for your convenience in the form of SynchronousThreadingService) allows the unit tests to run synchronously and shifts their focus to the business flow and interaction of components, rather than obscuring the picture with complex synchronisation code. The async command exposes IsBusy property which is set to true whenever the command handler is executing. As the UpdateableAsyncCommand<T> implements INotifyPropertyChanged you can even use the IsBusy property to drive the state of your UI. The following code fragment illustrates the most important aspects of the UpdateableAsyncCommand<T>

   1:  /// <summary>
   2:  /// Implements an asynchronous command
   3:  /// </summary>
   4:  /// <typeparam name="T"></typeparam>
   5:  public class UpdateableAsyncCommand<T> : NotifyPropertyChangedBase, IAsyncCommand
   6:  {
   7:      private readonly IThreadingService _threadingService;
   8:      private readonly Action<T> _executeMethod;
   9:      private readonly Func<T, bool> _canExecuteMethod;
  10:      private readonly Action _completionCallback;
  11:      private readonly Action<Exception> _errorCallback;
  12:      private bool _isBusy;
  13:   
  14:      /// <summary>
  15:      /// Initializes a new instance of the <see cref="UpdateableAsyncCommand&lt;T&gt;"/> class.
  16:      /// </summary>
  17:      /// <param name="threadingService">The threading service </param>
  18:      /// <param name="executeMethod">The execute method.</param>
  19:      /// <param name="canExecuteMethod">The method which determines if the command can be executed.</param>
  20:      /// <param name="completionCallback">The method to be executed when the command handler completes</param>
  21:      /// <param name="errorCallback">The error callback.</param>
  22:      public UpdateableAsyncCommand(IThreadingService threadingService, Action<T> executeMethod, Func<T, bool> canExecuteMethod, Action completionCallback, Action<Exception> errorCallback)
  23:      {
  24:          // Sanity checks omitted...
  25:          _threadingService = threadingService;
  26:          _executeMethod = executeMethod;
  27:          _canExecuteMethod = canExecuteMethod;
  28:          _completionCallback = completionCallback;
  29:          _errorCallback = errorCallback;
  30:      }
  31:   
  32:      /// <summary>
  33:      /// Defines the method that determines whether the command can execute in its current state.
  34:      /// </summary>
  35:      /// <param name="parameter">Data used by the command.  If the command does not require data to be passed, this object can be set to null.</param>
  36:      /// <returns>
  37:      /// true if this command can be executed; otherwise, false.
  38:      /// </returns>
  39:      public bool CanExecute(object parameter)
  40:      {
  41:          return !IsBusy && _canExecuteMethod((T) parameter);
  42:      }
  43:   
  44:      /// <summary>
  45:      /// Occurs when changes occur that affect whether or not the command should execute.
  46:      /// </summary>
  47:      event EventHandler ICommand.CanExecuteChanged
  48:      {
  49:          add { CommandManager.RequerySuggested += value; }
  50:          remove { CommandManager.RequerySuggested -= value; }
  51:      }
  52:   
  53:      /// <summary>
  54:      /// Executes the command with given parameter.
  55:      /// </summary>
  56:      /// <param name="parameter">The parameter.</param>
  57:      public void Execute(object parameter)
  58:      {
  59:          if ( IsBusy )
  60:              throw new InvalidOperationException("Concurrent execution of the command is not supported.");
  61:   
  62:          IsBusy = true;
  63:   
  64:          _threadingService.QueueExecution(() => _executeMethod((T) parameter), CommandFinished, CommandError );
  65:      }
  66:   
  67:      /// <summary>
  68:      /// Gets or sets a value indicating whether this instance is busy.
  69:      /// </summary>
  70:      /// <value><c>true</c> if this instance is busy; otherwise, <c>false</c>.</value>
  71:      public bool IsBusy
  72:      {
  73:          get { return _isBusy; }
  74:          private set
  75:          {
  76:              if (_isBusy == value)
  77:                  return;
  78:   
  79:              _isBusy = value;
  80:              // As the IsBusy may be set from the background thread, we ned to "poke" the 
  81:              // command manager to let it know it may be a good idea to check the command's CanExecute
  82:              CommandManager.InvalidateRequerySuggested();
  83:              OnPropertyChanged(() => IsBusy);
  84:          }
  85:      }
  86:   
  87:      private void CommandFinished()
  88:      {
  89:          _completionCallback();
  90:          IsBusy = false;
  91:      }
  92:   
  93:      private void CommandError(Exception ex)
  94:      {
  95:          _errorCallback(ex);
  96:          IsBusy = false;
  97:      }
  98:  }

 

More on the IThreadingService

The contract for the threading service is quite similar to that of IScheduler (found in reactive extensions) and for a while I was thinking if we should not use it instead. It became clear however that more often than not we need to call back to UI thread when the command handler is finished. This in turn forces use of SynchronisationContext, which is not available when running unit tests on the background thread (as some test runners do). As already mentioned we use SynchronousThreadingService in unit tests which alleviates the need to use SynchronizationContext altogether.

The concept of the IThreadingService has one more benefit: as the service is usually injected by an IoC container, it is very easy to switch from asynchronous to synchronous execution mode simply by replacing the implementation. This may be very helpful when debugging an application when we suspect the issue may be caused a misbehaving thread.

PS: To pay credit where it is due, I feel I need to mention that the threading service code included in the toolkit has been authored by John Rayner. The original idea however came from Dave Hanson who since then patented it and made enough money in royalties to leave his job and embark on a year long journey across Australia :)

Putting it all together

To illustrate the use of asynchronous commands I developed a simple (and rather silly) Web search application called Bingo. The app uses Microsoft’s Bing engine API and the search, as you would expect, is being executed using async command. For what it is, the sample may seem seriously over-engineered but I wanted to illustrate how the async command fits into the big picture of MVVM application.

image

As you can see from the screenshot above, in spite of all the years spent mastering Microsoft technologies, our website still does not deserve #1 spot in the Bing search results for “sharpfellows”… How disappointing ;) 

PS: The sample is obviously available as part of the toolkit.

September 1 2010

Using Delegate Commands with WPF Views (UPDATED)

UPDATED: Scroll to end of post.

Please note:  the examples in this post depend on an implementation of the Presentation Model described in a previous post. 

DelegateCommand<T> is a class that comes with the Composite Application Library (CAL or PRISM), which is the latest incarnation of the Composite application block (CAB).  I have included it in my solution for an application that is based on CAB and have also created a second class DelegateCommand which extends DelegateCommand<T> simply by overriding the constructors and specifying T as object.  This second class allows you to use delegate commands when you don't need to use a command parameter.  I will not go into detail here regarding the implementation of the DelegateCommand<T> class (you can look at the code for yourself – see the attached zip file at the bottom of the post), but will stick to describing how it is used.

Delegate commands can be used instead of WPF Routed commands.  The advantage of a delegate command is that they can be bound to directly on the PresentationModel without the need for a pass through method in the View's code behind.  The command parameters are also type safe, whereas with Routed Commands, parameters are always of type object, and so need to be cast before use.

 Delegate commands are exposed on the Presentation Model as a property.  For example:

OrdersPresentationModel: AddCommand Property

public DelegateCommand<Order> AddCommand { get; set; }

Here we are declaring a DelegateCommand<T>. If the command is to be passed a command parameter, the type of the parameter should be included as the template for the command.  If not, use DelegateCommand instead (no template).

I have chosen to use automatic properties for my commands.  I therefore need to initialise the commands from the OnViewReady method.  (Alternatively, I could have included the initialisation in the getter via a null check). I do this by calling the InitialiseCommands method:

OrdersPresentationModel: InitialiseCommands Method

private void InitialiseCommands()

{

    ...

    AddCommand = new DelegateCommand<Order>(OnAdd, CanAdd);

    ...

}

 My OnAdd() and CanAdd() methods are also declared in the presentation model as follows:

OrdersPresentationModel: OnAdd and CanAdd Methods

private static bool CanAdd(Order order)

{

    return order != null;

}

private void OnAdd(Order order)

{

    if (order == null) return;

    Customer.Orders.AddUnique(Order);

}

So how do we use the command?  As simple as any other property binding:  

OrdersView

<Button Margin="5,0,5,0"

        Height="20"

        Width="70"

        Command="{Binding AddCommand}"

        CommandParameter="{Binding ElementName=ordersComboBox, Path=SelectedItem}">

 

 That's it.  Very simple.  Notice that the OnAdd and CanAdd methods are private.  How can we test them then?  Better than just testing the methods, we can actually call the command from the test.  

OrdersPresentationModelTest

public void AddCommand_AddOrder_OrderAddedToCustomersOrdersCollection()

{

    ....

   _model.AddCommand.Execute(new Order(1));

    ....

    model.AddCommand.CanExecute(new Order(1));

    ....

} 

UPDATE:  Thanks to a tip off from a colleague of mine at EMC, Marcin Kaluza, regarding Josh Smith’s excellent post Allowing CommandManager to query your ICommand objects, I have updated the DelegateCommand class by removing the RaiseCanExecuteChanged and the OnCanExecuteChanged methods and instead implementing add and remove accessors on the CanExecuteChanged event that hook the event up to the CommandManager.RequerySuggested event.  As a result, we no longer need to implement a DispatcherTimer (as suggested below) for each view to periodically poll the CanExecute methods.  I’m sure you’ll agree, this is a much neater solution and has the added bonus of removing the concern of CPU spiking, since we are no longer polling the can execute methods every half second or so, but only when the CommandManager detects conditions that might change the ability of a command to execute.  Thanks Josh!

 There is just one fly in the ointment with this approach.  The CanExecute fires only once when the view is loaded.  This seems like a flaw in the DelegateCommand, since the WPF's Routed Command regularly polls CanExecute methods.  There may now be other implementations of the delegate command that claim to have solved this problem (the Relay Command may be one of them), but I have yet to research them.  In the mean time I have implemented a DispatcherTimer that raises the RaiseCanExecuteChanged() on the delegate command every half second.  This is initialised from the OnViewReady method by calling the InitialiseCanExecuteDispatcherTimer()  method on the PresentationModel.  Ideally this should be pushed down into the DelegateCommand class, but I have yet to look into solving that particular problem.

OrdersPresentationModel: InitialiseCanExecuteDispatcherTimer Method

private void InitialiseCanExecuteDispatcherTimer()

{

    _dispatcherTimer = new DispatcherTimer { Interval = new TimeSpan(0, 0, 0, 0,500) };
    _dispatcherTimer.Tick += (sender, e) => AddCommand.RaiseCanExecuteChanged();
    _dispatcherTimer.Start();

} 

Using the Presentation Model Pattern with WPF Views and CAB/CAL (PRISM)

The Established MVP Pattern
When creating WPF views for an application based on Microsoft Patterns & Practices Composite UI Application Block (CAB), a UI framework for developing applications in Windows Forms that also supports hosting WPF Views, the pattern we adopted for binding controls was to call methods from the OnViewReady method to retrieve or create the bound objects in the presenter and pipe them into the view's code behind via method calls on the views interface.  These methods in the view then set the DataContext of the target control, or indeed of the view itself, to the passed in object.  In some cases, when binding directly to an ItemsControl, the passed in object was a collection, and this was bound to the ItemsSource of the target control.  Here is an example:

Presenter:

public override void OnViewReady()

      {

          base.OnViewReady();

          BindView();

      }

      public void BindView()

      {

          ...

          View.BindCustomers(_customers);

          ...

      }

 

View Code Behind:

public void BindCustomers(ObservableCollection<CustomerBindingObject> customers)

{

    customerslistBox.ItemsSource = customers;

}

The Presentation Model
The Presentation Model is an architectural pattern introduced by Martin Fowler and is the basis of Microsoft’s more specialized MVVM (Model-View-ViewModel) pattern.  It is the favoured approach of the Composite Application Library (CAL or PRISM), the UI framework for developing applications in WPF and Silverlight,  and is employed for separating the responsibilities for the visual display of the user interface and the presentation state and behaviour.  This approach is not so different from the traditional MVP pattern, except in the way it handles data binding.

As before, methods are called from the OnViewReady method to retrieve or create the bound objects in the presenter.  But rather than piping them into the view's code behind for subsequent binding to controls in the view, the bound objects are stored in properties on the presenter.  The presenter itself, or presentation model as it should be called, is then bound directly to the data context of the view.

Now, in the Composite Application Library (CAL or PRISM), the way they implement this, seems a backward step to me.  After storing the binding objects in properties on the Presentation Model, they call a method on the view (as we did in the established MVP pattern above), and pass "this" (the instance of the presentation model) in.  They then set the DataContext of the view to the passed in presentation model, in the called method.


I felt that this unnecessarily cluttered the views code behind and so came up with what I feel is a cleaner approach.  I have created an interface called IBindableView.  This interface implements just one property shown below:

IBindableView Interface:

public interface IBindableView

{

    object DataContext { get; set; }

}

 By inheriting from this interface, the interface for a WPF view will expose the DataContext of that view.  For example:

ICustomersView Interface:

public interface ICustomersView : IBindableView

{

}

 This then allows you to directly set the DataContext from the OnViewReady method in the presenter, without needing to call methods on the view:

CustomersPresentationModel:

public override void OnViewReady()

{

    base.OnViewReady();

    ...

    View.DataContext = this;

    ...

}

You can then bind your controls directly to the properties on your presentation model in XAML.  You can also expose your commands as properties on the presentation model and bind to these directly in XAML.  I shall explain how to do this in another post on Delegate Commands.

November 24 2009
Older Posts