Sic04/FrameworkLocal/UIClient/Caliburn.Micro/Core/ContinueResultDecorator.cs

66 lines
2.7 KiB
C#

namespace Caliburn.Micro.Core {
using System;
/// <summary>
/// A result decorator which executes a coroutine when the wrapped result was cancelled.
/// </summary>
public class ContinueResultDecorator : ResultDecoratorBase {
static readonly ILog Log = LogManager.GetLog(typeof(ContinueResultDecorator));
readonly Func<IResult> coroutine;
/// <summary>
/// Initializes a new instance of the <see cref="ContinueResultDecorator"/> class.
/// </summary>
/// <param name="result">The result to decorate.</param>
/// <param name="coroutine">The coroutine to execute when <paramref name="result"/> was canceled.</param>
public ContinueResultDecorator(IResult result, Func<IResult> coroutine)
: base(result) {
if (coroutine == null)
throw new ArgumentNullException("coroutine");
this.coroutine = coroutine;
}
/// <summary>
/// Called when the execution of the decorated result has completed.
/// </summary>
/// <param name="context">The context.</param>
/// <param name="innerResult">The decorated result.</param>
/// <param name="args">The <see cref="ResultCompletionEventArgs" /> instance containing the event data.</param>
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)});
}
}
}