namespace Caliburn.Micro.Core { using System; /// /// A result decorator which executes a coroutine when the wrapped result was cancelled. /// public class ContinueResultDecorator : ResultDecoratorBase { static readonly ILog Log = LogManager.GetLog(typeof(ContinueResultDecorator)); readonly Func coroutine; /// /// Initializes a new instance of the class. /// /// The result to decorate. /// The coroutine to execute when was canceled. public ContinueResultDecorator(IResult result, Func coroutine) : base(result) { if (coroutine == null) throw new ArgumentNullException("coroutine"); this.coroutine = coroutine; } /// /// Called when the execution of the decorated result has completed. /// /// The context. /// The decorated result. /// The instance containing the event data. protected override void OnInnerResultCompleted(CoroutineExecutionContext context, IResult innerResult, ResultCompletionEventArgs args) { if (args.Error != null || !args.WasCancelled) { OnCompleted(new ResultCompletionEventArgs {Error = args.Error}); } else { Log.Info(string.Format("Executing coroutine because {0} was cancelled.", innerResult.GetType().Name)); Continue(context); } } void Continue(CoroutineExecutionContext context) { IResult continueResult; try { continueResult = coroutine(); } catch (Exception ex) { OnCompleted(new ResultCompletionEventArgs {Error = ex}); return; } try { continueResult.Completed += ContinueCompleted; IoC.BuildUp(continueResult); continueResult.Execute(context); } catch (Exception ex) { ContinueCompleted(continueResult, new ResultCompletionEventArgs {Error = ex}); } } void ContinueCompleted(object sender, ResultCompletionEventArgs args) { ((IResult)sender).Completed -= ContinueCompleted; OnCompleted(new ResultCompletionEventArgs {Error = args.Error, WasCancelled = (args.Error == null)}); } } }