Install the WorkflowCore.DSL
package from nuget and call AddWorkflowDSL
on your service collection.
Then grab the DefinitionLoader
from the IoC container and call the .LoadDefinition
method
using WorkflowCore.Interface;
...
var loader = serviceProvider.GetService<IDefinitionLoader>();
loader.LoadDefinition("<<json or yaml string here>>", Deserializers.Json);
Both the JSON and YAML formats follow a common DSL, where step types within the workflow are referenced by the fully qualified class names.
Built-in step types typically live in the WorklfowCore.Primitives
namespace.
Field | Description |
---|---|
Id | Workflow Definition ID |
Version | Workflow Definition Version |
DataType | Fully qualified assembly class name of the custom data object |
Steps[].Id | Step ID (required unique key for each step) |
Steps[].StepType | Fully qualified assembly class name of the step |
Steps[].NextStepId | Step ID of the next step after this one completes |
Steps[].Inputs | Optional Key/value pair of step inputs |
Steps[].Outputs | Optional Key/value pair of step outputs |
Steps[].CancelCondition | Optional cancel condition |
{
"Id": "HelloWorld",
"Version": 1,
"Steps": [
{
"Id": "Hello",
"StepType": "MyApp.HelloWorld, MyApp",
"NextStepId": "Bye"
},
{
"Id": "Bye",
"StepType": "MyApp.GoodbyeWorld, MyApp"
}
]
}
Id: HelloWorld
Version: 1
Steps:
- Id: Hello
StepType: MyApp.HelloWorld, MyApp
NextStepId: Bye
- Id: Bye
StepType: MyApp.GoodbyeWorld, MyApp
Inputs and outputs can be bound to a step as a key/value pair object,
- The
Inputs
collection, the key would match a property on theStep
class and the value would be an expression with both thedata
andcontext
parameters at your disposal. - The
Outputs
collection, the key would match a property on theData
class and the value would be an expression with both thestep
as a parameter at your disposal.
Full details of the capabilities of expression language can be found here
{
"Id": "AddWorkflow",
"Version": 1,
"DataType": "MyApp.MyDataClass, MyApp",
"Steps": [
{
"Id": "Hello",
"StepType": "MyApp.HelloWorld, MyApp",
"NextStepId": "Add"
},
{
"Id": "Add",
"StepType": "MyApp.AddNumbers, MyApp",
"NextStepId": "Bye",
"Inputs": {
"Value1": "data.Value1",
"Value2": "data.Value2"
},
"Outputs": {
"Answer": "step.Result"
}
},
{
"Id": "Bye",
"StepType": "MyApp.GoodbyeWorld, MyApp"
}
]
}
Id: AddWorkflow
Version: 1
DataType: MyApp.MyDataClass, MyApp
Steps:
- Id: Hello
StepType: MyApp.HelloWorld, MyApp
NextStepId: Add
- Id: Add
StepType: MyApp.AddNumbers, MyApp
NextStepId: Bye
Inputs:
Value1: data.Value1
Value2: data.Value2
Outputs:
Answer: step.Result
- Id: Bye
StepType: MyApp.GoodbyeWorld, MyApp
{
"Id": "AddWorkflow",
"Version": 1,
"DataType": "MyApp.MyDataClass, MyApp",
"Steps": [
{
"Id": "Hello",
"StepType": "MyApp.HelloWorld, MyApp",
"NextStepId": "Print"
},
{
"Id": "Print",
"StepType": "MyApp.PrintMessage, MyApp",
"Inputs": { "Message": "\"Hi there!\"" }
}
]
}
Id: AddWorkflow
Version: 1
DataType: MyApp.MyDataClass, MyApp
Steps:
- Id: Hello
StepType: MyApp.HelloWorld, MyApp
NextStepId: Print
- Id: Print
StepType: MyApp.PrintMessage, MyApp
Inputs:
Message: '"Hi there!"'
You can also pass object graphs to step inputs as opposed to just scalar values
"inputs":
{
"Body": {
"Value1": 1,
"Value2": 2
},
"Headers": {
"Content-Type": "application/json"
}
},
If you want to evaluate an expression for a given property of your object, simply prepend and @
and pass an expression string
"inputs":
{
"Body": {
"@Value1": "data.MyValue * 2",
"Value2": 5
},
"Headers": {
"Content-Type": "application/json"
}
},
If your step has an enum property, you can just pass the string representation of the enum value and it will be automatically converted.
You can access environment variables from within input expressions. usage:
environment["VARIABLE_NAME"]