Back to Workflow Core

Workflow Core 1.4.0

ReleaseNotes/1.4.0.md

3.17.07.6 KB
Original Source

Workflow Core 1.4.0

  • Changed MongoDB persistence provider to store custom workflow data as BsonDocument instead of serialized JSON string
  • Changed .Output builder method value expression type, so inferred generic type is not taken from value expression
  • Added a feature that enables the loading of workflow definitions from JSON files

Loading workflow definitions from JSON

Simply grab the DefinitionLoader from the IoC container and call the .LoadDefinition method

c#
var loader = serviceProvider.GetService<IDefinitionLoader>();
loader.LoadDefinition(...);

Format of the JSON definition

Basics

The JSON format defines the steps within the workflow by referencing the fully qualified class names.

FieldDescription
IdWorkflow Definition ID
VersionWorkflow Definition Version
DataTypeFully qualified assembly class name of the custom data object
Steps[].IdStep ID (required unique key for each step)
Steps[].StepStepTypeFully qualified assembly class name of the step
Steps[].NextStepIdStep ID of the next step after this one completes
Steps[].InputsOptional Key/value pair of step inputs
Steps[].OutputsOptional Key/value pair of step outputs
Steps[].CancelConditionOptional cancel condition
json
{
  "Id": "HelloWorld",
  "Version": 1,
  "Steps": [
    {
      "Id": "Hello",
      "StepType": "MyApp.HelloWorld, MyApp",
      "NextStepId": "Bye"
    },        
    {
      "Id": "Bye",
      "StepType": "MyApp.GoodbyeWorld, MyApp"
    }
  ]
}

Inputs and Outputs

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 the Step class and the value would be an expression with both the data and context parameters at your disposal.
  • The Outputs collection, the key would match a property on the Data class and the value would be an expression with both the step as a parameter at your disposal.

Full details of the capabilities of expression language can be found here

json
{
  "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"
    }
  ]
}
json
{
  "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!\"" }
    }
  ]
}

WaitFor

The .WaitFor can be implemented using 3 inputs as follows

FieldDescription
CancelConditionOptional expression to specify a cancel condition
Inputs.EventNameExpression to specify the event name
Inputs.EventKeyExpression to specify the event key
Inputs.EffectiveDateOptional expression to specify the effective date
json
{
    "Id": "MyWaitStep",
    "StepType": "WorkflowCore.Primitives.WaitFor, WorkflowCore",
    "NextStepId": "...",
    "CancelCondition": "...",
    "Inputs": {
        "EventName": "\"Event1\"",
        "EventKey": "\"Key1\"",
        "EffectiveDate": "DateTime.Now"
    }
}

If

The .If can be implemented as follows

json
{
      "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"
          }
      ]]
}

While

The .While can be implemented as follows

json
{
      "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"
          }
      ]]
}

ForEach

The .ForEach can be implemented as follows

json
{
      "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"
          }
      ]]
}

Delay

The .Delay can be implemented as follows

json
{
      "Id": "MyDelayStep",
      "StepType": "WorkflowCore.Primitives.Delay, WorkflowCore",
      "NextStepId": "...",
      "Inputs": { "Period": "<<expression to evaluate>>" }
}

Parallel

The .Parallel can be implemented as follows

json
{
      "Id": "MyParallelStep",
      "StepType": "WorkflowCore.Primitives.Sequence, WorkflowCore",
      "NextStepId": "...",
      "Do": [
		[ /* Branch 1 */
		  {
		    "Id": "Branch1.Step1",
		    "StepType": "MyApp.DoSomething1, MyApp",
		    "NextStepId": "Branch1.Step2"
		  },
		  {
		    "Id": "Branch1.Step2",
		    "StepType": "MyApp.DoSomething2, MyApp"
		  }
		],			
		[ /* Branch 2 */
		  {
		    "Id": "Branch2.Step1",
		    "StepType": "MyApp.DoSomething1, MyApp",
		    "NextStepId": "Branch2.Step2"
		  },
		  {
		    "Id": "Branch2.Step2",
		    "StepType": "MyApp.DoSomething2, MyApp"
		  }
		]
	  ]
}

Schedule

The .Schedule can be implemented as follows

json
{
      "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"
          }
      ]]
}

Recur

The .Recur can be implemented as follows

json
{
      "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"
          }
      ]]
}