Silverlight Unit Testing NuGet package

Posted on Jun 26, 2012 in and tagged ,
Silverlight Toolkit has several NuGet packages (Core, Input, Theming, etc.). Unfortunately, Unit Testing Framework, which comes as a part of downloadable toolkit version, was not available for the fellow NuGet users. Until now. You can easily install it by typing ‘Install-Package SilverlightToolkit-Testing’ in the Package Manager console. Details here. The package just adds references to Microsoft.Silverlight.Testing.dll and Microsoft.VisualStudio.QualityTools.UnitTesting.Silverlight.dll assemblies, so that you don’t have to install toolkit or bloat your VCS with unnecessary binaries.

Task Commands revisited

Posted on Feb 23, 2012 in and tagged , , , ,

Half a year ago I blogged about using TPL with MVVM in a test-friendly way. My solution turned out to be pretty handy, though it was far from being perfect. In this post I will describe what was wrong with the initial implementation and can we slightly improve it.

Looking at that solution right now, I wonder why did I decide to use event async pattern (providing the ExecuteCompleted event) in the first place. The intention was to notify the caller about completion of the asynchronous operation. That is what System.Threading.Task is used for this days, isn’t it? So the obvious solution is to expose the ExecuteAsync() method returning the Task instance on the command class. Here is the source of the updated AsyncRelayCommand:

public class AsyncRelayCommand<T> : ICommand {
    private readonly RelayCommand<T> _internalCommand;
    private readonly Func<T, Task> _executeMethod;
 
    public event EventHandler CanExecuteChanged
    {
        add { _internalCommand.CanExecuteChanged += value; }
        remove { _internalCommand.CanExecuteChanged -= value; }
    }
 
    public AsyncRelayCommand(Func<T, Task> executeMethod, Predicate<T> canExecuteMethod)
    {
        if (executeMethod == null)
        {
            throw new ArgumentNullException("executeMethod");
        }
 
        _executeMethod = executeMethod;
        _internalCommand = new RelayCommand<T>(_ => { }, canExecuteMethod);
    }
 
    public AsyncRelayCommand(Func<T, Task> executeMethod)
        : this(executeMethod, _ => true) { }
 
    void ICommand.Execute(object parameter)
    {
        if (parameter is T)
        {
            ExecuteAsync((T)parameter);
        }
 
        else throw new ArgumentException("Parameter should be of type " + typeof(T));
    }
 
    public Task ExecuteAsync(T parameter)
    {
        return _executeMethod(parameter);
    }
 
    public bool CanExecute(object parameter)
    {
        return _internalCommand.CanExecute((T)parameter);
    }
 
    public void RaiseCanExecuteChanged()
    {
        _internalCommand.RaiseCanExecuteChanged();
    }
}

The code is pretty straightforward, here are the key points:

  • Create an inner command that responds to CanExecute, RaiseCanExecute calls and handles subscriptions to CanExecuteChanged event (optional, since I am using MVVM Light with most of my projects, that’s an acceptable solution for me. However, you may easily implement your own commanding logic).
  • Introduce new ExecuteAsync method that returns Task instance.
  • Implement ICommand.Execute explicitly (I find it more consistent not to have Execute method in the AsyncRelayCommand class).

Side note: as I mentioned in the beginning, I find this command extension rather useful. It was successfully used in 5 own projects (both WP7 and WPF), and I hope you enjoy it too.

As usual, the source code is available at bitbucket (TaskCommands.v2.zip).

Building advanced MVVM commands, Part 1

Posted on Nov 24, 2010 in and tagged , ,

If you follow the MVVM pattern while developing your WPF/Silverlight applications, then you are probably familiar with DelegateCommand (or RelayCommand, as it is called sometimes) model. In brief: it is an implementation of WPF/Silverlight ICommand that allows you to specify what the command should do by passing some delegate that performs execution logic (instead of using CommandBindings). Pretty simple, but powerful pattern.

Dealing with MVVM a lot, I’ve build my own implementation of this pattern that lets you simplify its usage.

Here are some common features, that you have to handle on your own by using classic DelegateCommand:

  • Support for asynchronous execution (usually solved by generating additional code in ViewModel that handles async calls and free/busy indicator).
  • Different command states (Free/Busy/Failed with exception) + UI reactions for those states.
  • Support for execution cancellation and progress tracking (required for asynchronous commands)

Before we start, I offer you to imagine a common command execution timeline. In my opinion it looks like:

  1. Initialize some data (generally, UI settings – clear collections, set some indicators,…)
  2. Perform main execution logic (can be synchronous or asynchronous)
  3. Perform some actions after execution (update UI based on execution result)

And don’t forget about exception handling and correct cross-thread calls for asynchronous commands (all UI changes have to be performed through Dispatcher).

Let’s start with a little helper class, that I called PropertyChangedNotifier. It’s just a wrapper around IPropertyChangedNotifier that has OnPropertyChanged(string propertyName) method. This method raises underlying IPropertyChangedNotifier.PropertyChanged event. Also this class has VerifyPropertyName method that verifies if specified string corresponds to the actual property (this method is marked with [Conditional(“DEBUG”)] attribute and is only used while debugging your applications to find out possible bugs with invalid property names)

public abstract class PropertyChangedNotifier : INotifyPropertyChanged
{
    protected virtual bool ThrowOnInvalidPropertyName { get; private set; }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName)
    {
        VerifyPropertyName(propertyName);

        var handler = PropertyChanged;
        if (handler != null)
        {
            var e = new PropertyChangedEventArgs(propertyName);
            handler(this, e);
        }
    }

    [Conditional("DEBUG")]
    [DebuggerStepThrough]
    private void VerifyPropertyName(string propertyName)
    {
        if (String.IsNullOrEmpty(propertyName))
        {
            return;
        }

        if (TypeDescriptor.GetProperties(this)[propertyName] == null)
        {
            string msg = "Invalid property name: " + propertyName;
            if (ThrowOnInvalidPropertyName)
            {
                throw new Exception(msg);
            }
            Debug.Fail(msg);
        }
    }
}

Let’s start our DelegateCommand with this classic imlementation:

public sealed class DelegateCommand<T>: PropertyChangedNotifier, ICommand where T: class
{
    public Action<DelegateCommand<T>, T> ExecuteAction
    {
        get;
        set;
    }

    public Predicate<T> CanExecutePredicate
    {
        get;
        set;
    }

    public DelegateCommand(Action<DelegateCommand<T>, T> execute, Predicate<T> canExecute)
    {
        ExecuteAction = execute;
        CanExecutePredicate = canExecute;
    }

    public void Execute(object parameter)
    {
        //blank
    }

    public bool CanExecute(object parameter)
    {
        //blank
    }

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }
}

As I’ve mentioned, we may need to execute this command asynchronously, so I added property IsAsync that lets you specify whether the call will be asynchronous or not. Also as have been discussed earlier, we need delegates for pre-execute, post-execute and error actions.

public Action<T> PreExecute
{
    get;
    set;
}

public event Action<DelegateCommand<T>> Executed;

public Action<Exception> OnException
{
    get;
    set;
}

public bool IsAsync
{
    get;
    set;
}

public bool DisableOnExecution
{
    get;
    set;
}

The last property, DisableOnExecution, tells command to report False to CanExecute calls when it is executed asynchronously.

Remember the command state I’ve told about? Create an enum named CommandState

public enum CommandState
{
    Succeeded,
    Failed,
    IsExecuting
}

and add State property of type CommandState to DelegateCommand.

private CommandState _state;
public CommandState State
{
    get { return _state; }
    set
    {
        if (_state == value)
        {
            return;
        }

        _state = value;

        //if command was executed asynchronously, there may be some issues with correct CanExecute checks,
        //so we force CommandManager to perform that check.
        lock (this)
        {
            if (IsAsync && DisableOnExecution)
            {
                InvokeOnUIThread(CommandManager.InvalidateRequerySuggested);
            }
        }

        OnPropertyChanged("State");
    }
}

This one is a bit tricky. For now, there are some issues with WPF that prevent CanExecute checks when command is executed asynchronously. So when async execution is completed, we tell CommandManager to update all the bindings and re-evaluate CanExecute by calling CommandManager.InvalidateRequerySuggested. Note that is has to be called on UI thread. InvokeOnUIThread adds specified action to the UI dispatcher queue.


public void InvokeOnUIThread(Action action) { Dispatcher.Invoke(action); }

Here Dispatcher is a local variable that is initialized in the constructor.

#if SILVERLIGHT
    Dispatcher = Deployment.Current.Dispatcher;
#else
    Dispatcher = Dispatcher.CurrentDispatcher;
#endif

And if we speak about async calls, let’s add a method that will invoke specified delegate asynchronously:

private static void InvokeAsync(Action task, AsyncCallback executed)
{
    task.BeginInvoke(executed, null);
}

private static void InvokeAsync(Action task)
{
    InvokeAsync(task, x => { });
}

Also you may want to store some exception information if the command execution failed.

private Exception _commandException;
public Exception CommandException
{
    get { return _commandException; }
    set
    {
        if (_commandException == value)
        {
            return;
        }

        _commandException = value;
        OnPropertyChanged("CommandException");
    }
}

Command cancellation? Yes, add IsCancellationPending property. With all this things set up, we are ready to implement Execute and CanExecute methods.

public void Execute(object parameter = null)
{
    var typedParameter = parameter as T;

    Action action = () =>
    {
        try
        {
            CallExecute(typedParameter);
            if (State != CommandState.Failed)
            {
                State = CommandState.Succeeded;
            }
        }
        catch (Exception ex)
        {
            State = CommandState.Failed;
            CommandException = ex;
            CallOnException(ex);
        }
    };

    IsCancellationPending = false;
    CommandException = null;
    State = CommandState.IsExecuting;

    CallPreExecute(typedParameter);

    if (IsAsync)
    {
        var handler = Executed;
        if (handler == null)
        {
            InvokeAsync(action);
        }
        else
        {
            InvokeAsync(action, x => handler(this));
        }
    }
    else
    {
        action();
        CallExecuted();
    }
}

public bool CanExecute(object parameter)
{
    if (CanExecutePredicate != null)
    {
        try
        {
            return !GetIsBusy() && CanExecutePredicate(parameter as T);
        }
        catch
        {
            return false;
        }
    }
    return !GetIsBusy();
}

Methods that are named like CallXXX are just wrappers around corresponding delegates that check if they can be called.

private void CallPreExecute(T arg)
{
    if (PreExecute != null)
    {
        PreExecute(arg);
    }
}

private void CallExecute(T arg)
{
    if (ExecuteAction != null)
    {
        ExecuteAction(this, arg);
    }
}

private void CallExecuted()
{
    var handler = Executed;
    if (handler != null)
    {
        handler(this);
    }
}

private void CallOnException(Exception ex)
{
    if (OnException != null)
    {
        InvokeOnUIThread(() => OnException(ex));
    }
}

GetIsBusy method is pretty simple.

private bool GetIsBusy()
{
    return DisableOnExecution && (State == CommandState.IsExecuting);
}

Note that Execute method can perform both synchronous and asynchronous calls based on IsAsync value. Pre-execution, post-execution and error handling delegates are called on UI thread, so when you use the command, you don’t have to think about.

Building test application

It will be pretty simple. User selects a directory, application lists all the files in this directory and its sub-directories. I’ll start with FileModel class that will represent one list entry

public class FileModel
{
    public String Name
    {
        get;
        set;
    }

    public String Extension
    {
        get;
        set;
    }

    public String Size
    {
        get;
        set;
    }

    public String FullPath
    {
        get;
        set;
    }
}

Next to the ViewModel. It will have Files property (the collection of FileModel) and LoadFilesCommand (implemented as our DelegateCommand)

public sealed class MainWindowViewModel: PropertyChangedNotifier
{
    public MainWindowViewModel()
    {
        Files = new ObservableCollection();
    }
        
    public ObservableCollection Files
    {
        get;
        private set;
    }

    private DelegateCommand _loadFilesCommand;
    public DelegateCommand LoadFilesCommand
    {
        get
        {
            return _loadFilesCommand ?? (_loadFilesCommand = new DelegateCommand(LoadFiles)
            {
                DisableOnExecution = true,
                IsAsync = true
            });
        }
    }

    private void LoadFiles(DelegateCommand cmd, String loadFrom)
    {
        cmd.InvokeOnUIThread(() => Files.Clear());

        Action addFile = file =>
        {
            var model = new FileModel
            {
                Name = Path.GetFileNameWithoutExtension(file),
                FullPath = Path.GetFullPath(file),
                Extension = Path.GetExtension(file),
                Size = GetFileSize(file)
            };
            cmd.InvokeOnUIThread(() => Files.Add(model));
        };

        Action fileLoader = null;
        fileLoader = path =>
        {
            if (cmd.IsCancellationPending)
            {
                return;
            }

            foreach (var file in Directory.GetFiles(path))
            {
                addFile(file);
            }

            foreach (var dir in Directory.GetDirectories(path))
            {
                if (cmd.IsCancellationPending)
                {
                    return;
                }

                try
                {
                    fileLoader(dir);
                }
                catch {}
            }
        };

        fileLoader(loadFrom);
    }

    private static String GetFileSize(String fileName)
    {
        try
        {
            using (var stream = File.OpenRead(fileName))
            {
                return (stream.Length/1024).ToString();
            }
        }
        catch
        {
            return "?";
        }
    }
}

Some comments:

  • We use recursive lambda-function to get all the files in the specified folder.
  • At each loop step we have to check if the user decided to cancel operation.
  • Empty catch are blocks are not good! I used them only to keep things simple. Normally you will have to log all the errors.
  • All actions that change UI state must be performed on UI thread (I use cmd.InvokeOnUIThread(…))
  • Pre-execute, post-execute and error handling are not covered in this sample. I will show how they can be used in the next part.

The application window markup

private void StopButton_Click(object sender, RoutedEventArgs e)
{
    (DataContext as MainWindowViewModel).LoadFilesCommand.IsCancellationPending = true;
}

Event handler in the code-behind file (we will get rid of this in the following parts, so that cancellation will be available from markup)

private void StopButton_Click(object sender, RoutedEventArgs e)
{
    (DataContext as MainWindowViewModel).LoadFilesCommand.IsCancellationPending = true;
}

Run the application. Enter any path in the text box and click Start button. It will be disabled and application will start to fill the list with file information. Clicking Stop will cancel this operation.

Sample application that uses async commands

That’s all for now. With this implementation we can keep ViewModels clean and perform async operations practically the same way that we would perform the usual ones.

Download sources

In the next parts I will show how the progress tracking can be added, how we can improve command initialization with fluent extensions and how it all can be combined with visual states via DataTemplates techniques I’ve described earlier. Good luck =)

Consider a common task – you need to switch between different screens in your application, that represent various states (e.g. Normal/Loading/Error). How are you going to implement this?

You can start with VisualStateManager and define appropriate visual states. Well, this will surely do the thing, but you will have to create lots of controls and manage their Visibility or Opacity. And what if you have a complex markup? And I suppose that switching the state will not remove invisible items from the visual tree. And even more, with VisualStateManager you are bound to Expression Blend, because, you know, it’s not very convenient to edit VSM settings by hands in XAML (which I prefer, but it is a topic for another article). The second option that may fit well, if you just need something like “I’m busy!” overlay is Silverlight Activity Control. Works like a charm with RIA services, but I find it limited for complex scenarios (and it’s not available for WPF).

I’ve found another approach (it becomes especially useful with MVVM and improved DelegateCommand implementations – I will blog about this in a few days). The idea behind this technique is quite simple. You define different templates for different page/window/control states. Yeah, that’s it. Let’s start with our implementation.

Our application will have only one page with 2 different states:

  1. A welcome screen, that hosts a button to start ‘the heavy’ calculation.
  2. Busy window” that shows information about the current processing progress.

I decided to create a simple ViewModel as a backing storage for our UI properties. It has two properties – IsBusy that says whether some hard work is executing now, and Progress – simple execution progress indicator. Method StartCalculation runs a new thread executes a number of loop steps. On each step the executing thread is suspended for 100ms (to imitate a slow operation). Normally you will create a DelegateCommand that will handle all the execution logic, but I decided to keep things simple.

public sealed class MainWindowViewModel: INotifyPropertyChanged
{
    public const string IsBusyProperty = "IsBusy";
    private bool _isBusy;
    public bool IsBusy
    {
        get { return _isBusy; }
        set
        {
            if (_isBusy == value)
            {
                return;
            }

            _isBusy = value;
            OnPropertyChanged(IsBusyProperty);
        }
    }

    public const string ProgressProperty = "Progress";
    private int _progress;
    public int Progress
    {
        get { return _progress; }
        set
        {
            if (_progress == value)
            {
                return;
            }

            _progress = value;
            OnPropertyChanged(ProgressProperty);
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(String property)
    {
        var handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(property));
        }
    }

    public void StartCalculation()
    {
        IsBusy = true;
        ThreadPool.QueueUserWorkItem(_ =>
        {
            for (int i = 0; i <= 50; i++)
            {
                int i1 = i;
                Deployment.Current.Dispatcher.BeginInvoke(() => Progress = i1);
                Thread.Sleep(100);
            }

            Deployment.Current.Dispatcher.BeginInvoke(() => IsBusy = false);
        });
    }
}

Let’s build a simple user interface (for now, without any states, just to check if our threading logic works)

<UserControl 
    x:Class="DataTemplateStateApplication.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:ViewModels="clr-namespace:DataTemplateStateApplication.ViewModels"
    xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" 
    xmlns:ei="clr-namespace:Microsoft.Expression.Interactivity.Core;assembly=Microsoft.Expression.Interactions">

    <UserControl.DataContext>
        <ViewModels:MainWindowViewModel/>
    </UserControl.DataContext>

    <Grid x:Name="LayoutRoot" Background="White">
        <Grid HorizontalAlignment="Center" VerticalAlignment="Center">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
		    
            <Button Width="60" Height="24" Content="Test">
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="Click">
                        <ei:CallMethodAction MethodName="StartCalculation" TargetObject="{Binding}"/>
                    </i:EventTrigger>
               </i:Interaction.Triggers>
            </Button>
		    
            <ProgressBar 
                Minimum="0" Maximum="50"
                Value="{Binding Progress}" 
                Height="24" Width="250" 
                Grid.Row="1" Margin="0,8,0,0"/>
        </Grid>
    </Grid>
</UserControl>

Note that if you use Visual Studio, you will have to manually add references to Microsoft.Expression.Interactions.dll and System.Windows.Interactivity.dll

I added a simple event trigger that calls StartCalculation method of our ViewModel when user clicks the button.

Now let’s move to the article subject. Define two DataTemplates in UserControl.Resources section:

<UserControl.Resources>
    <DataTemplate x:Key="NormalTemplate">
        <Button Width="60" Height="24" Content="Test">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="Click">
                    <ei:CallMethodAction MethodName="StartCalculation" TargetObject="{Binding}"/>
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </Button>
    </DataTemplate>
    <DataTemplate x:Key="BusyTemplate">
        <ProgressBar Minimum="0" Maximum="50" Value="{Binding Progress}" 
                     Height="24" Width="250"/>
    </DataTemplate>
</UserControl.Resources>

These templates describe two different presentations for a single MainWindowViewModel. Now we just have to provide some logic for switching between these templates when IsBusy property changes. Remove old layout markup (Button and Progressbar) and replace it with ContentPresenter with Content property bound to MainWindowViewModel:

<ContentPresenter Content="{Binding}">
    <i:Interaction.Triggers>
        <ei:DataTrigger Binding="{Binding IsBusy}" Value="True">
            <ei:ChangePropertyAction PropertyName="ContentTemplate" Value="{StaticResource BusyTemplate}"/>
        </ei:DataTrigger>
        <ei:DataTrigger Binding="{Binding IsBusy}" Value="False">
            <ei:ChangePropertyAction PropertyName="ContentTemplate" Value="{StaticResource NormalTemplate}"/>
        </ei:DataTrigger>
    </i:Interaction.Triggers>
</ContentPresenter>

Those DataTriggers from Microsoft.Expression.Interactions assembly do all the magic. They analyze the current value of IsBusy property and change the ContentPresenter.ContentTemplate value to the appropriate template.

That’s it. This technique can easily be used with more than 2 states, just declare new templates and triggers. Works with WPF too.

Download sources