elsa-workflows / elsa-workflows/elsa-core

Serializing workflows with Sequence as Root

Open
#4,519 1 comment 0 reactions 0 assignees View on GitHub
triaged
Dominant language
C#
Stars
7.9k
Forks
1.5k
Avg merge
15h 22m
Merged PRs (30d)
114

Description

Hey, we're currently evaluating Elsa v3 as a replacement for our existing windows workflow based engine.
So far we had some fun with the API, really impressive work, keep it up.
But we've hit a snag, probably easy enough to get it working but I thought I ask.

This is our workflow definition:

``` csharp
private static Workflow CreateWorkflow()
{
return new Workflow
{
Root = new Sequence
{
Activities =
{
new Start(),
new Sum()
{
A = CreateInput.FromWorkflowInput("A"),
B = CreateInput.FromWorkflowInput("B"),
},
new Sum()
{
A = CreateInput.FromLastActivityResult(),
B = CreateInput.FromWorkflowInput("C")
},
new SetOutput() {
OutputName = new("TotalSum") ,
OutputValue = CreateInput.FromLastActivityResult()
}
}
},
Inputs =
{
new() { Name = "A", Type = typeof(int) },
new() { Name = "B", Type = typeof(int) },
new() { Name = "C", Type = typeof(int) }
},
Outputs =
{
new() { Name = "TotalSum" }
}
};
}
```

We can run this workflow, passing it a few numbers as inputs, and we can get the output and validate it - e.g.:
``` csharp
[TestMethod]
public async Task Running_Elsa_Workflow_With_Inputs_And_Outputs()
{
Workflow workflow = CreateWorkflow();

// Create work flow runner
var services = new ServiceCollection();
services.AddElsa(elsa => elsa.AddActivity());
var serviceProvider = services.BuildServiceProvider();
await serviceProvider.PopulateRegistriesAsync();
var workflowRunner = serviceProvider.GetRequiredService();

// Run the workflow
var input = new Dictionary
{
["A"] = 9,
["B"] = 5,
["C"] = 1
};
var result = await workflowRunner.RunAsync(workflow, new RunWorkflowOptions(input: input));

// Assert result object is created
result.Should().NotBeNull();
result.WorkflowState.Incidents.Should().BeEmpty("because this flows should not throw exceptions");
result.WorkflowState.Status.Should().Be(WorkflowStatus.Finished, "because the flow should be completed");
result.WorkflowState.Output["TotalSum"].Should().Be(15, "because that is the sum of the inputs");
}
```

Questions:
- we're using a static helper class called CreateInput to make it easier to wire some things together when reading/writing results, inputs & outputs. **Not sure if there is a more idiomatic approach compared to this**? It's definitely worth documenting this part a little better, we had to dig a bit in the source code to figure it all out (I know it's a WIP).
- When we serialize this workflow definition to json **we loose the root sequence & child activities in the process** - so it becomes an 'empty' workflow essentially**. I'm assuming the json converter for sequences is missing?** I found a custom converter for the Flowchart, but wiring flowcharts programmatically is quite painful, sequences are nicer to work with. In any case we would like to be able to support both sequences and flowcharts as root activities.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.