This is the next series in the Caliburn tutorials. You can find previous post: Part One, Part Two, Part Three.

One of the best features of Caliburn framework that I haven’t seen in other MVVM frameworks, is a feature called Coroutines. Coroutines are according to Wikipedia:

In computer science, coroutines are program components that generalize subroutines to allow multiple entry points for suspending and resuming execution at certain locations. Coroutines are well-suited for implementing more familiar program components such as cooperative tasks, iterators,infinite lists and pipes.

This feature is extremely useful if you do async programming like accessing data over a webservice or execution of long running tasks on the background thread. Let’s take a closer look on how to use this feature and how it helps us developing better applications and results in more maintainable code.

This post will work equally on Caliburn 1.1 and 2.0.

A Recap on Actions

If you have seen other parts of Caliburn posts, Caliburn facilitates implementing MVVM by eliminating usage of ICommands. Forget about implementing ICommand interface or using RelayCommands. You can not directly bind your events to public actions on your ViewModel class. You no longer are limited by controls having commands, you can bind any arbitrary event to any public method on your ViewModel. Caliburn also checks for any existing preconditions based on the convention. The precondition, called Filters, are properties name the same as your action, but with a “Can” prefix. Here’s how it looks to bind:

1
<Button cal:Message.Attach="[Event Click] = [Action ShowCustomers]">
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public virtual bool CanShowOrders 
{
get { return _canShowOrders; }
set
{
_canShowOrders = value;
NotifyOfPropertyChanged(() => CanShowOrders);
}
}

public virtual void ShowOrders()
{
CurrentPresenter = ViewModelFactory.Create<IOrderViewModel>();
}

Using Coroutines

Your action that used to return void can return a special return type that will be handeld by Caliburn upon execution. If your method returns an instance of IResult interface it will be treated differently. First let us look at IResult interface:

1
2
3
4
5
public interface IResult  
{
void Execute(ActionExecutionContext context);
event EventHandler<ResultCompletionEventArgs> Completed;
}

Very simple to implement! Basically, Execute method is called by Caliburn and this is where you implement the execution logic of this action. Caliburn then pauses unitl your action fires “Completed” event at which point it understands that action has compeleted and is finished. Where’s the power, you may ask? Well you can send multiple IResults instanced from your action method by returning an IEnumerable<IResult> and since Caliburn waits for each action to fire its Completed event, all IResult instances are processed sequentially. An example is displaying a progress window, firing up a background worker to do a long running process data and stop progress window when the background worker is finished, let’s see how:

1
2
3
4
5
6
public IEnumerable<IResult> LoadOrders()
{
yield return ProgressResult.Show("Loading Orders");
yield return new ServiceFetchResult(...);
yield return ProgressResult.Hide();
}

And the outcome is that the progress window is still showing until ServiceFetchResult has finished the long running procedure.

Progress Window

Remember how specially IResults are treated. In the above example, enumerable items are only processed if the previous one’s Completed event is fired. This helps a lot when you do async style programming, specially in Silverlight which almost every outgoing request should run asynchronously.

Testability

If you have used an async service, you know how painful it is when it comes down to testing. The problem is how the Async model works, and the easiest way is the same way you connect to webservices in Silverlight: First you subscribe to the event that is called when operation is completed, then you call the async method and wait for it to call you back on the callback handler. If you want to abstract it in an interface, it’d be something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class FetchOrdersCompletedEventArgs : AsyncCompletedEventArgs
{
public FetchOrdersCompletedEventArgs(Exception error, bool cancelled, object userState)
: base(error, cancelled, userState)
{
}
}

public class OrdersDataClient
{
public void FetchOrdersAsync()
{
//some stuff
}

public event EventHandler<FetchOrdersCompletedEventArgs> FetchOrdersCompleted;
}

The problem with this code which makes it unsuitable for testing is that you usually generate proxies for your services and this piece of generated code has numerous problems: there’s no clean interface and even generated methods are not virtual, making the whole thing unreplaceable in testing (at least by conventional tools). Notice that this implementation of async pattern which uses events is much cleaner than the one using IAsyncResult and callbacks, but still not much good in unit testing.

Now lets sit back and see what is it that we want to test? Let’s suppose we want to test that LoadOrders will load orders from the correct service operation, how would we do that?

1
2
3
4
5
6
7
8
9
10
11
[Test]
public void Orders_Are_Loaded_From_Service()
{
var mockService = Mock<OrdersServiceClient>();

var vm = new OrderViewModel(mockService);

vm.LoadOrders();

mockService.AssertWasCalled(x => x.FetchOrdersAsync());
}

This code would have worked unless you can’t mocked out the service that easily, remember? Now here’s how using IResult would help you test the same thing, but with a changed mindset:

1
2
3
4
5
6
7
8
9
10
11
[Test]
public void Orders_Are_Loaded_From_Service()
{
var vm = new OrderViewModel();

var results = vm.LoadOrders().ToList();
var fetchRequest = results[1] as ServiceFetchResult;

Assert.NotNull(fetchRequest);
Assert.That(fetchRequest.Action.Method.Name, Is.EqualTo("FetchOrdersAsync"));
}