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)});
}
}
}