204 lines
7.8 KiB
C#
204 lines
7.8 KiB
C#
using MainShell.Common;
|
|
using MainShell.ProcessResult;
|
|
using MW.WorkFlow;
|
|
using System;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace MainShell.Process
|
|
{
|
|
public abstract class ActivityAbstractBase : IActivity
|
|
{
|
|
public string Name { get; protected set; }
|
|
|
|
protected ProcessResultManager ResultManager { get; private set; }
|
|
|
|
protected string CurrentWorkflowName { get; private set; } = "UnknownFlow";
|
|
|
|
protected string ParentActivityName { get; private set; } = string.Empty;
|
|
|
|
protected ActivityAbstractBase(string name)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(name))
|
|
{
|
|
throw new ArgumentException("Activity name cannot be null or whitespace.", nameof(name));
|
|
}
|
|
|
|
Name = name;
|
|
}
|
|
|
|
public async Task<ActivityResult> ExecuteAsync(WorkflowContext context, ActivityControl activityControl)
|
|
{
|
|
if (context == null)
|
|
{
|
|
throw new ArgumentNullException(nameof(context));
|
|
}
|
|
|
|
if (activityControl == null)
|
|
{
|
|
throw new ArgumentNullException(nameof(activityControl));
|
|
}
|
|
|
|
var result = ActivityResult.Failure;
|
|
var hasFaulted = false;
|
|
|
|
try
|
|
{
|
|
if (context.TryGetData<string>(WorkflowContextKeys.WorkflowName, out var flowName))
|
|
{
|
|
CurrentWorkflowName = flowName;
|
|
}
|
|
|
|
if (context.TryGetData<string>(WorkflowContextKeys.ParentActivityName, out var parentName))
|
|
{
|
|
ParentActivityName = parentName;
|
|
}
|
|
else
|
|
{
|
|
ParentActivityName = string.Empty;
|
|
}
|
|
|
|
if (context.TryGetData<ProcessResultManager>(WorkflowContextKeys.ProcessResultManager, out var manager))
|
|
{
|
|
ResultManager = manager;
|
|
ResultManager.UpdateFlowState(CurrentWorkflowName, ParentActivityName, Name, ProcessExecutionStatus.Running, null);
|
|
}
|
|
|
|
PrepareExecute(context, activityControl);
|
|
result = await OnExecuteAsync(context, activityControl);
|
|
return result;
|
|
}
|
|
catch (OperationCanceledException)
|
|
{
|
|
ResultManager?.UpdateFlowState(CurrentWorkflowName, ParentActivityName, Name, ProcessExecutionStatus.Canceled, null);
|
|
throw;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
if (!HasWorkflowFailure(context))
|
|
{
|
|
SetWorkflowFailure(
|
|
context,
|
|
MessageKey.ProcessStepFailedWithReason,
|
|
new object[] { Name, ex.Message ?? string.Empty });
|
|
}
|
|
|
|
var errorMsg = ResolveWorkflowFailureMessage(context);
|
|
ResultManager?.UpdateFlowState(CurrentWorkflowName, ParentActivityName, Name, ProcessExecutionStatus.Faulted, errorMsg);
|
|
hasFaulted = true;
|
|
throw;
|
|
}
|
|
finally
|
|
{
|
|
AfterExecute(context, activityControl);
|
|
|
|
if (ResultManager != null && !hasFaulted)
|
|
{
|
|
if (result == ActivityResult.Success)
|
|
{
|
|
ResultManager.UpdateFlowState(CurrentWorkflowName, ParentActivityName, Name, ProcessExecutionStatus.Completed, null);
|
|
}
|
|
else if (result == ActivityResult.Canceled)
|
|
{
|
|
ResultManager.UpdateFlowState(CurrentWorkflowName, ParentActivityName, Name, ProcessExecutionStatus.Canceled, null);
|
|
}
|
|
else
|
|
{
|
|
ResultManager.UpdateFlowState(
|
|
CurrentWorkflowName,
|
|
ParentActivityName,
|
|
Name,
|
|
ProcessExecutionStatus.Faulted,
|
|
ResolveWorkflowFailureMessage(context));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
protected ActivityResult Fail(WorkflowContext context, MessageKey failureMessageKey, object[] failureMessageArguments)
|
|
{
|
|
SetWorkflowFailure(context, failureMessageKey, failureMessageArguments);
|
|
return ActivityResult.Failure;
|
|
}
|
|
|
|
protected void SetWorkflowFailure(WorkflowContext context, MessageKey failureMessageKey, object[] failureMessageArguments)
|
|
{
|
|
if (context == null)
|
|
{
|
|
throw new ArgumentNullException(nameof(context));
|
|
}
|
|
|
|
var normalized = NormalizeFailureMessageArguments(failureMessageArguments);
|
|
context.SetData(WorkflowContextKeys.WorkflowFailureMessageKey, failureMessageKey);
|
|
context.SetData(WorkflowContextKeys.WorkflowFailureMessageArguments, normalized);
|
|
context.SetData(WorkflowContextKeys.WorkflowFailureMessage, LanguageResourceHelper.Format(failureMessageKey, normalized));
|
|
}
|
|
|
|
protected void SetWorkflowFailure(WorkflowContext context, string failureMessage)
|
|
{
|
|
if (context == null)
|
|
{
|
|
throw new ArgumentNullException(nameof(context));
|
|
}
|
|
|
|
context.SetData(WorkflowContextKeys.WorkflowFailureMessageKey, MessageKey.None);
|
|
context.SetData<object[]>(WorkflowContextKeys.WorkflowFailureMessageArguments, null);
|
|
context.SetData(WorkflowContextKeys.WorkflowFailureMessage, failureMessage ?? string.Empty);
|
|
}
|
|
|
|
protected bool HasWorkflowFailure(WorkflowContext context)
|
|
{
|
|
if (context.TryGetData<MessageKey>(WorkflowContextKeys.WorkflowFailureMessageKey, out var failureMessageKey) &&
|
|
failureMessageKey > MessageKey.None)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
return context.TryGetData<string>(WorkflowContextKeys.WorkflowFailureMessage, out var failureMessage) &&
|
|
!string.IsNullOrWhiteSpace(failureMessage);
|
|
}
|
|
|
|
protected string ResolveWorkflowFailureMessage(WorkflowContext context)
|
|
{
|
|
if (context.TryGetData<MessageKey>(WorkflowContextKeys.WorkflowFailureMessageKey, out var failureMessageKey) &&
|
|
failureMessageKey > MessageKey.None)
|
|
{
|
|
return LanguageResourceHelper.Format(failureMessageKey, GetWorkflowFailureMessageArguments(context));
|
|
}
|
|
|
|
if (context.TryGetData<string>(WorkflowContextKeys.WorkflowFailureMessage, out var failureMessage) &&
|
|
!string.IsNullOrWhiteSpace(failureMessage))
|
|
{
|
|
return failureMessage;
|
|
}
|
|
|
|
return string.Empty;
|
|
}
|
|
|
|
protected object[] GetWorkflowFailureMessageArguments(WorkflowContext context)
|
|
{
|
|
if (context.TryGetData<object[]>(WorkflowContextKeys.WorkflowFailureMessageArguments, out var failureMessageArguments) &&
|
|
failureMessageArguments != null)
|
|
{
|
|
return failureMessageArguments;
|
|
}
|
|
|
|
return Array.Empty<object>();
|
|
}
|
|
|
|
protected object[] NormalizeFailureMessageArguments(object[] failureMessageArguments)
|
|
{
|
|
return failureMessageArguments ?? Array.Empty<object>();
|
|
}
|
|
|
|
protected abstract Task<ActivityResult> OnExecuteAsync(WorkflowContext context, ActivityControl activityControl);
|
|
|
|
protected virtual void PrepareExecute(WorkflowContext context, ActivityControl activityControl)
|
|
{
|
|
}
|
|
|
|
protected virtual void AfterExecute(WorkflowContext context, ActivityControl activityControl)
|
|
{
|
|
}
|
|
}
|
|
}
|