Implemented activity outputs (#57)

This commit is contained in:
Sipke Schoorstra 2019-07-25 22:00:44 +02:00 committed by GitHub
parent cb5b2fa53c
commit 9070aa9070
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 142 additions and 15 deletions

View file

@ -65,6 +65,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Activities.UserTask",
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sample12", "samples\Sample12\Sample12.csproj", "{D0F68FBB-17C6-421E-B8AE-AAAFE111BF0B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sample13", "samples\Sample13\Sample13.csproj", "{006BDFC0-0203-4B09-8FBC-52642E22CA79}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -159,6 +161,10 @@ Global
{D0F68FBB-17C6-421E-B8AE-AAAFE111BF0B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D0F68FBB-17C6-421E-B8AE-AAAFE111BF0B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D0F68FBB-17C6-421E-B8AE-AAAFE111BF0B}.Release|Any CPU.Build.0 = Release|Any CPU
{006BDFC0-0203-4B09-8FBC-52642E22CA79}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{006BDFC0-0203-4B09-8FBC-52642E22CA79}.Debug|Any CPU.Build.0 = Debug|Any CPU
{006BDFC0-0203-4B09-8FBC-52642E22CA79}.Release|Any CPU.ActiveCfg = Release|Any CPU
{006BDFC0-0203-4B09-8FBC-52642E22CA79}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -189,6 +195,7 @@ Global
{0C3BB425-2FED-4ADF-8DBE-D68DF0CA5A41} = {5E5E1E84-DDBC-40D6-B891-0D563A15A44A}
{823F80B6-E241-43F7-83BD-29FBB58A77F9} = {B43B546E-23F3-46E8-ACB7-D04F05CDA180}
{D0F68FBB-17C6-421E-B8AE-AAAFE111BF0B} = {5E5E1E84-DDBC-40D6-B891-0D563A15A44A}
{006BDFC0-0203-4B09-8FBC-52642E22CA79} = {5E5E1E84-DDBC-40D6-B891-0D563A15A44A}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {8B0975FD-7050-48B0-88C5-48C33378E158}

View file

@ -0,0 +1,20 @@
using Elsa.Activities.Console.Activities;
using Elsa.Expressions;
using Elsa.Services;
using Elsa.Services.Models;
namespace Sample13
{
public class ActivityOutputWorkflow : IWorkflow
{
public void Build(IWorkflowBuilder builder)
{
builder
.StartWith<WriteLine>(x => x.TextExpression = new PlainTextExpression("Hi! What's your name?"))
.Then<ReadLine>(id: "name")
.Then<WriteLine>(x => x.TextExpression = new JavaScriptExpression<string>("`${name.output.text}, that's a great name! Now, what's your age?`"))
.Then<ReadLine>(id: "age")
.Then<WriteLine>(x => x.TextExpression = new JavaScriptExpression<string>("`I see! So you were born in ${getDateOfBirth(parseInt(age.output.text))}. What a year to be alive!`"));
}
}
}

View file

@ -0,0 +1,38 @@
using System;
using System.Threading.Tasks;
using Elsa.Activities.Console.Extensions;
using Elsa.Extensions;
using Elsa.Persistence.Memory;
using Elsa.Scripting;
using Elsa.Services;
using Microsoft.Extensions.DependencyInjection;
namespace Sample13
{
/// <summary>
/// A strongly-typed workflows program demonstrating scripting, and branching.
/// </summary>
class Program
{
static async Task Main()
{
// Setup a service collection.
var services = new ServiceCollection()
.AddWorkflows()
.AddMemoryWorkflowInstanceStore()
.AddConsoleActivities()
.AddSingleton<IScriptEngineConfigurator, ScriptEngineConfigurator>()
.BuildServiceProvider();
// Create a workflow.
var workflowFactory = services.GetRequiredService<IWorkflowFactory>();
var workflow = workflowFactory.CreateWorkflow<ActivityOutputWorkflow>();
// Invoke the workflow.
var invoker = services.GetService<IWorkflowInvoker>();
await invoker.InvokeAsync(workflow);
Console.ReadLine();
}
}
}

View file

@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.2</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\activities\Elsa.Activities.Console\Elsa.Activities.Console.csproj" />
<ProjectReference Include="..\..\src\core\Elsa.Core\Elsa.Core.csproj" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,26 @@
using System;
using Elsa.Scripting;
using Elsa.Services.Models;
using Jint;
using NodaTime;
namespace Sample13
{
/// <summary>
/// Add custom JavaScript functions that are easy to use in workflow expressions.
/// </summary>
public class ScriptEngineConfigurator : IScriptEngineConfigurator
{
private readonly IClock clock;
public ScriptEngineConfigurator(IClock clock)
{
this.clock = clock;
}
public void Configure(Engine engine, WorkflowExecutionContext workflowExecutionContext)
{
engine.SetValue("getDateOfBirth", (Func<string, object>) (age => clock.GetCurrentInstant().Minus(Duration.FromDays(int.Parse(age) * 365)).ToDateTimeUtc().Year));
}
}
}

View file

@ -4,6 +4,7 @@ using System.Threading.Tasks;
using Elsa.Results;
using Elsa.Services;
using Elsa.Services.Models;
using Newtonsoft.Json.Linq;
namespace Elsa.Activities.Console.Activities
{
@ -22,13 +23,13 @@ namespace Elsa.Activities.Console.Activities
{
this.input = input;
}
public string VariableName
public string VariableName
{
get => GetState<string>();
set => SetState(value);
}
protected override async Task<ActivityExecutionResult> OnExecuteAsync(WorkflowExecutionContext context, CancellationToken cancellationToken)
{
if (input == null)
@ -40,14 +41,18 @@ namespace Elsa.Activities.Console.Activities
protected override ActivityExecutionResult OnResume(WorkflowExecutionContext context)
{
var receivedInput = (string)context.Workflow.Input[VariableName];
var receivedInput = (string) context.Workflow.Input[VariableName];
return Execute(context, receivedInput);
}
private ActivityExecutionResult Execute(WorkflowExecutionContext workflowContext, string receivedInput)
{
workflowContext.CurrentScope.SetVariable(VariableName, receivedInput);
if (!string.IsNullOrWhiteSpace(VariableName))
workflowContext.CurrentScope.SetVariable(VariableName, receivedInput);
workflowContext.SetLastResult(receivedInput);
Output = JObject.FromObject(new { text = receivedInput });
return Outcome(OutcomeNames.Done);
}
}

View file

@ -17,4 +17,8 @@
<ProjectReference Include="..\..\core\Elsa.Core\Elsa.Core.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CSharp" Version="4.5.0" />
</ItemGroup>
</Project>

View file

@ -14,15 +14,9 @@ using NodaTime.Serialization.JsonNet;
namespace Elsa.Services
{
public abstract class ActivityBase : IActivity
{
private readonly JsonSerializer serializer;
protected ActivityBase()
{
serializer = new JsonSerializer().ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);
}
{
public JObject State { get; set; } = new JObject();
public JObject Output { get; set; } = new JObject();
public virtual string Type => GetType().Name;
public string Id { get; set; }

View file

@ -13,6 +13,11 @@ namespace Elsa.Services.Models
/// </summary>
JObject State { get; set; }
/// <summary>
/// Holds activity output.
/// </summary>
JObject Output { get; set; }
/// <summary>
/// The type name of this activity.
/// </summary>

View file

@ -16,6 +16,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Hosting.Server.Abstractions" Version="2.2.0" />
<PackageReference Include="Microsoft.CSharp" Version="4.5.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Localization" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.2.0" />

View file

@ -1,6 +1,8 @@
using System;
using System.Dynamic;
using Elsa.Services.Models;
using Jint;
using Newtonsoft.Json;
namespace Elsa.Scripting
{
@ -10,16 +12,28 @@ namespace Elsa.Scripting
{
var context = workflowExecutionContext;
var workflow = workflowExecutionContext.Workflow;
engine.SetValue("input", (Func<string, object>) (name => workflow.Input.GetVariable(name)));
engine.SetValue("variable", (Func<string, object>) (name => context.CurrentScope.GetVariable(name)));
engine.SetValue("lastResult", (Func<string, object>) (name => context.CurrentScope.LastResult));
engine.SetValue("correlationId", (Func<string, object>) (name => context.Workflow.CorrelationId));
foreach (var variable in workflowExecutionContext.CurrentScope.Variables)
{
engine.SetValue(variable.Key, variable.Value);
}
foreach (var activity in workflowExecutionContext.Workflow.Activities)
{
engine.SetValue(
activity.Id,
new
{
state = activity.State,
output = JsonConvert.DeserializeObject<ExpandoObject>(activity.Output.ToString())
}
);
}
}
}
}