Elsa 3.0 Help

Dispatching Child Workflows

When building workflows, you might want to reuse existing workflows as part of a larger workflow.

In Elsa, you can reuse workflows by dispatching them from other workflows. This is done using the Dispatch Workflow activity.

Dispatching a workflow

To dispatch a workflow, you need to add a Dispatch Workflow activity to your workflow. This activity has a Workflow Definition property that you can use to specify the definition ID of the workflow you want to dispatch.

When the DispatchWorkflow activity executes, it dispatches the selected workflow. The dispatched workflow will run in the background and the parent workflow will continue executing, unless the Wait For Completion property is set to true.

Trying it out

First, we will create a child workflow and then a parent workflow that will dispatch said child workflow for execution.

Create Child Workflow

  1. Create a new workflow called Child Workflow.

  2. Add a new WriteLine activity to the design surface.

  3. Configure the WriteLine activity's Text property with the text Hello from Child.

  4. Publish the workflow.

The result should look like this:

Child Workflow

Download Child Workflow

Create Child Workflow

  • Create a new workflow class called ChildWorkflow using the following code:

    Workflows/ChildWorkflow.cs

    using Elsa.Workflows; using Elsa.Workflows.Activities; using Elsa.Workflows.Contracts; using JetBrains.Annotations; namespace ElsaServer.Workflows; [UsedImplicitly] public class ChildWorkflow : WorkflowBase { protected override void Build(IWorkflowBuilder builder) { builder.Name = "Child Workflow"; builder.Root = new WriteLine("Hello from Child"); } }

Create Parent Workflow

  1. Create a new workflow called Parent Workflow.

  2. Add a new WriteLine activity to the design surface.

    Configure the WriteLine activity's Text property with the text Parent started.

  3. Add a new Dispatch Workflow activity with the following settings:

    Name

    Value

    Workflow Definition

    Child Workflow

    Wait For Completion

    true

  4. Add another WriteLine activity to the design surface and configure its Text property with the text Parent completed.

  5. Publish the workflow.

The result should look like this:

Parent Workflow

Download Parent Workflow

Create Parent Workflow

  • Create a new class called ParentWorkflow using the following code:

    Workflows/ParentWorkflow.cs

    using Elsa.Workflows; using Elsa.Workflows.Activities; using Elsa.Workflows.Contracts; using Elsa.Workflows.Runtime.Activities; using JetBrains.Annotations; namespace ElsaServer.Workflows; [UsedImplicitly] public class ParentWorkflow : WorkflowBase { protected override void Build(IWorkflowBuilder builder) { builder.Name = "Parent Workflow"; builder.Root = new Sequence { Activities = { new WriteLine("Parent started"), new DispatchWorkflow { WorkflowDefinitionId = new("ChildWorkflow"), WaitForCompletion = new(true) }, new WriteLine("Parent completed") } }; } }

Running the Parent Workflow

  1. Make sure the Elsa Server app is running.

  2. From Elsa Studio, open the Parent Workflow and click on the Start button.

  3. From the left menu, select the Workflows | Workflow Instances menu item and notice that two workflow instances have been created:

    1. Parent Workflow

    2. Child Workflow

Passing Input

You can pass input to the dispatched workflow. To do this, you need to set the Input property to a JSON object that contains the input you want to pass to the workflow.

When the workflow is executed, the Dispatch Workflow activity will dispatch the workflow with the specified input.

Trying it out

Let's see how we can pass input from the parent workflow to the child workflow using the Dispatch Workflow activity.

Update Child Workflow

  1. Open Child Workflow in Elsa Studio.

  2. From the Input/Output tab, add a new Input called Message of type String.

  3. Update the WriteLine activity's Text property with a dynamic expression:

    getMessage()
    return Inputs.Message;
    input.get("Message")
    {{ Input.Message }}
  4. Publish the changes.

Update Child Workflow

  • Update the ChildWorkflow class as follows:

    Workflows/ChildWorkflow.cs

    using Elsa.Workflows; using Elsa.Workflows.Activities; using Elsa.Workflows.Contracts; using Elsa.Workflows.Models; using JetBrains.Annotations; namespace ElsaServer.Workflows; [UsedImplicitly] public class ChildWorkflow : WorkflowBase { protected override void Build(IWorkflowBuilder builder) { builder.Name = "Child Workflow"; builder.Inputs.Add(new InputDefinition { Name = "Message", DisplayName = "Message", Description = "The message to write to the console.", Type = typeof(string) }); builder.Root = new WriteLine("Hello from Child"); } }

Update Parent Workflow

  1. Open Parent Workflow in Elsa Studio.

  2. Update the Dispatch Workflow activity's Input property with a dynamic expression:

    return { Message: "Hello from Parent" }
    return new { Message = "Hello from Parent" };
    { "Input": "Hello from Parent" }
  3. Publish the workflow.

Update Parent Workflow

  • Update the ParentWorkflow as follows:

    Workflows/ParentWorkflow.cs

    using Elsa.Workflows; using Elsa.Workflows.Activities; using Elsa.Workflows.Contracts; using Elsa.Workflows.Runtime.Activities; using JetBrains.Annotations; namespace ElsaServer.Workflows; [UsedImplicitly] public class ParentWorkflow : WorkflowBase { protected override void Build(IWorkflowBuilder builder) { builder.Name = "Parent Workflow"; builder.Root = new Sequence { Activities = { new WriteLine("Parent started"), new DispatchWorkflow { WorkflowDefinitionId = new("ChildWorkflow"), WaitForCompletion = new(true), Input = new(_ => new Dictionary<string, object> { ["Message"] = "Hello from Parent" }) }, new WriteLine("Parent completed") } }; } }

Running the Parent Workflow

  1. Make sure the Elsa Server app is running.

  2. From Elsa Studio, open the Parent Workflow and click on the Start button.

  3. Keep an eye out on the console to witness the changed output.

Receiving Output

You can also receive output from the dispatched workflow. To do this, you need to set the Wait For Completion property to true and set the Output property to a workflow variable of type Object or ObjectDictionary that contains the output you want to receive from the workflow.

You can also receive output from the dispatched workflow. To do this, you need to set the WaitForCompletion property to true and assign a workflow variable to the Output property of type IDictionary<string, object>.

Trying it Out

In this example, we will see how to update the child workflow to produce an output, that is then captured by the parent workflow's Dispatch Workflow activity.

Update Child Workflow

  1. Open Child Workflow in Elsa Studio.

  2. Add a new Output Definition called Response of type String

    Child Workflow Output
    Child Workflow Output Settings
  3. Add a new Set Output activity to the workflow and configure it as follows

    Property

    Value

    Output

    Response

    Value

    Hello from Child

    Make sure that you connect the Write Line activity to the Set Output activity.

    Set Output activity
  4. Publish the workflow.

Update Child Workflow

  • Update the ChildWorkflow class as follows:

    Workflows/ChildWorkflow.cs

    using Elsa.Extensions; using Elsa.Workflows; using Elsa.Workflows.Activities; using Elsa.Workflows.Contracts; using Elsa.Workflows.Management.Activities.SetOutput; using Elsa.Workflows.Models; using JetBrains.Annotations; namespace ElsaServer.Workflows; [UsedImplicitly] public class ChildWorkflow : WorkflowBase { protected override void Build(IWorkflowBuilder builder) { var messageInput = new InputDefinition { Name = "Message", DisplayName = "Message", Description = "The message to write to the console.", Type = typeof(string) }; var messageOutput = new OutputDefinition { Name = "Response", DisplayName = "Response", Description = "The message to provide as output.", Type = typeof(string) }; builder.Name = "Child Workflow"; builder.Inputs.Add(messageInput); builder.Outputs.Add(messageOutput); builder.Root = new Sequence { Activities = { new WriteLine(context => context.GetInput<string>("Message")), new SetOutput { OutputName = new(messageOutput.Name), OutputValue = new("Hello from Child") } } }; } }

Now that the child workflow produces an output, let's update the parent workflow to capture this output.

Update Parent Workflow

  1. Open Parent Workflow in Elsa Studio

  2. Add a new workflow variable called ChildOutput of type ObjectDictionary

    Add variable
    Add ChildOutput variable
  3. Select the Dispatch Workflow activity and select its Outputs tab

    From this tab, you will see the Result property that is displayed as a dropdown list.

    From this list, select the ChildOutput variable that we created in the previous step.

    Bind Result output to ChildOutput variable
  4. Select the existing Write Line activity and update its Text property with one of the following:

    return Variables.ChildOutput["Response"];
    getChildOutput().Response
    variables.ChildOutput.Response
    {{ Variables.ChildOutput["Response"] }}
  5. Publish the workflow

Update Parent Workflow

  • Update the ParentWorkflow class as follows:

    Workflows/ParentWorkflow.cs

    using Elsa.Workflows; using Elsa.Workflows.Activities; using Elsa.Workflows.Contracts; using Elsa.Workflows.Runtime.Activities; using JetBrains.Annotations; namespace ElsaServer.Workflows; [UsedImplicitly] public class ParentWorkflow : WorkflowBase { protected override void Build(IWorkflowBuilder builder) { var childOutput = builder.WithVariable<IDictionary<string, object>>(); builder.Name = "Parent Workflow"; builder.Root = new Sequence { Activities = { new WriteLine("Parent started"), new DispatchWorkflow { WorkflowDefinitionId = new("ChildWorkflow"), WaitForCompletion = new(true), Input = new(_ => new Dictionary<string, object> { ["Message"] = "Hello from Parent" }), Result = new(childOutput) }, new WriteLine(context => (string)childOutput.Get<IDictionary<string, object>>(context)!["Response"]) } }; } }

Running the Parent Workflow

  1. From the Parent Workflow open in the editor, click on the Start button.

  2. From the left menu, select the Workflows | Workflow Instances menu item and notice that two workflow instances have been created:

    Workflow Instances
  3. Inspect the Child Workflow instance to observe that it produced an output.

    Set Output activity
  4. Inspect the Parent Workflow instance to observe that its Dispatch Workflow activity received the output from the dispatched Child workflow.

    Dispatch Workflow activity output

    Also observe that the Write Line activity printed the expected result.

    Write Line activity printed the expected result

Summary

In this guide, we have seen how to dispatch child workflows using the Dispatch Workflow activity.

We have seen how to send input to and receive output from the child workflow.

Source Code

The completed code for this guide can be found here.

Last modified: 19 February 2024