Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add context to If When ForEach and UserTask #1095

Merged
merged 2 commits into from
Apr 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion src/WorkflowCore/Interface/IWorkflowModifier.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,28 +83,49 @@ IStepBuilder<TData, WaitFor> WaitFor(string eventName,
/// <param name="collection">Resolves a collection for iterate over</param>
/// <returns></returns>
IContainerStepBuilder<TData, Foreach, Foreach> ForEach(Expression<Func<TData, IEnumerable>> collection);

/// <summary>
/// Execute a block of steps, once for each item in a collection in a RunParallel foreach
/// </summary>
/// <param name="collection">Resolves a collection for iterate over</param>
/// <returns></returns>
IContainerStepBuilder<TData, Foreach, Foreach> ForEach(Expression<Func<TData, IEnumerable>> collection, Expression<Func<TData, bool>> runParallel);

/// <summary>
/// Execute a block of steps, once for each item in a collection in a RunParallel foreach
/// </summary>
/// <param name="collection">Resolves a collection for iterate over</param>
/// <returns></returns>
IContainerStepBuilder<TData, Foreach, Foreach> ForEach(Expression<Func<TData, IStepExecutionContext, IEnumerable>> collection, Expression<Func<TData, bool>> runParallel);

/// <summary>
/// Repeat a block of steps until a condition becomes true
/// </summary>
/// <param name="condition">Resolves a condition to break out of the while loop</param>
/// <returns></returns>
IContainerStepBuilder<TData, While, While> While(Expression<Func<TData, bool>> condition);

/// <summary>
/// Repeat a block of steps until a condition becomes true
/// </summary>
/// <param name="condition">Resolves a condition to break out of the while loop</param>
/// <returns></returns>
IContainerStepBuilder<TData, While, While> While(Expression<Func<TData, IStepExecutionContext, bool>> condition);

/// <summary>
/// Execute a block of steps if a condition is true
/// </summary>
/// <param name="condition">Resolves a condition to evaluate</param>
/// <returns></returns>
IContainerStepBuilder<TData, If, If> If(Expression<Func<TData, bool>> condition);

/// <summary>
/// Execute a block of steps if a condition is true
/// </summary>
/// <param name="condition">Resolves a condition to evaluate</param>
/// <returns></returns>
IContainerStepBuilder<TData, If, If> If(Expression<Func<TData, IStepExecutionContext, bool>> condition);

/// <summary>
/// Configure an outcome for this step, then wire it to a sequence
/// </summary>
Expand Down
73 changes: 60 additions & 13 deletions src/WorkflowCore/Services/FluentBuilders/StepBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public IStepBuilder<TData, TStep> Then<TStep>(IStepBuilder<TData, TStep> newStep
}

public IStepBuilder<TData, InlineStepBody> Then(Func<IStepExecutionContext, ExecutionResult> body)
{
{
WorkflowStepInline newStep = new WorkflowStepInline();
newStep.Body = body;
WorkflowBuilder.AddStep(newStep);
Expand Down Expand Up @@ -100,7 +100,7 @@ public IStepOutcomeBuilder<TData> When(object outcomeValue, string label = null)
var outcomeBuilder = new StepOutcomeBuilder<TData>(WorkflowBuilder, result);
return outcomeBuilder;
}

public IStepBuilder<TData, TStepBody> Branch<TStep>(object outcomeValue, IStepBuilder<TData, TStep> branch) where TStep : IStepBody
{
if (branch.WorkflowBuilder.Steps.Count == 0)
Expand All @@ -123,10 +123,10 @@ public IStepBuilder<TData, TStepBody> Branch<TStep>(Expression<Func<TData, objec
if (branch.WorkflowBuilder.Steps.Count == 0)
return this;

WorkflowBuilder.AttachBranch(branch.WorkflowBuilder);
WorkflowBuilder.AttachBranch(branch.WorkflowBuilder);

Step.Outcomes.Add(new ExpressionOutcome<TData>(outcomeExpression)
{
{
NextStep = branch.WorkflowBuilder.Steps[0].Id
});

Expand Down Expand Up @@ -155,7 +155,7 @@ public IStepBuilder<TData, TStepBody> Input(Action<TStepBody, TData, IStepExecut
{
Step.Inputs.Add(new ActionParameter<TStepBody, TData>(action));
return this;
}
}

public IStepBuilder<TData, TStepBody> Output<TOutput>(Expression<Func<TData, TOutput>> dataProperty, Expression<Func<TStepBody, object>> value)
{
Expand Down Expand Up @@ -206,7 +206,7 @@ public IStepBuilder<TData, WaitFor> WaitFor(string eventName, Expression<Func<TD
Step.Outcomes.Add(new ValueOutcome { NextStep = newStep.Id });
return stepBuilder;
}

public IStepBuilder<TData, TStep> End<TStep>(string name) where TStep : IStepBody
{
var ancestor = IterateParents(Step.Id, name);
Expand Down Expand Up @@ -294,12 +294,12 @@ public IStepBuilder<TData, Decide> Decide(Expression<Func<TData, object>> expres
public IContainerStepBuilder<TData, Foreach, Foreach> ForEach(Expression<Func<TData, IEnumerable>> collection)
{
var newStep = new WorkflowStep<Foreach>();

Expression<Func<Foreach, IEnumerable>> inputExpr = (x => x.Collection);
newStep.Inputs.Add(new MemberMapParameter(collection, inputExpr));
newStep.Inputs.Add(new MemberMapParameter(collection, inputExpr));

WorkflowBuilder.AddStep(newStep);
var stepBuilder = new StepBuilder<TData, Foreach>(WorkflowBuilder, newStep);
var stepBuilder = new StepBuilder<TData, Foreach>(WorkflowBuilder, newStep);

Step.Outcomes.Add(new ValueOutcome { NextStep = newStep.Id });

Expand All @@ -324,6 +324,23 @@ public IContainerStepBuilder<TData, Foreach, Foreach> ForEach(Expression<Func<TD
return stepBuilder;
}

public IContainerStepBuilder<TData, Foreach, Foreach> ForEach(Expression<Func<TData, IStepExecutionContext, IEnumerable>> collection, Expression<Func<TData, bool>> runParallel)
{
var newStep = new WorkflowStep<Foreach>();

Expression<Func<Foreach, IEnumerable>> inputExpr = (x => x.Collection);
newStep.Inputs.Add(new MemberMapParameter(collection, inputExpr));

Expression<Func<Foreach, bool>> pExpr = (x => x.RunParallel);
newStep.Inputs.Add(new MemberMapParameter(runParallel, pExpr));

WorkflowBuilder.AddStep(newStep);
var stepBuilder = new StepBuilder<TData, Foreach>(WorkflowBuilder, newStep);

Step.Outcomes.Add(new ValueOutcome { NextStep = newStep.Id });

return stepBuilder;
}

public IContainerStepBuilder<TData, While, While> While(Expression<Func<TData, bool>> condition)
{
Expand All @@ -340,6 +357,21 @@ public IContainerStepBuilder<TData, While, While> While(Expression<Func<TData, b
return stepBuilder;
}

public IContainerStepBuilder<TData, While, While> While(Expression<Func<TData, IStepExecutionContext, bool>> condition)
{
var newStep = new WorkflowStep<While>();

Expression<Func<While, bool>> inputExpr = (x => x.Condition);
newStep.Inputs.Add(new MemberMapParameter(condition, inputExpr));

WorkflowBuilder.AddStep(newStep);
var stepBuilder = new StepBuilder<TData, While>(WorkflowBuilder, newStep);

Step.Outcomes.Add(new ValueOutcome { NextStep = newStep.Id });

return stepBuilder;
}

public IContainerStepBuilder<TData, If, If> If(Expression<Func<TData, bool>> condition)
{
var newStep = new WorkflowStep<If>();
Expand All @@ -354,7 +386,22 @@ public IContainerStepBuilder<TData, If, If> If(Expression<Func<TData, bool>> con

return stepBuilder;
}


public IContainerStepBuilder<TData, If, If> If(Expression<Func<TData, IStepExecutionContext, bool>> condition)
{
var newStep = new WorkflowStep<If>();

Expression<Func<If, bool>> inputExpr = (x => x.Condition);
newStep.Inputs.Add(new MemberMapParameter(condition, inputExpr));

WorkflowBuilder.AddStep(newStep);
var stepBuilder = new StepBuilder<TData, If>(WorkflowBuilder, newStep);

Step.Outcomes.Add(new ValueOutcome { NextStep = newStep.Id });

return stepBuilder;
}

public IContainerStepBuilder<TData, When, OutcomeSwitch> When(Expression<Func<TData, object>> outcomeValue, string label = null)
{
var newStep = new WorkflowStep<When>();
Expand All @@ -378,7 +425,7 @@ public IContainerStepBuilder<TData, When, OutcomeSwitch> When(Expression<Func<TD
{
switchBuilder = (this as IStepBuilder<TData, OutcomeSwitch>);
}

WorkflowBuilder.AddStep(newStep);
var stepBuilder = new ReturnStepBuilder<TData, When, OutcomeSwitch>(WorkflowBuilder, newStep, switchBuilder);
switchBuilder.Step.Children.Add(newStep.Id);
Expand Down Expand Up @@ -512,10 +559,10 @@ public IStepBuilder<TData, Activity> Activity(string activityName, Expression<Fu
WorkflowBuilder.AddStep(newStep);
var stepBuilder = new StepBuilder<TData, Activity>(WorkflowBuilder, newStep);
stepBuilder.Input((step) => step.ActivityName, (data) => activityName);

if (parameters != null)
stepBuilder.Input((step) => step.Parameters, parameters);

if (effectiveDate != null)
stepBuilder.Input((step) => step.EffectiveDate, effectiveDate);

Expand Down
15 changes: 15 additions & 0 deletions src/WorkflowCore/Services/FluentBuilders/WorkflowBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -241,16 +241,31 @@ public IContainerStepBuilder<TData, Foreach, Foreach> ForEach(Expression<Func<TD
return Start().ForEach(collection, runParallel);
}

public IContainerStepBuilder<TData, Foreach, Foreach> ForEach(Expression<Func<TData, IStepExecutionContext, IEnumerable>> collection, Expression<Func<TData, bool>> runParallel)
{
return Start().ForEach(collection, runParallel);
}

public IContainerStepBuilder<TData, While, While> While(Expression<Func<TData, bool>> condition)
{
return Start().While(condition);
}

public IContainerStepBuilder<TData, While, While> While(Expression<Func<TData, IStepExecutionContext, bool>> condition)
{
return Start().While(condition);
}

public IContainerStepBuilder<TData, If, If> If(Expression<Func<TData, bool>> condition)
{
return Start().If(condition);
}

public IContainerStepBuilder<TData, If, If> If(Expression<Func<TData, IStepExecutionContext, bool>> condition)
{
return Start().If(condition);
}

public IContainerStepBuilder<TData, When, OutcomeSwitch> When(Expression<Func<TData, object>> outcomeValue, string label = null)
{
return ((IWorkflowModifier<TData, InlineStepBody>) Start()).When(outcomeValue, label);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public static IStepBuilder<TData, UserStep> UserStep<TData, TStepBody>(this ISte
{
var newStep = new UserStepContainer();
newStep.Principal = assigner;
newStep.UserPrompt = userPrompt;
newStep.UserPrompt = userPrompt;
builder.WorkflowBuilder.AddStep(newStep);
var stepBuilder = new StepBuilder<TData, UserStep>(builder.WorkflowBuilder, newStep);

Expand Down Expand Up @@ -64,5 +64,23 @@ public static IUserTaskBuilder<TData> UserTask<TData, TStepBody>(this IStepBuild

return stepBuilder;
}

public static IUserTaskBuilder<TData> UserTask<TData, TStepBody>(this IStepBuilder<TData, TStepBody> builder, string userPrompt, Expression<Func<TData, IStepExecutionContext, string>> assigner, Action<IStepBuilder<TData, UserTask>> stepSetup = null)
where TStepBody : IStepBody
{
var newStep = new UserTaskStep();
builder.WorkflowBuilder.AddStep(newStep);
var stepBuilder = new UserTaskBuilder<TData>(builder.WorkflowBuilder, newStep);
stepBuilder.Input(step => step.AssignedPrincipal, assigner);
stepBuilder.Input(step => step.Prompt, data => userPrompt);

if (stepSetup != null)
stepSetup.Invoke(stepBuilder);

newStep.Name = newStep.Name ?? typeof(UserTask).Name;
builder.Step.Outcomes.Add(new ValueOutcome { NextStep = newStep.Id });

return stepBuilder;
}
}
}