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
This commit is contained in:
Sipke Schoorstra 2021-02-24 14:29:56 +01:00 committed by GitHub
parent b583c7f1a9
commit 3814ea6ff4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 96 additions and 2 deletions

View file

@ -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

View file

@ -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);
}

View file

@ -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");
}
}
}

View file

@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="5.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\core\Elsa\Elsa.csproj" />
<ProjectReference Include="..\..\..\persistence\Elsa.Persistence.YesSql\Elsa.Persistence.YesSql.csproj" />
</ItemGroup>
</Project>

View file

@ -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<SomeCustomActivity>()
.AddWorkflow<Demoworkflow>())
.BuildServiceProvider();
// Run startup actions (not needed when registering Elsa with a Host).
var startupRunner = services.GetRequiredService<IStartupRunner>();
await startupRunner.StartupAsync();
// Get a workflow runner.
var workflowRunner = services.GetRequiredService<IWorkflowRunner>();
// Run the workflow.
await workflowRunner.RunWorkflowAsync<Demoworkflow>();
}
}
}

View file

@ -0,0 +1,17 @@
using Elsa.Activities.Console;
using Elsa.Builders;
using Elsa.Samples.AutoConnectNextActivityConsole.Activities;
namespace Elsa.Samples.AutoConnectNextActivityConsole.Workflows
{
/// <summary>
/// A basic workflow with just one WriteLine activity.
/// </summary>
public class Demoworkflow : IWorkflow
{
public void Build(IWorkflowBuilder builder) => builder
.WriteLine("Running demo workflow.")
.Then<SomeCustomActivity>() // Even though this activity returns "Next", we still want to execute the next activity (which is connected via "Done").
.WriteLine("Done!");
}
}