From 3814ea6ff47e20bd94280cb000bb4d716dad1ea6 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Wed, 24 Feb 2021 14:29:56 +0100 Subject: [PATCH] Update OutcomeResult to try a default connection via implicit "Done" outcome (#655) * Update OutcomeResult to try a default connection via implicit "Done" outcome * Add demo project for auto-connected activities --- Elsa.sln | 6 ++++ .../ActivityResults/OutcomeResult.cs | 8 +++-- .../Activities/SomeCustomActivity.cs | 17 ++++++++++ ...ples.AutoConnectNextActivityConsole.csproj | 18 +++++++++++ .../Program.cs | 32 +++++++++++++++++++ .../Workflows/Demoworkflow.cs | 17 ++++++++++ 6 files changed, 96 insertions(+), 2 deletions(-) create mode 100644 src/samples/console/Elsa.Samples.AutoConnectNextActivityConsole/Activities/SomeCustomActivity.cs create mode 100644 src/samples/console/Elsa.Samples.AutoConnectNextActivityConsole/Elsa.Samples.AutoConnectNextActivityConsole.csproj create mode 100644 src/samples/console/Elsa.Samples.AutoConnectNextActivityConsole/Program.cs create mode 100644 src/samples/console/Elsa.Samples.AutoConnectNextActivityConsole/Workflows/Demoworkflow.cs diff --git a/Elsa.sln b/Elsa.sln index e1f526d9c..3fedfc86d 100644 --- a/Elsa.sln +++ b/Elsa.sln @@ -232,6 +232,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Designer.Bindings.Blaz EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Samples.Timers.Quartz", "src\samples\worker\Elsa.Samples.Timers.Quartz\Elsa.Samples.Timers.Quartz.csproj", "{FE724143-B24C-43DA-BBF5-15431BCA6E27}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Samples.AutoConnectNextActivityConsole", "src\samples\console\Elsa.Samples.AutoConnectNextActivityConsole\Elsa.Samples.AutoConnectNextActivityConsole.csproj", "{DB42A8DA-06CA-4402-9C87-8F7F055AB37E}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "unit", "unit", "{F471267A-DA3A-48C7-8784-F8E4E46203A2}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.UnitTests", "test\unit\Elsa.UnitTests\Elsa.UnitTests.csproj", "{F822DE2F-A91D-416E-BF4A-A6C466C1BF0A}" @@ -558,6 +559,10 @@ Global {FE724143-B24C-43DA-BBF5-15431BCA6E27}.Debug|Any CPU.Build.0 = Debug|Any CPU {FE724143-B24C-43DA-BBF5-15431BCA6E27}.Release|Any CPU.ActiveCfg = Release|Any CPU {FE724143-B24C-43DA-BBF5-15431BCA6E27}.Release|Any CPU.Build.0 = Release|Any CPU + {DB42A8DA-06CA-4402-9C87-8F7F055AB37E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DB42A8DA-06CA-4402-9C87-8F7F055AB37E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DB42A8DA-06CA-4402-9C87-8F7F055AB37E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DB42A8DA-06CA-4402-9C87-8F7F055AB37E}.Release|Any CPU.Build.0 = Release|Any CPU {F822DE2F-A91D-416E-BF4A-A6C466C1BF0A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {F822DE2F-A91D-416E-BF4A-A6C466C1BF0A}.Debug|Any CPU.Build.0 = Debug|Any CPU {F822DE2F-A91D-416E-BF4A-A6C466C1BF0A}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -672,6 +677,7 @@ Global {5C005CC7-B5F2-49C3-8A8B-7640FCDBEE50} = {E42743A0-FBDD-4150-9D53-6000496D9B87} {45A06CA3-199B-4650-8880-30DDF2E38E19} = {8B6B40A8-DF21-4CD2-BABD-474B79D0C3AF} {FE724143-B24C-43DA-BBF5-15431BCA6E27} = {E42743A0-FBDD-4150-9D53-6000496D9B87} + {DB42A8DA-06CA-4402-9C87-8F7F055AB37E} = {FC9F520F-BA51-4AD2-BFEE-EF787798E734} {F471267A-DA3A-48C7-8784-F8E4E46203A2} = {AB1AE008-6FD6-414C-8E88-D735F42E1FA6} {F822DE2F-A91D-416E-BF4A-A6C466C1BF0A} = {F471267A-DA3A-48C7-8784-F8E4E46203A2} EndGlobalSection diff --git a/src/core/Elsa.Abstractions/ActivityResults/OutcomeResult.cs b/src/core/Elsa.Abstractions/ActivityResults/OutcomeResult.cs index 83805cb9e..7d3563701 100644 --- a/src/core/Elsa.Abstractions/ActivityResults/OutcomeResult.cs +++ b/src/core/Elsa.Abstractions/ActivityResults/OutcomeResult.cs @@ -27,6 +27,10 @@ namespace Elsa.ActivityResults var workflowExecutionContext = activityExecutionContext.WorkflowExecutionContext; var nextConnections = GetNextConnections(workflowExecutionContext, activityExecutionContext.ActivityBlueprint.Id, outcomes).ToList(); + // Always try if we got a "default" connection (from the current activity to the next activity via the default "Done" outcome). + if (!outcomes.Contains(OutcomeNames.Done) && !nextConnections.Any()) + nextConnections = GetNextConnections(workflowExecutionContext, activityExecutionContext.ActivityBlueprint.Id, new[] { OutcomeNames.Done }).ToList(); + var nextActivities = ( from connection in nextConnections @@ -36,9 +40,9 @@ namespace Elsa.ActivityResults ) .Distinct(); - foreach (var nextConnection in nextConnections) + foreach (var nextConnection in nextConnections) workflowExecutionContext.ExecutionLog.Add(nextConnection); - + workflowExecutionContext.ScheduleActivities(nextActivities, activityExecutionContext.Output); } diff --git a/src/samples/console/Elsa.Samples.AutoConnectNextActivityConsole/Activities/SomeCustomActivity.cs b/src/samples/console/Elsa.Samples.AutoConnectNextActivityConsole/Activities/SomeCustomActivity.cs new file mode 100644 index 000000000..078ae8335 --- /dev/null +++ b/src/samples/console/Elsa.Samples.AutoConnectNextActivityConsole/Activities/SomeCustomActivity.cs @@ -0,0 +1,17 @@ +using System; +using Elsa.ActivityResults; +using Elsa.Services; + +namespace Elsa.Samples.AutoConnectNextActivityConsole.Activities +{ + // The important aspect of this activity is that it returns an outcome other than "Done". + // Despite that, we still want to be able to execute any activities connected to this one if that connection is established with the "Done" outcome, because that's what the Workflow Builder API uses when connecting activities implicitly. + public class SomeCustomActivity : Activity + { + protected override IActivityExecutionResult OnExecute() + { + Console.WriteLine("Executing custom activity."); + return Outcome("Next"); + } + } +} \ No newline at end of file diff --git a/src/samples/console/Elsa.Samples.AutoConnectNextActivityConsole/Elsa.Samples.AutoConnectNextActivityConsole.csproj b/src/samples/console/Elsa.Samples.AutoConnectNextActivityConsole/Elsa.Samples.AutoConnectNextActivityConsole.csproj new file mode 100644 index 000000000..770fd14d0 --- /dev/null +++ b/src/samples/console/Elsa.Samples.AutoConnectNextActivityConsole/Elsa.Samples.AutoConnectNextActivityConsole.csproj @@ -0,0 +1,18 @@ + + + + Exe + net5.0 + false + + + + + + + + + + + + diff --git a/src/samples/console/Elsa.Samples.AutoConnectNextActivityConsole/Program.cs b/src/samples/console/Elsa.Samples.AutoConnectNextActivityConsole/Program.cs new file mode 100644 index 000000000..82cf046ee --- /dev/null +++ b/src/samples/console/Elsa.Samples.AutoConnectNextActivityConsole/Program.cs @@ -0,0 +1,32 @@ +using System.Threading.Tasks; +using Elsa.Samples.AutoConnectNextActivityConsole.Activities; +using Elsa.Samples.AutoConnectNextActivityConsole.Workflows; +using Elsa.Services; +using Microsoft.Extensions.DependencyInjection; + +namespace Elsa.Samples.AutoConnectNextActivityConsole +{ + class Program + { + private static async Task Main() + { + // Create a service container with Elsa services. + var services = new ServiceCollection() + .AddElsa(options => options + .AddConsoleActivities() + .AddActivity() + .AddWorkflow()) + .BuildServiceProvider(); + + // Run startup actions (not needed when registering Elsa with a Host). + var startupRunner = services.GetRequiredService(); + await startupRunner.StartupAsync(); + + // Get a workflow runner. + var workflowRunner = services.GetRequiredService(); + + // Run the workflow. + await workflowRunner.RunWorkflowAsync(); + } + } +} \ No newline at end of file diff --git a/src/samples/console/Elsa.Samples.AutoConnectNextActivityConsole/Workflows/Demoworkflow.cs b/src/samples/console/Elsa.Samples.AutoConnectNextActivityConsole/Workflows/Demoworkflow.cs new file mode 100644 index 000000000..b3dd62f4b --- /dev/null +++ b/src/samples/console/Elsa.Samples.AutoConnectNextActivityConsole/Workflows/Demoworkflow.cs @@ -0,0 +1,17 @@ +using Elsa.Activities.Console; +using Elsa.Builders; +using Elsa.Samples.AutoConnectNextActivityConsole.Activities; + +namespace Elsa.Samples.AutoConnectNextActivityConsole.Workflows +{ + /// + /// A basic workflow with just one WriteLine activity. + /// + public class Demoworkflow : IWorkflow + { + public void Build(IWorkflowBuilder builder) => builder + .WriteLine("Running demo workflow.") + .Then() // Even though this activity returns "Next", we still want to execute the next activity (which is connected via "Done"). + .WriteLine("Done!"); + } +} \ No newline at end of file