diff --git a/src/modules/Elsa.Expressions/Models/ExpressionExecutionContext.cs b/src/modules/Elsa.Expressions/Models/ExpressionExecutionContext.cs index 8c628cc64..200e6ba49 100644 --- a/src/modules/Elsa.Expressions/Models/ExpressionExecutionContext.cs +++ b/src/modules/Elsa.Expressions/Models/ExpressionExecutionContext.cs @@ -36,9 +36,13 @@ public class ExpressionExecutionContext public ExpressionExecutionContext? ParentContext { get; set; } public CancellationToken CancellationToken { get; } + public MemoryBlock GetBlock(Func blockReference) => GetBlock(blockReference()); public MemoryBlock GetBlock(MemoryBlockReference blockReference) => GetMemoryDatumInternal(blockReference) ?? throw new Exception($"Failed to retrieve memory block with reference {blockReference.Id}"); + public object Get(Func blockReference) => Get(blockReference()); public object Get(MemoryBlockReference blockReference) => GetBlock(blockReference).Value!; + public T Get(Func blockReference) => Get(blockReference()); public T Get(MemoryBlockReference blockReference) => (T)Get(blockReference); + public void Set(Func blockReference, object? value) => Set(blockReference(), value); public void Set(MemoryBlockReference blockReference, object? value) { diff --git a/src/modules/Elsa.JavaScript/Handlers/ConfigureJavaScriptEngineWithActivityOutput.cs b/src/modules/Elsa.JavaScript/Handlers/ConfigureJavaScriptEngineWithActivityOutput.cs index a4f77e5cb..7e5798351 100644 --- a/src/modules/Elsa.JavaScript/Handlers/ConfigureJavaScriptEngineWithActivityOutput.cs +++ b/src/modules/Elsa.JavaScript/Handlers/ConfigureJavaScriptEngineWithActivityOutput.cs @@ -33,7 +33,7 @@ public class ConfigureJavaScriptEngineWithActivityOutput : INotificationHandler< foreach (var property in properties) { - if (register.TryGetBlock(property.Value.MemoryBlockReference.Id, out var location)) + if (register.TryGetBlock(property.Value.MemoryBlockReference().Id, out var location)) jsActivity[property.Name] = location.Value; } diff --git a/src/modules/Elsa.Persistence.EntityFrameworkCore.SqlServer/Extensions/DbContextOptionsBuilderExtensions.cs b/src/modules/Elsa.Persistence.EntityFrameworkCore.SqlServer/Extensions/DbContextOptionsBuilderExtensions.cs index 4d8f41983..ddb881339 100644 --- a/src/modules/Elsa.Persistence.EntityFrameworkCore.SqlServer/Extensions/DbContextOptionsBuilderExtensions.cs +++ b/src/modules/Elsa.Persistence.EntityFrameworkCore.SqlServer/Extensions/DbContextOptionsBuilderExtensions.cs @@ -1,12 +1,18 @@ using Elsa.Persistence.EntityFrameworkCore.Common; using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; namespace Elsa.Persistence.EntityFrameworkCore.SqlServer.Extensions; public static class DbContextOptionsBuilderExtensions { - public static DbContextOptionsBuilder UseElsaSqlServer(this DbContextOptionsBuilder builder, string connectionString) => - builder.UseSqlServer(connectionString, db => db - .MigrationsAssembly(typeof(DbContextOptionsBuilderExtensions).Assembly.GetName().Name) - .MigrationsHistoryTable(ElsaDbContextBase.MigrationsHistoryTable, ElsaDbContextBase.ElsaSchema)); + public static DbContextOptionsBuilder UseElsaSqlServer(this DbContextOptionsBuilder builder, string connectionString, Action? configure = default) => + builder.UseSqlServer(connectionString, db => + { + db + .MigrationsAssembly(typeof(DbContextOptionsBuilderExtensions).Assembly.GetName().Name) + .MigrationsHistoryTable(ElsaDbContextBase.MigrationsHistoryTable, ElsaDbContextBase.ElsaSchema); + + configure?.Invoke(db); + }); } \ No newline at end of file diff --git a/src/modules/Elsa.Quartz/Elsa.Quartz.csproj b/src/modules/Elsa.Quartz/Elsa.Quartz.csproj index 1ecf992d2..e1d5fe46d 100644 --- a/src/modules/Elsa.Quartz/Elsa.Quartz.csproj +++ b/src/modules/Elsa.Quartz/Elsa.Quartz.csproj @@ -1,7 +1,7 @@ - - + + net6.0 diff --git a/src/modules/Elsa.Quartz/Extensions/ModuleExtensions.cs b/src/modules/Elsa.Quartz/Extensions/ModuleExtensions.cs new file mode 100644 index 000000000..23848fb73 --- /dev/null +++ b/src/modules/Elsa.Quartz/Extensions/ModuleExtensions.cs @@ -0,0 +1,14 @@ +using Elsa.Features.Extensions; +using Elsa.Features.Services; +using Elsa.Quartz.Features; + +namespace Elsa.Quartz.Extensions; + +public static class ModuleExtensions +{ + public static IModule UseQuartz(this IModule module, Action? configure = default) + { + module.Use(configure); + return module; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Quartz/Extensions/SchedulingFeatureExtensions.cs b/src/modules/Elsa.Quartz/Extensions/SchedulingFeatureExtensions.cs new file mode 100644 index 000000000..3d17be6cf --- /dev/null +++ b/src/modules/Elsa.Quartz/Extensions/SchedulingFeatureExtensions.cs @@ -0,0 +1,15 @@ +using Elsa.Features.Extensions; +using Elsa.Features.Services; +using Elsa.Quartz.Features; +using Elsa.Scheduling.Features; + +namespace Elsa.Quartz.Extensions; + +public static class SchedulingFeatureExtensions +{ + public static SchedulingFeature UseQuartzScheduling(this SchedulingFeature scheduling) + { + scheduling.Module.Use(); + return scheduling; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Telnyx/Activities/Dial.cs b/src/modules/Elsa.Telnyx/Activities/Dial.cs index 5ee291bbd..72c7ccbeb 100644 --- a/src/modules/Elsa.Telnyx/Activities/Dial.cs +++ b/src/modules/Elsa.Telnyx/Activities/Dial.cs @@ -1,4 +1,5 @@ -using Elsa.Telnyx.Client.Models; +using Elsa.Telnyx.Bookmarks; +using Elsa.Telnyx.Client.Models; using Elsa.Telnyx.Client.Services; using Elsa.Telnyx.Exceptions; using Elsa.Telnyx.Extensions; @@ -8,6 +9,7 @@ using Elsa.Workflows.Core; using Elsa.Workflows.Core.Activities.Flowchart.Attributes; using Elsa.Workflows.Core.Attributes; using Elsa.Workflows.Core.Models; +using Elsa.Workflows.Core.Services; using Elsa.Workflows.Management.Models; using Microsoft.Extensions.Options; @@ -17,8 +19,7 @@ namespace Elsa.Telnyx.Activities; /// Dial a number or SIP URI. /// [Activity(Constants.Namespace, "Dial a number or SIP URI.", Kind = ActivityKind.Task)] -[FlowNode("Answered", "Hangup")] -public class Dial : ActivityBase +public abstract class DialBase : ActivityBase { [Input(Description = "The DID or SIP URI to dial out and bridge to the given call.")] public Input? To { get; set; } = default!; @@ -33,7 +34,7 @@ public class Dial : ActivityBase [Input( Description = "Enables Answering Machine Detection.", UIHint = InputUIHints.Dropdown, - Options = new[] { "disabled", "detect", "detect_beep", "detect_words", "greeting_end" }, + Options = new[] { "disabled", "detect", "detect_beep", "detect_words", "greeting_end", "premium" }, DefaultValue = "disabled")] public Input? AnsweringMachineDetection { get; set; } = new("disabled"); @@ -71,16 +72,16 @@ public class Dial : ActivityBase } } - private async ValueTask HandleAnsweredAsync(ActivityExecutionContext context) => await context.CompleteActivityWithOutcomesAsync("Answered"); - - private async ValueTask HandleHangupAsync(ActivityExecutionContext context) => await context.CompleteActivityWithOutcomesAsync("Hangup"); - private void HandleMachineGreetingEnded(ActivityExecutionContext context, CallMachineGreetingEndedBase payload) { context.Set(MachineDetectionResult, payload.Result); - context.CreateBookmark(); + context.CreateBookmark(new WebhookEventBookmarkPayload(WebhookEventTypes.CallAnswered), ResumeAsync); + context.CreateBookmark(new WebhookEventBookmarkPayload(WebhookEventTypes.CallHangup), ResumeAsync); } + protected abstract ValueTask HandleAnsweredAsync(ActivityExecutionContext context); + protected abstract ValueTask HandleHangupAsync(ActivityExecutionContext context); + private async Task DialAsync(ActivityExecutionContext context) { var telnyxOptions = context.GetRequiredService>().Value; @@ -100,8 +101,33 @@ public class Dial : ActivityBase AnsweringMachineDetection.Get(context), ClientState: clientState ); - + var telnyxClient = context.GetRequiredService(); await telnyxClient.Calls.DialAsync(request, context.CancellationToken); } +} + +[FlowNode("Answered", "Hangup")] +public class FlowDial : DialBase +{ + protected override async ValueTask HandleAnsweredAsync(ActivityExecutionContext context) => await context.CompleteActivityWithOutcomesAsync("Answered"); + protected override async ValueTask HandleHangupAsync(ActivityExecutionContext context) => await context.CompleteActivityWithOutcomesAsync("Hangup"); +} + +public class Dial : DialBase +{ + [Port] public IActivity? Answered { get; set; } + [Port] public IActivity? Hangup { get; set; } + + protected override ValueTask HandleAnsweredAsync(ActivityExecutionContext context) + { + context.ScheduleActivity(Answered); + return ValueTask.CompletedTask; + } + + protected override ValueTask HandleHangupAsync(ActivityExecutionContext context) + { + context.ScheduleActivity(Hangup); + return ValueTask.CompletedTask; + } } \ No newline at end of file diff --git a/src/modules/Elsa.Telnyx/WebhookEventTypes.cs b/src/modules/Elsa.Telnyx/WebhookEventTypes.cs index 3bac5558c..ea2e47f4d 100644 --- a/src/modules/Elsa.Telnyx/WebhookEventTypes.cs +++ b/src/modules/Elsa.Telnyx/WebhookEventTypes.cs @@ -10,6 +10,7 @@ internal static class WebhookEventTypes public const string CallInitiated = "call.initiated"; public const string CallMachineGreetingEnded = "call.machine.greeting.ended"; public const string CallMachinePremiumGreetingEnded = "call.machine.premium.greeting.ended"; + public const string CallMachineDetectionEnded = "call.machine.detection.ended"; public const string CallMachinePremiumDetectionEnded = "call.machine.premium.detection.ended"; public const string CallPlaybackStarted = "call.playback.started"; public const string CallPlaybackEnded = "call.playback.ended"; diff --git a/src/modules/Elsa.Workflows.Core/Activities/ForEach.cs b/src/modules/Elsa.Workflows.Core/Activities/ForEach.cs index 15d1075ef..e7f7af128 100644 --- a/src/modules/Elsa.Workflows.Core/Activities/ForEach.cs +++ b/src/modules/Elsa.Workflows.Core/Activities/ForEach.cs @@ -95,8 +95,8 @@ public class ForEach : ForEach [Input] public new Input> Items { - get => new(base.Items.Expression, base.Items.MemoryBlockReference); - set => base.Items = new Input>(value.Expression, value.MemoryBlockReference); + get => new(base.Items.Expression, base.Items.MemoryBlockReference()); + set => base.Items = new Input>(value.Expression, value.MemoryBlockReference()); } public new Output CurrentValue diff --git a/src/modules/Elsa.Workflows.Core/Extensions/ActivityExecutionContextExtensions.cs b/src/modules/Elsa.Workflows.Core/Extensions/ActivityExecutionContextExtensions.cs index 63796e548..a95f2f824 100644 --- a/src/modules/Elsa.Workflows.Core/Extensions/ActivityExecutionContextExtensions.cs +++ b/src/modules/Elsa.Workflows.Core/Extensions/ActivityExecutionContextExtensions.cs @@ -64,7 +64,7 @@ public static class ActivityExecutionContextExtensions foreach (var input in assignedInputs) { - var memoryReference = input.MemoryBlockReference; + var memoryReference = input.MemoryBlockReference(); var value = await evaluator.EvaluateAsync(input, expressionExecutionContext); memoryReference.Set(context, value); } @@ -96,9 +96,9 @@ public static class ActivityExecutionContextExtensions var evaluator = context.GetRequiredService(); var expressionExecutionContext = context.ExpressionExecutionContext; - var locationReference = input.MemoryBlockReference; + var memoryBlockReference = input.MemoryBlockReference(); var value = await evaluator.EvaluateAsync(input, expressionExecutionContext); - locationReference.Set(context, value); + memoryBlockReference.Set(context, value); return input; } @@ -151,9 +151,9 @@ public static class ActivityExecutionContextExtensions public static async Task EvaluateAsync(this ActivityExecutionContext context, Input input) { var evaluator = context.GetRequiredService(); - var locationReference = input.MemoryBlockReference; + var memoryBlockReference = input.MemoryBlockReference(); var value = await evaluator.EvaluateAsync(input, context.ExpressionExecutionContext); - locationReference.Set(context, value); + memoryBlockReference.Set(context, value); return value; } diff --git a/src/modules/Elsa.Workflows.Core/Extensions/ExpressionExecutionContextExtensions.cs b/src/modules/Elsa.Workflows.Core/Extensions/ExpressionExecutionContextExtensions.cs index 47449f53f..24aee5a3a 100644 --- a/src/modules/Elsa.Workflows.Core/Extensions/ExpressionExecutionContextExtensions.cs +++ b/src/modules/Elsa.Workflows.Core/Extensions/ExpressionExecutionContextExtensions.cs @@ -45,6 +45,6 @@ public static class ExpressionExecutionContextExtensions public static void Set(this ExpressionExecutionContext context, Output? output, object? value) { - if(output != null) context.Set(output.MemoryBlockReference, value); + if(output != null) context.Set(output.MemoryBlockReference(), value); } } \ No newline at end of file diff --git a/src/modules/Elsa.Workflows.Core/Implementations/IdentityGraphService.cs b/src/modules/Elsa.Workflows.Core/Implementations/IdentityGraphService.cs index 53fa3dc12..55e36d143 100644 --- a/src/modules/Elsa.Workflows.Core/Implementations/IdentityGraphService.cs +++ b/src/modules/Elsa.Workflows.Core/Implementations/IdentityGraphService.cs @@ -36,24 +36,33 @@ public class IdentityGraphService : IIdentityGraphService private void AssignInputOutputs(IActivity activity) { var inputs = activity.GetInputs(); - var assignedInputs = inputs.Where(x => x.MemoryBlockReference != null! && x.MemoryBlockReference.Id == null!).ToList(); + + var assignedInputs = inputs.Where(x => + { + var memoryBlockReference = x.MemoryBlockReference(); + return memoryBlockReference.Id == null!; + }).ToList(); + var seed = 0; foreach (var input in assignedInputs) { - var locationReference = input.MemoryBlockReference; - + var locationReference = input.MemoryBlockReference(); locationReference.Id = $"{activity.Id}:input-{++seed}"; } seed = 0; var outputs = activity.GetOutputs(); - var assignedOutputs = outputs.Where(x => x.Value.MemoryBlockReference != null! && x.Value.MemoryBlockReference.Id == null!).ToList(); + + var assignedOutputs = outputs.Where(x => + { + var memoryBlockReference = x.Value.MemoryBlockReference(); + return memoryBlockReference != null! && memoryBlockReference.Id == null!; + }).ToList(); foreach (var output in assignedOutputs) { - var memoryReference = output.Value.MemoryBlockReference; - + var memoryReference = output.Value.MemoryBlockReference(); memoryReference.Id = $"{activity.Id}:output-{++seed}"; } } diff --git a/src/modules/Elsa.Workflows.Core/Models/ActivityExecutionContext.cs b/src/modules/Elsa.Workflows.Core/Models/ActivityExecutionContext.cs index 0e8693cff..ace31d25f 100644 --- a/src/modules/Elsa.Workflows.Core/Models/ActivityExecutionContext.cs +++ b/src/modules/Elsa.Workflows.Core/Models/ActivityExecutionContext.cs @@ -190,7 +190,7 @@ public class ActivityExecutionContext public T? GetService() where T : notnull => WorkflowExecutionContext.GetService(); public IEnumerable GetServices() where T : notnull => WorkflowExecutionContext.GetServices(); public object? GetService(Type serviceType) => WorkflowExecutionContext.GetService(serviceType); - public T? Get(Input? input) => input == null ? default : Get(input.MemoryBlockReference); + public T? Get(Input? input) => input == null ? default : Get(input.MemoryBlockReference()); public object? Get(MemoryBlockReference blockReference) { diff --git a/src/modules/Elsa.Workflows.Core/Models/Argument.cs b/src/modules/Elsa.Workflows.Core/Models/Argument.cs index 4b03a8290..f30221cd1 100644 --- a/src/modules/Elsa.Workflows.Core/Models/Argument.cs +++ b/src/modules/Elsa.Workflows.Core/Models/Argument.cs @@ -4,14 +4,18 @@ namespace Elsa.Workflows.Core.Models; public abstract class Argument { - protected Argument(){} - - protected Argument(MemoryBlockReference memoryBlockReference /*, Func? valueConverter = default*/) + protected Argument() { - MemoryBlockReference = memoryBlockReference; - //ValueConverter = valueConverter; } - public MemoryBlockReference MemoryBlockReference { get; set; } = default!; - //public Func? ValueConverter { get; set; } + protected Argument(MemoryBlockReference memoryBlockReference) : this(() => memoryBlockReference) + { + } + + protected Argument(Func memoryBlockReference) + { + MemoryBlockReference = memoryBlockReference; + } + + public Func MemoryBlockReference { get; set; } = default!; } \ No newline at end of file diff --git a/src/modules/Elsa.Workflows.Core/Models/Input.cs b/src/modules/Elsa.Workflows.Core/Models/Input.cs index e1d5d1ed3..b3eda3acc 100644 --- a/src/modules/Elsa.Workflows.Core/Models/Input.cs +++ b/src/modules/Elsa.Workflows.Core/Models/Input.cs @@ -43,7 +43,7 @@ public class Input : Input { } - public Input(Output output) : base(new OutputExpression(output), output.MemoryBlockReference, typeof(T)) + public Input(Output output) : base(new OutputExpression(output), output.MemoryBlockReference(), typeof(T)) { } diff --git a/src/modules/Elsa.Workflows.Core/Models/Output.cs b/src/modules/Elsa.Workflows.Core/Models/Output.cs index 48aed4534..4d32d7412 100644 --- a/src/modules/Elsa.Workflows.Core/Models/Output.cs +++ b/src/modules/Elsa.Workflows.Core/Models/Output.cs @@ -8,11 +8,13 @@ public class Output : Argument { } - public Output(MemoryBlockReference locationBlockReference) : base(locationBlockReference) + public Output(MemoryBlockReference memoryBlockReference) : base(memoryBlockReference) + { + } + + public Output(Func memoryBlockReference) : base(memoryBlockReference) { } - - //public ICollection Targets { get; } = new List(); } public class Output : Output @@ -21,7 +23,11 @@ public class Output : Output { } - public Output(MemoryBlockReference locationBlockReference) : base(locationBlockReference) + public Output(MemoryBlockReference memoryBlockReference) : base(memoryBlockReference) + { + } + + public Output(Func memoryBlockReference) : base(memoryBlockReference) { } } \ No newline at end of file diff --git a/src/modules/Elsa.Workflows.Management/Serialization/Converters/OutputJsonConverter.cs b/src/modules/Elsa.Workflows.Management/Serialization/Converters/OutputJsonConverter.cs index 02a0bf4e5..199b05623 100644 --- a/src/modules/Elsa.Workflows.Management/Serialization/Converters/OutputJsonConverter.cs +++ b/src/modules/Elsa.Workflows.Management/Serialization/Converters/OutputJsonConverter.cs @@ -46,7 +46,7 @@ public class OutputJsonConverter : JsonConverter?> Type = valueTypeAlias, MemoryReference = value == null ? null : new { - Id = value.MemoryBlockReference.Id + Id = value.MemoryBlockReference().Id } }; diff --git a/src/modules/Elsa.Workflows.Runtime/Implementations/TriggerIndexer.cs b/src/modules/Elsa.Workflows.Runtime/Implementations/TriggerIndexer.cs index b4d86dfe5..73c507505 100644 --- a/src/modules/Elsa.Workflows.Runtime/Implementations/TriggerIndexer.cs +++ b/src/modules/Elsa.Workflows.Runtime/Implementations/TriggerIndexer.cs @@ -165,7 +165,7 @@ public class TriggerIndexer : ITriggerIndexer // Evaluate activity inputs before requesting trigger data. foreach (var input in assignedInputs) { - var locationReference = input.MemoryBlockReference; + var locationReference = input.MemoryBlockReference(); try { diff --git a/src/modules/Elsa.Workflows.Runtime/Middleware/PersistWorkflowExecutionLogMiddleware.cs b/src/modules/Elsa.Workflows.Runtime/Middleware/PersistWorkflowExecutionLogMiddleware.cs index 058d9e6cf..0d092e0a9 100644 --- a/src/modules/Elsa.Workflows.Runtime/Middleware/PersistWorkflowExecutionLogMiddleware.cs +++ b/src/modules/Elsa.Workflows.Runtime/Middleware/PersistWorkflowExecutionLogMiddleware.cs @@ -7,7 +7,7 @@ using Elsa.Workflows.Runtime.Services; namespace Elsa.Workflows.Runtime.Middleware; /// -/// Takes care of persisting a workflow instance after workflow execution. +/// Takes care of persisting workflow execution log entries. /// public class PersistWorkflowExecutionLogMiddleware : WorkflowExecutionMiddleware { diff --git a/src/samples/console/Elsa.Samples.Composition/AskAge.cs b/src/samples/console/Elsa.Samples.Composition/Activities/AskAge.cs similarity index 77% rename from src/samples/console/Elsa.Samples.Composition/AskAge.cs rename to src/samples/console/Elsa.Samples.Composition/Activities/AskAge.cs index b2e894f1c..0909dca15 100644 --- a/src/samples/console/Elsa.Samples.Composition/AskAge.cs +++ b/src/samples/console/Elsa.Samples.Composition/Activities/AskAge.cs @@ -4,7 +4,6 @@ using Elsa.Workflows.Core.Models; public class AskAge : Composite { - private readonly WriteLine _prompt = new(); private readonly Variable _age = new(); public Input Prompt { get; set; } = new("Please tell me your age:"); @@ -16,17 +15,12 @@ public class AskAge : Composite Variables = { _age }, Activities = { - _prompt, + new WriteLine(context => Prompt.Get(context)), new ReadLine(_age) } }; } - protected override void ConfigureActivities(ActivityExecutionContext context) - { - _prompt.Text = Prompt; - } - protected override void OnCompleted(ActivityExecutionContext context, ActivityExecutionContext childContext) { var age = _age.Get(context); diff --git a/src/samples/console/Elsa.Samples.Composition/Activities/AskDetails.cs b/src/samples/console/Elsa.Samples.Composition/Activities/AskDetails.cs new file mode 100644 index 000000000..d9e85fcfe --- /dev/null +++ b/src/samples/console/Elsa.Samples.Composition/Activities/AskDetails.cs @@ -0,0 +1,42 @@ +using Elsa.Workflows.Core; +using Elsa.Workflows.Core.Activities; +using Elsa.Workflows.Core.Models; + +public class AskDetails : Composite +{ + private readonly Variable _name = new(); + private readonly Variable _age = new(); + + public Input NamePrompt { get; set; } = new("Please tell me your name:"); + public Input AgePrompt { get; set; } = new("Please tell me your age:"); + + public AskDetails() + { + Root = new Sequence + { + Variables = { _name, _age }, + Activities = + { + new AskName + { + Prompt = new Input(context => NamePrompt.Get(context)), + Result = new Output(() => _name) + }, + new AskAge + { + Prompt = new Input(context => AgePrompt.Get(context)), + Result = new Output(() => _age) + } + } + }; + } + + protected override void OnCompleted(ActivityExecutionContext context, ActivityExecutionContext childContext) + { + var name = _name.Get(context)!; + var age = _age.Get(context); + var person = new Person(name, age); + + context.Set(Result, person); + } +} \ No newline at end of file diff --git a/src/samples/console/Elsa.Samples.Composition/Activities/AskName.cs b/src/samples/console/Elsa.Samples.Composition/Activities/AskName.cs new file mode 100644 index 000000000..f9b11a11a --- /dev/null +++ b/src/samples/console/Elsa.Samples.Composition/Activities/AskName.cs @@ -0,0 +1,29 @@ +using Elsa.Workflows.Core; +using Elsa.Workflows.Core.Activities; +using Elsa.Workflows.Core.Models; + +public class AskName : Composite +{ + private readonly Variable _name = new(); + + public Input Prompt { get; set; } = new("Please tell me your name:"); + + public AskName() + { + Root = new Sequence + { + Variables = { _name }, + Activities = + { + new WriteLine(context => Prompt.Get(context)), + new ReadLine(_name) + } + }; + } + + protected override void OnCompleted(ActivityExecutionContext context, ActivityExecutionContext childContext) + { + var name = _name.Get(context); + context.Set(Result, name); + } +} \ No newline at end of file diff --git a/src/samples/console/Elsa.Samples.Composition/Models/Person.cs b/src/samples/console/Elsa.Samples.Composition/Models/Person.cs new file mode 100644 index 000000000..5a64edbe3 --- /dev/null +++ b/src/samples/console/Elsa.Samples.Composition/Models/Person.cs @@ -0,0 +1 @@ +public record Person(string Name, int Age); \ No newline at end of file diff --git a/src/samples/console/Elsa.Samples.Composition/Program.cs b/src/samples/console/Elsa.Samples.Composition/Program.cs index 054916832..cecdb22a7 100644 --- a/src/samples/console/Elsa.Samples.Composition/Program.cs +++ b/src/samples/console/Elsa.Samples.Composition/Program.cs @@ -14,20 +14,25 @@ services.AddElsa(); var serviceProvider = services.BuildServiceProvider(); // Declare a workflow variable for use in the workflow. -var ageVariable = new Variable(); +var personVariable = new Variable(); // Declare a workflow. var workflow = new Sequence { - Variables = { ageVariable }, + Variables = { personVariable }, Activities = { - new AskAge + new AskDetails() { - Prompt = new Input("What's your age?"), - Result = new Output(ageVariable) + NamePrompt = new Input("What's your name?"), + AgePrompt = new Input("What's your age?"), + Result = new Output(personVariable) }, - new WriteLine(context => $"The age you told me is: {ageVariable.Get(context)}") + new WriteLine(context => + { + var person = personVariable.Get(context)!; + return $"Your name is {person.Name} and you are {person.Age} years old."; + }) } };