You can define multiple independent branches within your workflow and select one based on an expression value.
For the fluent API, we define our branches with the CreateBranch()
method on the workflow builder. We can then select a branch using the Branch
method.
The select expressions will be matched to the branch listed via the Branch
method, and the matching next step(s) will be scheduled to execute next. Matching multiple next steps will result in parallel branches running.
This workflow will select branch1
if the value of data.Value1
is one
, and branch2
if it is two
.
var branch1 = builder.CreateBranch()
.StartWith<PrintMessage>()
.Input(step => step.Message, data => "hi from 1")
.Then<PrintMessage>()
.Input(step => step.Message, data => "bye from 1");
var branch2 = builder.CreateBranch()
.StartWith<PrintMessage>()
.Input(step => step.Message, data => "hi from 2")
.Then<PrintMessage>()
.Input(step => step.Message, data => "bye from 2");
builder
.StartWith<HelloWorld>()
.Decide(data => data.Value1)
.Branch((data, outcome) => data.Value1 == "one", branch1)
.Branch((data, outcome) => data.Value1 == "two", branch2);
Hook up your branches via the SelectNextStep
property, instead of a NextStepId
. The expressions will be matched to the step Ids listed in SelectNextStep
, and the matching next step(s) will be scheduled to execute next.
{
"Id": "DecisionWorkflow",
"Version": 1,
"DataType": "MyApp.MyData, MyApp",
"Steps": [
{
"Id": "decide",
"StepType": "...",
"SelectNextStep":
{
"Branch1": "<<result expression to match for branch 1>>",
"Branch2": "<<result expression to match for branch 2>>"
}
},
{
"Id": "Branch1",
"StepType": "MyApp.PrintMessage, MyApp",
"Inputs":
{
"Message": "\"Hello from 1\""
}
},
{
"Id": "Branch2",
"StepType": "MyApp.PrintMessage, MyApp",
"Inputs":
{
"Message": "\"Hello from 2\""
}
}
]
}
Id: DecisionWorkflow
Version: 1
DataType: MyApp.MyData, MyApp
Steps:
- Id: decide
StepType: WorkflowCore.Primitives.Decide, WorkflowCore
Inputs:
Expression: <<input expression to evaluate>>
OutcomeSteps:
Branch1: '<<result expression to match for branch 1>>'
Branch2: '<<result expression to match for branch 2>>'
- Id: Branch1
StepType: MyApp.PrintMessage, MyApp
Inputs:
Message: '"Hello from 1"'
- Id: Branch2
StepType: MyApp.PrintMessage, MyApp
Inputs:
Message: '"Hello from 2"'
Use the .ForEach method to start a parallel for loop
public class ForEachWorkflow : IWorkflow
{
public string Id => "Foreach";
public int Version => 1;
public void Build(IWorkflowBuilder<object> builder)
{
builder
.StartWith<SayHello>()
.ForEach(data => new List<int>() { 1, 2, 3, 4 })
.Do(x => x
.StartWith<DisplayContext>()
.Input(step => step.Message, (data, context) => context.Item)
.Then<DoSomething>())
.Then<SayGoodbye>();
}
}
{
"Id": "MyForEachStep",
"StepType": "WorkflowCore.Primitives.ForEach, WorkflowCore",
"NextStepId": "...",
"Inputs": { "Collection": "<<expression to evaluate>>" },
"Do": [[
{
"Id": "do1",
"StepType": "MyApp.DoSomething1, MyApp",
"NextStepId": "do2"
},
{
"Id": "do2",
"StepType": "MyApp.DoSomething2, MyApp"
}
]]
}
Id: MyForEachStep
StepType: WorkflowCore.Primitives.ForEach, WorkflowCore
NextStepId: "..."
Inputs:
Collection: "<<expression to evaluate>>"
Do:
- - Id: do1
StepType: MyApp.DoSomething1, MyApp
NextStepId: do2
- Id: do2
StepType: MyApp.DoSomething2, MyApp
Use the .While method to start a while construct
public class WhileWorkflow : IWorkflow<MyData>
{
public string Id => "While";
public int Version => 1;
public void Build(IWorkflowBuilder<MyData> builder)
{
builder
.StartWith<SayHello>()
.While(data => data.Counter < 3)
.Do(x => x
.StartWith<DoSomething>()
.Then<IncrementStep>()
.Input(step => step.Value1, data => data.Counter)
.Output(data => data.Counter, step => step.Value2))
.Then<SayGoodbye>();
}
}
{
"Id": "MyWhileStep",
"StepType": "WorkflowCore.Primitives.While, WorkflowCore",
"NextStepId": "...",
"Inputs": { "Condition": "<<expression to evaluate>>" },
"Do": [[
{
"Id": "do1",
"StepType": "MyApp.DoSomething1, MyApp",
"NextStepId": "do2"
},
{
"Id": "do2",
"StepType": "MyApp.DoSomething2, MyApp"
}
]]
}
Id: MyWhileStep
StepType: WorkflowCore.Primitives.While, WorkflowCore
NextStepId: "..."
Inputs:
Condition: "<<expression to evaluate>>"
Do:
- - Id: do1
StepType: MyApp.DoSomething1, MyApp
NextStepId: do2
- Id: do2
StepType: MyApp.DoSomething2, MyApp
Use the .If method to start an if condition
public class IfWorkflow : IWorkflow<MyData>
{
public void Build(IWorkflowBuilder<MyData> builder)
{
builder
.StartWith<SayHello>()
.If(data => data.Counter < 3).Do(then => then
.StartWith<PrintMessage>()
.Input(step => step.Message, data => "Value is less than 3")
)
.If(data => data.Counter < 5).Do(then => then
.StartWith<PrintMessage>()
.Input(step => step.Message, data => "Value is less than 5")
)
.Then<SayGoodbye>();
}
}
{
"Id": "MyIfStep",
"StepType": "WorkflowCore.Primitives.If, WorkflowCore",
"NextStepId": "...",
"Inputs": { "Condition": "<<expression to evaluate>>" },
"Do": [[
{
"Id": "do1",
"StepType": "MyApp.DoSomething1, MyApp",
"NextStepId": "do2"
},
{
"Id": "do2",
"StepType": "MyApp.DoSomething2, MyApp"
}
]]
}
Id: MyIfStep
StepType: WorkflowCore.Primitives.If, WorkflowCore
NextStepId: "..."
Inputs:
Condition: "<<expression to evaluate>>"
Do:
- - Id: do1
StepType: MyApp.DoSomething1, MyApp
NextStepId: do2
- Id: do2
StepType: MyApp.DoSomething2, MyApp
Use the .Parallel() method to branch parallel tasks
public class ParallelWorkflow : IWorkflow<MyData>
{
public string Id => "parallel-sample";
public int Version => 1;
public void Build(IWorkflowBuilder<MyData> builder)
{
builder
.StartWith<SayHello>()
.Parallel()
.Do(then =>
then.StartWith<Task1dot1>()
.Then<Task1dot2>()
.Do(then =>
then.StartWith<Task2dot1>()
.Then<Task2dot2>()
.Do(then =>
then.StartWith<Task3dot1>()
.Then<Task3dot2>()
.Join()
.Then<SayGoodbye>();
}
}
{
"Id": "MyParallelStep",
"StepType": "WorkflowCore.Primitives.Sequence, WorkflowCore",
"NextStepId": "...",
"Do": [
[
{
"Id": "Branch1.Step1",
"StepType": "MyApp.DoSomething1, MyApp",
"NextStepId": "Branch1.Step2"
},
{
"Id": "Branch1.Step2",
"StepType": "MyApp.DoSomething2, MyApp"
}
],
[
{
"Id": "Branch2.Step1",
"StepType": "MyApp.DoSomething1, MyApp",
"NextStepId": "Branch2.Step2"
},
{
"Id": "Branch2.Step2",
"StepType": "MyApp.DoSomething2, MyApp"
}
]
]
}
Id: MyParallelStep
StepType: WorkflowCore.Primitives.Sequence, WorkflowCore
NextStepId: "..."
Do:
- - Id: Branch1.Step1
StepType: MyApp.DoSomething1, MyApp
NextStepId: Branch1.Step2
- Id: Branch1.Step2
StepType: MyApp.DoSomething2, MyApp
- - Id: Branch2.Step1
StepType: MyApp.DoSomething1, MyApp
NextStepId: Branch2.Step2
- Id: Branch2.Step2
StepType: MyApp.DoSomething2, MyApp
Use .Schedule
to register a future set of steps to run asynchronously in the background within your workflow.
builder
.StartWith(context => Console.WriteLine("Hello"))
.Schedule(data => TimeSpan.FromSeconds(5)).Do(schedule => schedule
.StartWith(context => Console.WriteLine("Doing scheduled tasks"))
)
.Then(context => Console.WriteLine("Doing normal tasks"));
{
"Id": "MyScheduleStep",
"StepType": "WorkflowCore.Primitives.Schedule, WorkflowCore",
"Inputs": { "Interval": "<<expression to evaluate>>" },
"Do": [[
{
"Id": "do1",
"StepType": "MyApp.DoSomething1, MyApp",
"NextStepId": "do2"
},
{
"Id": "do2",
"StepType": "MyApp.DoSomething2, MyApp"
}
]]
}
Id: MyScheduleStep
StepType: WorkflowCore.Primitives.Schedule, WorkflowCore
Inputs:
Interval: "<<expression to evaluate>>"
Do:
- - Id: do1
StepType: MyApp.DoSomething1, MyApp
NextStepId: do2
- Id: do2
StepType: MyApp.DoSomething2, MyApp
The Delay
step will pause the current branch of your workflow for a specified period.
{
"Id": "MyDelayStep",
"StepType": "WorkflowCore.Primitives.Delay, WorkflowCore",
"NextStepId": "...",
"Inputs": { "Period": "<<expression to evaluate>>" }
}
Id: MyDelayStep
StepType: WorkflowCore.Primitives.Delay, WorkflowCore
NextStepId: "..."
Inputs:
Period: "<<expression to evaluate>>"
Use .Recur
to setup a set of recurring background steps within your workflow, until a certain condition is met
builder
.StartWith(context => Console.WriteLine("Hello"))
.Recur(data => TimeSpan.FromSeconds(5), data => data.Counter > 5).Do(recur => recur
.StartWith(context => Console.WriteLine("Doing recurring task"))
)
.Then(context => Console.WriteLine("Carry on"));
{
"Id": "MyScheduleStep",
"StepType": "WorkflowCore.Primitives.Recur, WorkflowCore",
"Inputs": {
"Interval": "<<expression to evaluate>>",
"StopCondition": "<<expression to evaluate>>"
},
"Do": [[
{
"Id": "do1",
"StepType": "MyApp.DoSomething1, MyApp",
"NextStepId": "do2"
},
{
"Id": "do2",
"StepType": "MyApp.DoSomething2, MyApp"
}
]]
}
Id: MyScheduleStep
StepType: WorkflowCore.Primitives.Recur, WorkflowCore
Inputs:
Interval: "<<expression to evaluate>>"
StopCondition: "<<expression to evaluate>>"
Do:
- - Id: do1
StepType: MyApp.DoSomething1, MyApp
NextStepId: do2
- Id: do2
StepType: MyApp.DoSomething2, MyApp