Tag Archives: Caliburn Micro

Caliburn Micro Coroutines without individual IResult-implementing classes

I recently began a Silverlight project using Caliburn Micro.  So far, I’m pretty impressed.  It reduces the amount of code we write which is efficient for initial development and ongoing maintenance.  But in my opinion, even more important than that is the structure and simplicity it facilitates.

One of the things I find pretty sweet is the Coroutine feature to make implementing a sequence of asynchronous and synchronous tasks really straightforward.  For example, let’s say I want to issue a web request of some kind, wait for the result, then display the result in a dialog box, wait for the user input, then close (deactivate, or navigate away from) the current page or tab.  Writing this “by hand” with a series of event handlers is very doable, but messy.  Doing that with Caliburn Micro Coroutines is really straightforward.

If you are not familiar with this feature of Caliburn Micro, now would be a good time to read all about it at Caliburn Micro IResult and Coroutines.  You might also want to download and play with the Caliburn.Micro.Coroutines sample.  Then come back here and read about my small suggestion for another way to use this feature.

In the Caliburn.Micro.Coroutines sample, there are two classes that implement IResult: Loader and LoadCatalog.  In a different sample, Caliburn.Micro.HelloWindowManagerWP7 (also in the bundle of samples with the source code), is a third one called ShowDialog.cs which makes it easy to use a dialog in one of these Coroutine-based sequences.  I am using ShowDialog in my Silverlight project almost unmodified from it’s WP7 implementation.

As I started to write code in my project that needed to do several sequences like I mentioned in the second paragraph of this post, it struck me that I was going to have to write quite a few small, repetitive classes that basically just wrapped a call to our server data access.  So having already looked at the ShowDialog class which wraps invocation of any dialog screen with a single IResult-implementing class, I thought it would be useful to make an even more generic IResult wrapper class for doing any work I want.  The result is that I can now have the benefits of the Coroutine feature and avoid creating a bunch of extra classes when they are very short and not going to be reused anyway.

The code for my generic IResult wrapper class, which I called CoroutineWrapper, is below, but first, here is how I might implement a sequence of steps in an Action method on a Screen view model:

public IEnumerable<IResult> SaveButton()
{
    //  Update the data to the database.

    var updateCommand = new CoroutineWrapper().Init(coroutineWrapper =>
        {
            MyServiceAgentLayer.UpdateMyData(this.MyDataObject, (result) =>
            {
                coroutineWrapper.Result = result;
                coroutineWrapper.DoCompleted(new ResultCompletionEventArgs());
            });
        });
    yield return updateCommand;

    //  Show a dialog with the results of the update.

    var showResult = new ShowDialog<StandardDialogViewModel>().Init(dialog =>
        {
            dialog.Message = updateCommand.Result as string;
            dialog.ButtonText = "Close";
        });
    yield return showResult;

    //  Close this tab if the data was saved.

    if (updateCommand.Result as string == "Successfully updated") 
    { 
        TryClose(); 
    }
}

Basically, whatever work I would have put inside the Execute method of the class that implements IResult, I now pass as a parameter to the CoroutineWrapper.Init method. 

With this approach, we lose the impressive single line step invocation we see in the Coroutine samples, and I think that is a significant loss.  But we also avoid creating extra files and classes that each contain quite a few more repetitive lines of code.  So sometimes, I think this will be a good tradeoff.

If I planned to call this same code from multiple places, or it was more than a handful of lines of code, or it made sense to have a set of steps implemented in a single contained class (such as the Loader class in the Coroutines sample), creating a unique class that implements IResult and carries out the step is appropriate.  But when I only want to do a few simple lines of code, creating a whole class to do that seems like overkill to me.

Here is my initial implementation of the CoroutineWrapper class, adapted from the ShowDialog implementation:

using System;
using Caliburn.Micro;

namespace MyApp.CoroutineHelpers
{
    public class CoroutineWrapper : IResult
    {
        private Action<CoroutineWrapper> work = x => { };

        public ActionExecutionContext Context { get; set; }

        public object Result { get; set; }
       
        public CoroutineWrapper Init(Action<CoroutineWrapper> work)
        {
            this.work = work;
            return this;
        }

        public void Execute(ActionExecutionContext context) {
            this.Context = context;
            work.Invoke(this);
        }

        public void DoCompleted(ResultCompletionEventArgs args)
        {
            this.Completed(this, args);
        }

        public event EventHandler<ResultCompletionEventArgs> Completed = delegate { };
    }
}