From 344e95e70ecd751b8de0887bddd6eb9408249508 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Sat, 5 Jan 2019 12:50:08 +0100 Subject: [PATCH] Initial work on separating descriptors from drivers --- .../Descriptors/ReadLineDescriptor.cs | 23 +++++++++++ .../Descriptors/WriteLineDriver.cs | 26 ++++++++++++ .../ReadLineDriver.cs} | 17 ++------ .../WriteLineDriver.cs} | 19 +++------ .../Elsa.Activities.Console.csproj | 6 ++- .../Extensions/ServiceCollectionExtensions.cs | 17 ++++++-- .../HttpRequestTriggerDescriptor.cs | 21 ++++++++++ .../HttpRequestTriggerDriver.cs} | 15 ++----- .../Extensions/ServiceCollectionExtensions.cs | 13 ++++-- .../Descriptors/ForEachDescriptor.cs | 25 +++++++++++ .../Descriptors/IfElseDescriptor.cs | 21 ++++++++++ .../Descriptors/SetVariableDescriptor.cs | 20 +++++++++ .../Drivers/ForEachDriver.cs | 24 +++++++++++ .../Drivers/IfElseDriver.cs | 26 ++++++++++++ .../SetVariableDriver.cs} | 14 ++----- .../Elsa.Activities.Primitives.csproj | 2 +- .../Extensions/ServiceCollectionExtensions.cs | 20 ++++++--- .../Handlers/ForEachHandler.cs | 34 --------------- .../Handlers/IfElseHandler.cs | 36 ---------------- .../Elsa.Abstractions.csproj | 1 + .../Extensions/ServiceCollectionExtensions.cs | 19 +++++++++ .../Handlers/ActivityDescriptorBase.cs | 26 ++++++++++++ ...tyHandlerBase.cs => ActivityDriverBase.cs} | 18 +------- ...ivityHandler.cs => IActivityDescriptor.cs} | 17 +------- src/core/Elsa.Abstractions/IActivityDriver.cs | 30 ++++++++++++++ .../IActivityDriverRegistry.cs | 7 ++++ ...ivityProvider.cs => IActivityHarvester.cs} | 2 +- .../Elsa.Abstractions/IActivityInvoker.cs | 13 ++++++ .../Elsa.Abstractions/IWorkflowInvoker.cs | 1 + .../Models/ActivityDescriptor.cs | 3 -- .../Models/ActivityExecutionContext.cs | 4 +- .../Models/WorkflowExecutionContext.cs | 6 +-- src/core/Elsa.Core/ActivityDriverRegistry.cs | 20 +++++++++ src/core/Elsa.Core/ActivityInvoker.cs | 41 +++++++++++++++++++ src/core/Elsa.Core/ActivityLibrary.cs | 4 +- ...yProvider.cs => TypedActivityHarvester.cs} | 11 ++--- .../Extensions/ServiceCollectionExtensions.cs | 13 ++++-- .../{ActivityHandler.cs => ActivityDriver.cs} | 2 +- .../Handlers/UnknownActivityDescriptor.cs | 22 ++++++++++ .../Handlers/UnknownActivityDriver.cs | 14 +++++++ .../Handlers/UnknownActivityHandler.cs | 26 ------------ src/core/Elsa.Core/Results/HaltResult.cs | 3 +- src/core/Elsa.Core/WorkflowInvoker.cs | 21 +++++----- src/samples/SampleHost.Web/Startup.cs | 6 +-- .../Extensions/ServiceCollectionExtensions.cs | 10 ++--- .../{ReadLineDriver.cs => ReadLineDisplay.cs} | 2 +- ...WriteLineDriver.cs => WriteLineDisplay.cs} | 2 +- .../Elsa.Web.Activities.Console.csproj | 18 ++++---- .../Elsa.Web.Activities.Console/Startup.cs | 6 +-- ...Driver.cs => HttpRequestTriggerDisplay.cs} | 2 +- .../Elsa.Web.Activities.Http.csproj | 8 ++-- .../Elsa.Web.Activities.Http/Startup.cs | 4 +- .../{ForEachDriver.cs => ForEachDisplay.cs} | 2 +- .../{IfElseDriver.cs => IfElseDisplay.cs} | 2 +- ...ityDriver.cs => UnknownActivityDisplay.cs} | 2 +- .../Elsa.Web.Activities.Primitives.csproj | 8 ++-- .../Elsa.Web.Activities.Primitives/Startup.cs | 8 ++-- 57 files changed, 514 insertions(+), 269 deletions(-) create mode 100644 src/activities/Elsa.Activities.Console/Descriptors/ReadLineDescriptor.cs create mode 100644 src/activities/Elsa.Activities.Console/Descriptors/WriteLineDriver.cs rename src/activities/Elsa.Activities.Console/{Handlers/ReadLineHandler.cs => Drivers/ReadLineDriver.cs} (61%) rename src/activities/Elsa.Activities.Console/{Handlers/WriteLineHandler.cs => Drivers/WriteLineDriver.cs} (53%) create mode 100644 src/activities/Elsa.Activities.Http/Descriptors/HttpRequestTriggerDescriptor.cs rename src/activities/Elsa.Activities.Http/{Handlers/HttpRequestTriggerHandler.cs => Drivers/HttpRequestTriggerDriver.cs} (73%) create mode 100644 src/activities/Elsa.Activities.Primitives/Descriptors/ForEachDescriptor.cs create mode 100644 src/activities/Elsa.Activities.Primitives/Descriptors/IfElseDescriptor.cs create mode 100644 src/activities/Elsa.Activities.Primitives/Descriptors/SetVariableDescriptor.cs create mode 100644 src/activities/Elsa.Activities.Primitives/Drivers/ForEachDriver.cs create mode 100644 src/activities/Elsa.Activities.Primitives/Drivers/IfElseDriver.cs rename src/activities/Elsa.Activities.Primitives/{Handlers/SetVariableHandler.cs => Drivers/SetVariableDriver.cs} (56%) delete mode 100644 src/activities/Elsa.Activities.Primitives/Handlers/ForEachHandler.cs delete mode 100644 src/activities/Elsa.Activities.Primitives/Handlers/IfElseHandler.cs create mode 100644 src/core/Elsa.Abstractions/Extensions/ServiceCollectionExtensions.cs create mode 100644 src/core/Elsa.Abstractions/Handlers/ActivityDescriptorBase.cs rename src/core/Elsa.Abstractions/Handlers/{ActivityHandlerBase.cs => ActivityDriverBase.cs} (72%) rename src/core/Elsa.Abstractions/{IActivityHandler.cs => IActivityDescriptor.cs} (58%) create mode 100644 src/core/Elsa.Abstractions/IActivityDriver.cs create mode 100644 src/core/Elsa.Abstractions/IActivityDriverRegistry.cs rename src/core/Elsa.Abstractions/{IActivityProvider.cs => IActivityHarvester.cs} (85%) create mode 100644 src/core/Elsa.Abstractions/IActivityInvoker.cs create mode 100644 src/core/Elsa.Core/ActivityDriverRegistry.cs create mode 100644 src/core/Elsa.Core/ActivityInvoker.cs rename src/core/Elsa.Core/ActivityProviders/{TypedActivityProvider.cs => TypedActivityHarvester.cs} (70%) rename src/core/Elsa.Core/Handlers/{ActivityHandler.cs => ActivityDriver.cs} (90%) create mode 100644 src/core/Elsa.Core/Handlers/UnknownActivityDescriptor.cs create mode 100644 src/core/Elsa.Core/Handlers/UnknownActivityDriver.cs delete mode 100644 src/core/Elsa.Core/Handlers/UnknownActivityHandler.cs rename src/web/modules/Elsa.Web.Activities.Console/Drivers/{ReadLineDriver.cs => ReadLineDisplay.cs} (66%) rename src/web/modules/Elsa.Web.Activities.Console/Drivers/{WriteLineDriver.cs => WriteLineDisplay.cs} (87%) rename src/web/modules/Elsa.Web.Activities.Http/Drivers/{HttpRequestTriggerDriver.cs => HttpRequestTriggerDisplay.cs} (85%) rename src/web/modules/Elsa.Web.Activities.Primitives/Drivers/{ForEachDriver.cs => ForEachDisplay.cs} (67%) rename src/web/modules/Elsa.Web.Activities.Primitives/Drivers/{IfElseDriver.cs => IfElseDisplay.cs} (68%) rename src/web/modules/Elsa.Web.Activities.Primitives/Drivers/{UnknownActivityDriver.cs => UnknownActivityDisplay.cs} (58%) diff --git a/src/activities/Elsa.Activities.Console/Descriptors/ReadLineDescriptor.cs b/src/activities/Elsa.Activities.Console/Descriptors/ReadLineDescriptor.cs new file mode 100644 index 000000000..3565df591 --- /dev/null +++ b/src/activities/Elsa.Activities.Console/Descriptors/ReadLineDescriptor.cs @@ -0,0 +1,23 @@ +using Elsa.Activities.Console.Activities; +using Elsa.Activities.Console.Drivers; +using Elsa.Handlers; +using Microsoft.Extensions.Localization; + +namespace Elsa.Activities.Console.Descriptors +{ + public class ReadLineDescriptor : ActivityDescriptorBase + { + public ReadLineDescriptor(IStringLocalizer localizer) + { + T = localizer; + } + + private IStringLocalizer T { get; } + + protected override LocalizedString GetEndpoint() => T["Done"]; + + public override LocalizedString Category => T["Console"]; + public override LocalizedString DisplayText => T["Read Line"]; + public override LocalizedString Description => T["Read a line from the console"]; + } +} \ No newline at end of file diff --git a/src/activities/Elsa.Activities.Console/Descriptors/WriteLineDriver.cs b/src/activities/Elsa.Activities.Console/Descriptors/WriteLineDriver.cs new file mode 100644 index 000000000..27dd85cc2 --- /dev/null +++ b/src/activities/Elsa.Activities.Console/Descriptors/WriteLineDriver.cs @@ -0,0 +1,26 @@ +using Elsa.Activities.Console.Activities; +using Elsa.Activities.Console.Drivers; +using Elsa.Handlers; +using Microsoft.Extensions.Localization; + +namespace Elsa.Activities.Console.Descriptors +{ + /// + /// Writes a text string to the specified stream. + /// + public class WriteLineDescriptor : ActivityDescriptorBase + { + public WriteLineDescriptor(IStringLocalizer localizer) + { + T = localizer; + } + + private IStringLocalizer T { get; } + + protected override LocalizedString GetEndpoint() => T["Done"]; + + public override LocalizedString Category => T["Console"]; + public override LocalizedString DisplayText => T["Write Line"]; + public override LocalizedString Description => T["Write a line to the console"]; + } +} diff --git a/src/activities/Elsa.Activities.Console/Handlers/ReadLineHandler.cs b/src/activities/Elsa.Activities.Console/Drivers/ReadLineDriver.cs similarity index 61% rename from src/activities/Elsa.Activities.Console/Handlers/ReadLineHandler.cs rename to src/activities/Elsa.Activities.Console/Drivers/ReadLineDriver.cs index ec384414d..0e24da34b 100644 --- a/src/activities/Elsa.Activities.Console/Handlers/ReadLineHandler.cs +++ b/src/activities/Elsa.Activities.Console/Drivers/ReadLineDriver.cs @@ -7,30 +7,21 @@ using Elsa.Models; using Elsa.Results; using Microsoft.Extensions.Localization; -namespace Elsa.Activities.Console.Handlers +namespace Elsa.Activities.Console.Drivers { - public class ReadLineHandler : ActivityHandler + public class ReadLineDriver : ActivityDriver { private readonly TextReader input; - public ReadLineHandler(IStringLocalizer localizer) + public ReadLineDriver() { - T = localizer; } - public ReadLineHandler(IStringLocalizer localizer, TextReader input) : this(localizer) + public ReadLineDriver(TextReader input) : this() { this.input = input; } - private IStringLocalizer T { get; } - - protected override LocalizedString GetEndpoint() => T["Done"]; - - public override LocalizedString Category => T["Console"]; - public override LocalizedString DisplayText => T["Read Line"]; - public override LocalizedString Description => T["Read a line from the console"]; - protected override async Task OnExecuteAsync(ReadLine activity, WorkflowExecutionContext workflowContext, CancellationToken cancellationToken) { if (input == null) diff --git a/src/activities/Elsa.Activities.Console/Handlers/WriteLineHandler.cs b/src/activities/Elsa.Activities.Console/Drivers/WriteLineDriver.cs similarity index 53% rename from src/activities/Elsa.Activities.Console/Handlers/WriteLineHandler.cs rename to src/activities/Elsa.Activities.Console/Drivers/WriteLineDriver.cs index 7a806e6af..a54182a83 100644 --- a/src/activities/Elsa.Activities.Console/Handlers/WriteLineHandler.cs +++ b/src/activities/Elsa.Activities.Console/Drivers/WriteLineDriver.cs @@ -7,36 +7,27 @@ using Elsa.Models; using Elsa.Results; using Microsoft.Extensions.Localization; -namespace Elsa.Activities.Console.Handlers +namespace Elsa.Activities.Console.Drivers { /// /// Writes a text string to the specified stream. /// - public class WriteLineHandler : ActivityHandler + public class WriteLineDriver : ActivityDriver { private readonly IWorkflowExpressionEvaluator evaluator; private readonly TextWriter output; - public WriteLineHandler(IStringLocalizer localizer, IWorkflowExpressionEvaluator evaluator) - : this(localizer, evaluator, System.Console.Out) + public WriteLineDriver(IWorkflowExpressionEvaluator evaluator) + : this(evaluator, System.Console.Out) { } - public WriteLineHandler(IStringLocalizer localizer, IWorkflowExpressionEvaluator evaluator, TextWriter output) + public WriteLineDriver(IWorkflowExpressionEvaluator evaluator, TextWriter output) { - T = localizer; this.evaluator = evaluator; this.output = output; } - private IStringLocalizer T { get; } - - protected override LocalizedString GetEndpoint() => T["Done"]; - - public override LocalizedString Category => T["Console"]; - public override LocalizedString DisplayText => T["Write Line"]; - public override LocalizedString Description => T["Write a line to the console"]; - protected override async Task OnExecuteAsync(WriteLine activity, WorkflowExecutionContext workflowContext, CancellationToken cancellationToken) { var text = await evaluator.EvaluateAsync(activity.TextExpression, workflowContext, cancellationToken); diff --git a/src/activities/Elsa.Activities.Console/Elsa.Activities.Console.csproj b/src/activities/Elsa.Activities.Console/Elsa.Activities.Console.csproj index 595033afa..95647353d 100644 --- a/src/activities/Elsa.Activities.Console/Elsa.Activities.Console.csproj +++ b/src/activities/Elsa.Activities.Console/Elsa.Activities.Console.csproj @@ -13,7 +13,11 @@ - + + + + + diff --git a/src/activities/Elsa.Activities.Console/Extensions/ServiceCollectionExtensions.cs b/src/activities/Elsa.Activities.Console/Extensions/ServiceCollectionExtensions.cs index 080845d84..5b4665e59 100644 --- a/src/activities/Elsa.Activities.Console/Extensions/ServiceCollectionExtensions.cs +++ b/src/activities/Elsa.Activities.Console/Extensions/ServiceCollectionExtensions.cs @@ -1,15 +1,24 @@ -using Elsa.Activities.Console.Handlers; +using Elsa.Activities.Console.Descriptors; +using Elsa.Activities.Console.Drivers; +using Elsa.Extensions; using Microsoft.Extensions.DependencyInjection; namespace Elsa.Activities.Console.Extensions { public static class ServiceCollectionExtensions { - public static IServiceCollection AddWorkflowsConsole(this IServiceCollection services) + public static IServiceCollection AddConsoleDescriptors(this IServiceCollection services) { return services - .AddSingleton() - .AddSingleton(); + .AddActivityDescriptor() + .AddActivityDescriptor(); + } + + public static IServiceCollection AddConsoleDrivers(this IServiceCollection services) + { + return services + .AddActivityDriver() + .AddActivityDriver(); } } } \ No newline at end of file diff --git a/src/activities/Elsa.Activities.Http/Descriptors/HttpRequestTriggerDescriptor.cs b/src/activities/Elsa.Activities.Http/Descriptors/HttpRequestTriggerDescriptor.cs new file mode 100644 index 000000000..41aedfebc --- /dev/null +++ b/src/activities/Elsa.Activities.Http/Descriptors/HttpRequestTriggerDescriptor.cs @@ -0,0 +1,21 @@ +using Elsa.Activities.Http.Activities; +using Elsa.Handlers; +using Microsoft.Extensions.Localization; + +namespace Elsa.Activities.Http.Descriptors +{ + public class HttpRequestTriggerDescriptor : ActivityDescriptorBase + { + public HttpRequestTriggerDescriptor(IStringLocalizer localizer) + { + T = localizer; + } + + public IStringLocalizer T { get; } + public override bool IsTrigger => true; + public override LocalizedString Category => T["HTTP"]; + public override LocalizedString DisplayText => T["HTTP Request"]; + public override LocalizedString Description => T["Triggers when an incoming HTTP request is received."]; + protected override LocalizedString GetEndpoint() => T["Done"]; + } +} \ No newline at end of file diff --git a/src/activities/Elsa.Activities.Http/Handlers/HttpRequestTriggerHandler.cs b/src/activities/Elsa.Activities.Http/Drivers/HttpRequestTriggerDriver.cs similarity index 73% rename from src/activities/Elsa.Activities.Http/Handlers/HttpRequestTriggerHandler.cs rename to src/activities/Elsa.Activities.Http/Drivers/HttpRequestTriggerDriver.cs index 256a0bf4c..11e70e121 100644 --- a/src/activities/Elsa.Activities.Http/Handlers/HttpRequestTriggerHandler.cs +++ b/src/activities/Elsa.Activities.Http/Drivers/HttpRequestTriggerDriver.cs @@ -11,30 +11,21 @@ using Elsa.Results; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Localization; -namespace Elsa.Activities.Http.Handlers +namespace Elsa.Activities.Http.Drivers { - public class HttpRequestTriggerHandler : ActivityHandler + public class HttpRequestTriggerDriver : ActivityDriver { private readonly IHttpContextAccessor httpContextAccessor; private readonly IWorkflowExpressionEvaluator expressionEvaluator; - public HttpRequestTriggerHandler( - IStringLocalizer localizer, + public HttpRequestTriggerDriver( IHttpContextAccessor httpContextAccessor, IWorkflowExpressionEvaluator expressionEvaluator) { - T = localizer; this.httpContextAccessor = httpContextAccessor; this.expressionEvaluator = expressionEvaluator; } - public IStringLocalizer T { get; } - public override bool IsTrigger => true; - public override LocalizedString Category => T["HTTP"]; - public override LocalizedString DisplayText => T["HTTP Request"]; - public override LocalizedString Description => T["Triggers when an incoming HTTP request is received."]; - protected override LocalizedString GetEndpoint() => T["Done"]; - protected override async Task OnExecuteAsync(HttpRequestTrigger activity, WorkflowExecutionContext workflowContext, CancellationToken cancellationToken) { var request = httpContextAccessor.HttpContext.Request; diff --git a/src/activities/Elsa.Activities.Http/Extensions/ServiceCollectionExtensions.cs b/src/activities/Elsa.Activities.Http/Extensions/ServiceCollectionExtensions.cs index df59eeef8..1c0da6a6e 100644 --- a/src/activities/Elsa.Activities.Http/Extensions/ServiceCollectionExtensions.cs +++ b/src/activities/Elsa.Activities.Http/Extensions/ServiceCollectionExtensions.cs @@ -1,7 +1,9 @@ -using Elsa.Activities.Http.Handlers; +using Elsa.Activities.Http.Descriptors; +using Elsa.Activities.Http.Drivers; using Elsa.Activities.Http.Initialization; using Elsa.Activities.Http.Services; using Elsa.Activities.Http.Services.Implementations; +using Elsa.Extensions; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; @@ -10,12 +12,17 @@ namespace Elsa.Activities.Http.Extensions { public static class ServiceCollectionExtensions { - public static IServiceCollection AddWorkflowsHttp(this IServiceCollection services) + public static IServiceCollection AddHttpDescriptors(this IServiceCollection services) + { + return services.AddActivityDescriptor(); + } + + public static IServiceCollection AddHttpDrivers(this IServiceCollection services) { services .AddSingleton() .AddAsyncInitializer() - .AddSingleton(); + .AddActivityDriver(); services.TryAddSingleton(); return services; diff --git a/src/activities/Elsa.Activities.Primitives/Descriptors/ForEachDescriptor.cs b/src/activities/Elsa.Activities.Primitives/Descriptors/ForEachDescriptor.cs new file mode 100644 index 000000000..ee858e000 --- /dev/null +++ b/src/activities/Elsa.Activities.Primitives/Descriptors/ForEachDescriptor.cs @@ -0,0 +1,25 @@ +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Elsa.Activities.Primitives.Activities; +using Elsa.Handlers; +using Elsa.Models; +using Elsa.Results; +using Microsoft.Extensions.Localization; + +namespace Elsa.Activities.Primitives.Descriptors +{ + public class ForEachDescriptor : ActivityDescriptorBase + { + public ForEachDescriptor(IStringLocalizer localizer) + { + T = localizer; + } + + public IStringLocalizer T { get; } + public override LocalizedString Category => T["Control Flow"]; + public override LocalizedString DisplayText => T["For Each"]; + public override LocalizedString Description => T["Iterate over a list of items."]; + protected override IEnumerable GetEndpoints() => Endpoints(T["Next"], T["Done"]); + } +} \ No newline at end of file diff --git a/src/activities/Elsa.Activities.Primitives/Descriptors/IfElseDescriptor.cs b/src/activities/Elsa.Activities.Primitives/Descriptors/IfElseDescriptor.cs new file mode 100644 index 000000000..571a7c232 --- /dev/null +++ b/src/activities/Elsa.Activities.Primitives/Descriptors/IfElseDescriptor.cs @@ -0,0 +1,21 @@ +using System.Collections.Generic; +using Elsa.Activities.Primitives.Activities; +using Elsa.Handlers; +using Microsoft.Extensions.Localization; + +namespace Elsa.Activities.Primitives.Descriptors +{ + public class IfElseDescriptor : ActivityDescriptorBase + { + public IfElseDescriptor(IStringLocalizer localizer) + { + T = localizer; + } + + public IStringLocalizer T { get; } + public override LocalizedString Category => T["Control Flow"]; + public override LocalizedString DisplayText => T["If/Else Branch"]; + public override LocalizedString Description => T["Evaluate a boolean condition and continues execution based on the outcome."]; + protected override IEnumerable GetEndpoints() => Endpoints(T["True"], T["False"]); + } +} \ No newline at end of file diff --git a/src/activities/Elsa.Activities.Primitives/Descriptors/SetVariableDescriptor.cs b/src/activities/Elsa.Activities.Primitives/Descriptors/SetVariableDescriptor.cs new file mode 100644 index 000000000..1dd2fa296 --- /dev/null +++ b/src/activities/Elsa.Activities.Primitives/Descriptors/SetVariableDescriptor.cs @@ -0,0 +1,20 @@ +using Elsa.Activities.Primitives.Activities; +using Elsa.Handlers; +using Microsoft.Extensions.Localization; + +namespace Elsa.Activities.Primitives.Descriptors +{ + public class SetVariableDescriptor : ActivityDescriptorBase + { + public SetVariableDescriptor(IStringLocalizer localizer) + { + T = localizer; + } + + public IStringLocalizer T { get; } + public override LocalizedString Category => T["Primitives"]; + public override LocalizedString DisplayText => T["Set Variable"]; + public override LocalizedString Description => T["Set a custom variable on the workflow."]; + protected override LocalizedString GetEndpoint() => T["Done"]; + } +} \ No newline at end of file diff --git a/src/activities/Elsa.Activities.Primitives/Drivers/ForEachDriver.cs b/src/activities/Elsa.Activities.Primitives/Drivers/ForEachDriver.cs new file mode 100644 index 000000000..497a758df --- /dev/null +++ b/src/activities/Elsa.Activities.Primitives/Drivers/ForEachDriver.cs @@ -0,0 +1,24 @@ +using System.Threading; +using System.Threading.Tasks; +using Elsa.Activities.Primitives.Activities; +using Elsa.Handlers; +using Elsa.Models; +using Elsa.Results; + +namespace Elsa.Activities.Primitives.Drivers +{ + public class ForEachDriver : ActivityDriver + { + private readonly IWorkflowExpressionEvaluator expressionEvaluator; + + public ForEachDriver(IWorkflowExpressionEvaluator expressionEvaluator) + { + this.expressionEvaluator = expressionEvaluator; + } + + protected override async Task OnExecuteAsync(ForEach activity, WorkflowExecutionContext workflowContext, CancellationToken cancellationToken) + { + return TriggerEndpoint("Done"); + } + } +} \ No newline at end of file diff --git a/src/activities/Elsa.Activities.Primitives/Drivers/IfElseDriver.cs b/src/activities/Elsa.Activities.Primitives/Drivers/IfElseDriver.cs new file mode 100644 index 000000000..ba9822909 --- /dev/null +++ b/src/activities/Elsa.Activities.Primitives/Drivers/IfElseDriver.cs @@ -0,0 +1,26 @@ +using System.Threading; +using System.Threading.Tasks; +using Elsa.Activities.Primitives.Activities; +using Elsa.Handlers; +using Elsa.Models; +using Elsa.Results; + +namespace Elsa.Activities.Primitives.Drivers +{ + public class IfElseDriver : ActivityDriver + { + private readonly IWorkflowExpressionEvaluator expressionEvaluator; + + public IfElseDriver(IWorkflowExpressionEvaluator expressionEvaluator) + { + this.expressionEvaluator = expressionEvaluator; + } + + protected override async Task OnExecuteAsync(IfElse activity, WorkflowExecutionContext workflowContext, CancellationToken cancellationToken) + { + var result = await expressionEvaluator.EvaluateAsync(activity.ConditionExpression, workflowContext, cancellationToken); + return TriggerEndpoint(result ? "True" : "False"); + } + + } +} \ No newline at end of file diff --git a/src/activities/Elsa.Activities.Primitives/Handlers/SetVariableHandler.cs b/src/activities/Elsa.Activities.Primitives/Drivers/SetVariableDriver.cs similarity index 56% rename from src/activities/Elsa.Activities.Primitives/Handlers/SetVariableHandler.cs rename to src/activities/Elsa.Activities.Primitives/Drivers/SetVariableDriver.cs index 893441dc2..011389763 100644 --- a/src/activities/Elsa.Activities.Primitives/Handlers/SetVariableHandler.cs +++ b/src/activities/Elsa.Activities.Primitives/Drivers/SetVariableDriver.cs @@ -6,25 +6,17 @@ using Elsa.Models; using Elsa.Results; using Microsoft.Extensions.Localization; -namespace Elsa.Activities.Primitives.Handlers +namespace Elsa.Activities.Primitives.Drivers { - public class SetVariableHandler : ActivityHandler + public class SetVariableDriver : ActivityDriver { private readonly IWorkflowExpressionEvaluator expressionEvaluator; - public SetVariableHandler(IStringLocalizer localizer, IWorkflowExpressionEvaluator expressionEvaluator) + public SetVariableDriver(IWorkflowExpressionEvaluator expressionEvaluator) { - T = localizer; this.expressionEvaluator = expressionEvaluator; } - public override LocalizedString Category => T["Primitives"]; - public override LocalizedString DisplayText => T["Set Variable"]; - public override LocalizedString Description => T["Set a custom variable on the workflow."]; - public IStringLocalizer T { get; } - - protected override LocalizedString GetEndpoint() => T["Done"]; - protected override async Task OnExecuteAsync(SetVariable activity, WorkflowExecutionContext workflowContext, CancellationToken cancellationToken) { var value = await expressionEvaluator.EvaluateAsync(activity.ValueExpression, workflowContext, cancellationToken); diff --git a/src/activities/Elsa.Activities.Primitives/Elsa.Activities.Primitives.csproj b/src/activities/Elsa.Activities.Primitives/Elsa.Activities.Primitives.csproj index 595033afa..8af5fb098 100644 --- a/src/activities/Elsa.Activities.Primitives/Elsa.Activities.Primitives.csproj +++ b/src/activities/Elsa.Activities.Primitives/Elsa.Activities.Primitives.csproj @@ -13,7 +13,7 @@ - + diff --git a/src/activities/Elsa.Activities.Primitives/Extensions/ServiceCollectionExtensions.cs b/src/activities/Elsa.Activities.Primitives/Extensions/ServiceCollectionExtensions.cs index 8ceefacb8..4167c13c1 100644 --- a/src/activities/Elsa.Activities.Primitives/Extensions/ServiceCollectionExtensions.cs +++ b/src/activities/Elsa.Activities.Primitives/Extensions/ServiceCollectionExtensions.cs @@ -1,16 +1,26 @@ -using Elsa.Activities.Primitives.Handlers; +using Elsa.Activities.Primitives.Descriptors; +using Elsa.Activities.Primitives.Drivers; +using Elsa.Extensions; using Microsoft.Extensions.DependencyInjection; namespace Elsa.Activities.Primitives.Extensions { public static class ServiceCollectionExtensions { - public static IServiceCollection AddWorkflowsPrimitives(this IServiceCollection services) + public static IServiceCollection AddPrimitiveDescriptors(this IServiceCollection services) { return services - .AddSingleton() - .AddSingleton() - .AddSingleton(); + .AddActivityDescriptor() + .AddActivityDescriptor() + .AddActivityDescriptor(); + } + + public static IServiceCollection AddPrimitiveDrivers(this IServiceCollection services) + { + return services + .AddActivityDriver() + .AddActivityDriver() + .AddActivityDriver(); } } } \ No newline at end of file diff --git a/src/activities/Elsa.Activities.Primitives/Handlers/ForEachHandler.cs b/src/activities/Elsa.Activities.Primitives/Handlers/ForEachHandler.cs deleted file mode 100644 index e8bf82af4..000000000 --- a/src/activities/Elsa.Activities.Primitives/Handlers/ForEachHandler.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; -using Elsa.Activities.Primitives.Activities; -using Elsa.Handlers; -using Elsa.Models; -using Elsa.Results; -using Microsoft.Extensions.Localization; - -namespace Elsa.Activities.Primitives.Handlers -{ - public class ForEachHandler : ActivityHandler - { - private readonly IWorkflowExpressionEvaluator expressionEvaluator; - - public ForEachHandler(IStringLocalizer localizer, IWorkflowExpressionEvaluator expressionEvaluator) - { - T = localizer; - this.expressionEvaluator = expressionEvaluator; - } - - public override LocalizedString Category => T["Control Flow"]; - public override LocalizedString DisplayText => T["For Each"]; - public override LocalizedString Description => T["Iterate over a list of items."]; - public IStringLocalizer T { get; } - - protected override IEnumerable GetEndpoints() => Endpoints(T["Next"], T["Done"]); - - protected override async Task OnExecuteAsync(ForEach activity, WorkflowExecutionContext workflowContext, CancellationToken cancellationToken) - { - return TriggerEndpoint("Done"); - } - } -} \ No newline at end of file diff --git a/src/activities/Elsa.Activities.Primitives/Handlers/IfElseHandler.cs b/src/activities/Elsa.Activities.Primitives/Handlers/IfElseHandler.cs deleted file mode 100644 index 647255d0a..000000000 --- a/src/activities/Elsa.Activities.Primitives/Handlers/IfElseHandler.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; -using Elsa.Activities.Primitives.Activities; -using Elsa.Handlers; -using Elsa.Models; -using Elsa.Results; -using Microsoft.Extensions.Localization; - -namespace Elsa.Activities.Primitives.Handlers -{ - public class IfElseHandler : ActivityHandler - { - private readonly IWorkflowExpressionEvaluator expressionEvaluator; - - public IfElseHandler(IStringLocalizer localizer, IWorkflowExpressionEvaluator expressionEvaluator) - { - T = localizer; - this.expressionEvaluator = expressionEvaluator; - } - - public override LocalizedString Category => T["Control Flow"]; - public override LocalizedString DisplayText => T["If/Else Branch"]; - public override LocalizedString Description => T["Evaluate a boolean condition and continues execution based on the outcome."]; - public IStringLocalizer T { get; } - - protected override IEnumerable GetEndpoints() => Endpoints(T["True"], T["False"]); - - protected override async Task OnExecuteAsync(IfElse activity, WorkflowExecutionContext workflowContext, CancellationToken cancellationToken) - { - var result = await expressionEvaluator.EvaluateAsync(activity.ConditionExpression, workflowContext, cancellationToken); - return TriggerEndpoint(result ? "True" : "False"); - } - - } -} \ No newline at end of file diff --git a/src/core/Elsa.Abstractions/Elsa.Abstractions.csproj b/src/core/Elsa.Abstractions/Elsa.Abstractions.csproj index 203f919e4..47fc4df6b 100644 --- a/src/core/Elsa.Abstractions/Elsa.Abstractions.csproj +++ b/src/core/Elsa.Abstractions/Elsa.Abstractions.csproj @@ -15,6 +15,7 @@ + diff --git a/src/core/Elsa.Abstractions/Extensions/ServiceCollectionExtensions.cs b/src/core/Elsa.Abstractions/Extensions/ServiceCollectionExtensions.cs new file mode 100644 index 000000000..201df5543 --- /dev/null +++ b/src/core/Elsa.Abstractions/Extensions/ServiceCollectionExtensions.cs @@ -0,0 +1,19 @@ +using Microsoft.Extensions.DependencyInjection; + +namespace Elsa.Extensions +{ + public static class ServiceCollectionExtensions + { + public static IServiceCollection AddActivityDescriptor(this IServiceCollection services) + where T : class, IActivityDescriptor + { + return services.AddSingleton(); + } + + public static IServiceCollection AddActivityDriver(this IServiceCollection services) + where T : class, IActivityDriver + { + return services.AddSingleton(); + } + } +} \ No newline at end of file diff --git a/src/core/Elsa.Abstractions/Handlers/ActivityDescriptorBase.cs b/src/core/Elsa.Abstractions/Handlers/ActivityDescriptorBase.cs new file mode 100644 index 000000000..ead1984a6 --- /dev/null +++ b/src/core/Elsa.Abstractions/Handlers/ActivityDescriptorBase.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Elsa.Models; +using Elsa.Results; +using Microsoft.Extensions.Localization; + +namespace Elsa.Handlers +{ + public abstract class ActivityDescriptorBase : IActivityDescriptor where T : IActivity + { + public Type ActivityType => typeof(T); + public virtual bool IsTrigger => false; + public abstract LocalizedString Category { get; } + public virtual LocalizedString DisplayText => new LocalizedString(ActivityType.Name, ActivityType.Name); + public virtual LocalizedString Description => new LocalizedString("", ""); + protected IEnumerable Endpoints(params LocalizedString[] endpoints) => endpoints; + public virtual IEnumerable GetEndpoints(IActivity activity) => GetEndpoints((T) activity); + protected virtual IEnumerable GetEndpoints(T activity) => Endpoints(GetEndpoint()); + protected virtual IEnumerable GetEndpoints() => Endpoints(GetEndpoint()); + protected virtual LocalizedString GetEndpoint(IActivity activity) => GetEndpoint((T) activity); + protected virtual LocalizedString GetEndpoint(T activity) => GetEndpoint(); + protected virtual LocalizedString GetEndpoint() => new LocalizedString("Done", "Done", true); + } +} \ No newline at end of file diff --git a/src/core/Elsa.Abstractions/Handlers/ActivityHandlerBase.cs b/src/core/Elsa.Abstractions/Handlers/ActivityDriverBase.cs similarity index 72% rename from src/core/Elsa.Abstractions/Handlers/ActivityHandlerBase.cs rename to src/core/Elsa.Abstractions/Handlers/ActivityDriverBase.cs index 200632060..44719b4db 100644 --- a/src/core/Elsa.Abstractions/Handlers/ActivityHandlerBase.cs +++ b/src/core/Elsa.Abstractions/Handlers/ActivityDriverBase.cs @@ -1,20 +1,13 @@ -using System; -using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using Elsa.Models; using Elsa.Results; -using Microsoft.Extensions.Localization; namespace Elsa.Handlers { - public abstract class ActivityHandlerBase : IActivityHandler where T : IActivity + public abstract class ActivityDriverBase : IActivityDriver where T : IActivity { - public Type ActivityType => typeof(T); - public virtual bool IsTrigger => false; - public abstract LocalizedString Category { get; } - public virtual LocalizedString DisplayText => new LocalizedString(ActivityType.Name, ActivityType.Name); - public virtual LocalizedString Description => new LocalizedString("", ""); + public string ActivityType => typeof(T).Name; public Task CanExecuteAsync(ActivityExecutionContext activityContext, WorkflowExecutionContext workflowContext, CancellationToken cancellationToken) => OnCanExecuteAsync(activityContext, workflowContext, cancellationToken); public Task ExecuteAsync(ActivityExecutionContext activityContext, WorkflowExecutionContext workflowContext, CancellationToken cancellationToken) => OnExecuteAsync(activityContext, workflowContext, cancellationToken); public Task ResumeAsync(ActivityExecutionContext activityContext, WorkflowExecutionContext workflowContext, CancellationToken cancellationToken) => OnResumeAsync(activityContext, workflowContext, cancellationToken); @@ -31,12 +24,5 @@ namespace Elsa.Handlers protected virtual ActivityExecutionResult OnResume(ActivityExecutionContext activityContext, WorkflowExecutionContext workflowContext) => OnResume((T) activityContext.Activity, workflowContext); protected virtual ActivityExecutionResult OnResume(T activity, WorkflowExecutionContext workflowContext) => Noop(); protected NoopResult Noop() => new NoopResult(); - protected IEnumerable Endpoints(params LocalizedString[] endpoints) => endpoints; - public virtual IEnumerable GetEndpoints(IActivity activity) => GetEndpoints((T) activity); - protected virtual IEnumerable GetEndpoints(T activity) => Endpoints(GetEndpoint()); - protected virtual IEnumerable GetEndpoints() => Endpoints(GetEndpoint()); - protected virtual LocalizedString GetEndpoint(IActivity activity) => GetEndpoint((T) activity); - protected virtual LocalizedString GetEndpoint(T activity) => GetEndpoint(); - protected virtual LocalizedString GetEndpoint() => new LocalizedString("Done", "Done", true); } } \ No newline at end of file diff --git a/src/core/Elsa.Abstractions/IActivityHandler.cs b/src/core/Elsa.Abstractions/IActivityDescriptor.cs similarity index 58% rename from src/core/Elsa.Abstractions/IActivityHandler.cs rename to src/core/Elsa.Abstractions/IActivityDescriptor.cs index fc74d8cfb..c9dbfc2d8 100644 --- a/src/core/Elsa.Abstractions/IActivityHandler.cs +++ b/src/core/Elsa.Abstractions/IActivityDescriptor.cs @@ -8,7 +8,7 @@ using Microsoft.Extensions.Localization; namespace Elsa { - public interface IActivityHandler + public interface IActivityDescriptor { /// /// A value indicating whether this activity can trigger the execution of the workflow. @@ -40,20 +40,5 @@ namespace Elsa /// /// IEnumerable GetEndpoints(IActivity activity); - - /// - /// Returns a value of whether the specified activity can execute. - /// - Task CanExecuteAsync(ActivityExecutionContext activityContext, WorkflowExecutionContext workflowContext, CancellationToken cancellationToken); - - /// - /// Executes the specified activity. - /// - Task ExecuteAsync(ActivityExecutionContext activityContext, WorkflowExecutionContext workflowContext, CancellationToken cancellationToken); - - /// - /// Resumes the specified activity. - /// - Task ResumeAsync(ActivityExecutionContext activityContext, WorkflowExecutionContext workflowContext, CancellationToken cancellationToken); } } \ No newline at end of file diff --git a/src/core/Elsa.Abstractions/IActivityDriver.cs b/src/core/Elsa.Abstractions/IActivityDriver.cs new file mode 100644 index 000000000..477f17997 --- /dev/null +++ b/src/core/Elsa.Abstractions/IActivityDriver.cs @@ -0,0 +1,30 @@ +using System.Threading; +using System.Threading.Tasks; +using Elsa.Models; +using Elsa.Results; + +namespace Elsa +{ + public interface IActivityDriver + { + /// + /// The activity type of this driver. + /// + string ActivityType { get; } + + /// + /// Returns a value of whether the specified activity can execute. + /// + Task CanExecuteAsync(ActivityExecutionContext activityContext, WorkflowExecutionContext workflowContext, CancellationToken cancellationToken); + + /// + /// Executes the specified activity. + /// + Task ExecuteAsync(ActivityExecutionContext activityContext, WorkflowExecutionContext workflowContext, CancellationToken cancellationToken); + + /// + /// Resumes the specified activity. + /// + Task ResumeAsync(ActivityExecutionContext activityContext, WorkflowExecutionContext workflowContext, CancellationToken cancellationToken); + } +} \ No newline at end of file diff --git a/src/core/Elsa.Abstractions/IActivityDriverRegistry.cs b/src/core/Elsa.Abstractions/IActivityDriverRegistry.cs new file mode 100644 index 000000000..c8175cb1d --- /dev/null +++ b/src/core/Elsa.Abstractions/IActivityDriverRegistry.cs @@ -0,0 +1,7 @@ +namespace Elsa +{ + public interface IActivityDriverRegistry + { + IActivityDriver GetDriver(string activityTypeName); + } +} diff --git a/src/core/Elsa.Abstractions/IActivityProvider.cs b/src/core/Elsa.Abstractions/IActivityHarvester.cs similarity index 85% rename from src/core/Elsa.Abstractions/IActivityProvider.cs rename to src/core/Elsa.Abstractions/IActivityHarvester.cs index 9262585bb..f7c7879e4 100644 --- a/src/core/Elsa.Abstractions/IActivityProvider.cs +++ b/src/core/Elsa.Abstractions/IActivityHarvester.cs @@ -5,7 +5,7 @@ using Elsa.Models; namespace Elsa { - public interface IActivityProvider + public interface IActivityHarvester { Task> GetActivitiesAsync(CancellationToken cancellationToken); } diff --git a/src/core/Elsa.Abstractions/IActivityInvoker.cs b/src/core/Elsa.Abstractions/IActivityInvoker.cs new file mode 100644 index 000000000..071eb76e3 --- /dev/null +++ b/src/core/Elsa.Abstractions/IActivityInvoker.cs @@ -0,0 +1,13 @@ +using System.Threading; +using System.Threading.Tasks; +using Elsa.Models; +using Elsa.Results; + +namespace Elsa +{ + public interface IActivityInvoker + { + Task ExecuteAsync(WorkflowExecutionContext workflowContext, IActivity activity, CancellationToken cancellationToken = default); + Task ResumeAsync(WorkflowExecutionContext workflowContext, IActivity activity, CancellationToken cancellationToken = default); + } +} \ No newline at end of file diff --git a/src/core/Elsa.Abstractions/IWorkflowInvoker.cs b/src/core/Elsa.Abstractions/IWorkflowInvoker.cs index f01602016..28e6dbcfd 100644 --- a/src/core/Elsa.Abstractions/IWorkflowInvoker.cs +++ b/src/core/Elsa.Abstractions/IWorkflowInvoker.cs @@ -6,6 +6,7 @@ namespace Elsa { public interface IWorkflowInvoker { + IActivityInvoker ActivityInvoker { get; } Task InvokeAsync(Workflow workflow, IActivity startActivity = default, Variables arguments = default, CancellationToken cancellationToken = default); Task ResumeAsync(Workflow workflow, IActivity startActivity = default, Variables arguments = default, CancellationToken cancellationToken = default); } diff --git a/src/core/Elsa.Abstractions/Models/ActivityDescriptor.cs b/src/core/Elsa.Abstractions/Models/ActivityDescriptor.cs index adbc319c6..37d71b32a 100644 --- a/src/core/Elsa.Abstractions/Models/ActivityDescriptor.cs +++ b/src/core/Elsa.Abstractions/Models/ActivityDescriptor.cs @@ -17,8 +17,5 @@ namespace Elsa.Models public LocalizedString DisplayText { get; set; } public LocalizedString Description { get; set; } public Func> GetEndpoints { get; set; } - public Func> CanExecuteAsync { get; set; } - public Func> ExecuteAsync { get; set; } - public Func> ResumeAsync { get; set; } } } \ No newline at end of file diff --git a/src/core/Elsa.Abstractions/Models/ActivityExecutionContext.cs b/src/core/Elsa.Abstractions/Models/ActivityExecutionContext.cs index 25768c7a2..98aac6fd7 100644 --- a/src/core/Elsa.Abstractions/Models/ActivityExecutionContext.cs +++ b/src/core/Elsa.Abstractions/Models/ActivityExecutionContext.cs @@ -2,13 +2,11 @@ { public class ActivityExecutionContext { - public ActivityExecutionContext(IActivity activity, ActivityDescriptor descriptor) + public ActivityExecutionContext(IActivity activity) { Activity = activity; - Descriptor = descriptor; } public IActivity Activity { get; } - public ActivityDescriptor Descriptor { get; } } } diff --git a/src/core/Elsa.Abstractions/Models/WorkflowExecutionContext.cs b/src/core/Elsa.Abstractions/Models/WorkflowExecutionContext.cs index d73294275..d2c721175 100644 --- a/src/core/Elsa.Abstractions/Models/WorkflowExecutionContext.cs +++ b/src/core/Elsa.Abstractions/Models/WorkflowExecutionContext.cs @@ -6,12 +6,10 @@ namespace Elsa.Models { public class WorkflowExecutionContext { - private readonly IDictionary activityDescriptors; private readonly Stack scheduledActivities; - public WorkflowExecutionContext(Workflow workflow, IDictionary activityDescriptors) + public WorkflowExecutionContext(Workflow workflow) { - this.activityDescriptors = activityDescriptors; Workflow = workflow; IsFirstPass = true; scheduledActivities = new Stack(); @@ -29,7 +27,7 @@ namespace Elsa.Models } public ActivityExecutionContext CreateActivityExecutionContext(IActivity activity) => - new ActivityExecutionContext(activity, activityDescriptors[activity.Name]); + new ActivityExecutionContext(activity); public void BeginScope() { diff --git a/src/core/Elsa.Core/ActivityDriverRegistry.cs b/src/core/Elsa.Core/ActivityDriverRegistry.cs new file mode 100644 index 000000000..c07d67395 --- /dev/null +++ b/src/core/Elsa.Core/ActivityDriverRegistry.cs @@ -0,0 +1,20 @@ +using System.Collections.Generic; +using System.Linq; + +namespace Elsa +{ + public class ActivityDriverRegistry : IActivityDriverRegistry + { + private readonly IDictionary dictionary; + + public ActivityDriverRegistry(IEnumerable drivers) + { + dictionary = drivers.ToDictionary(x => x.ActivityType); + } + + public IActivityDriver GetDriver(string activityTypeName) + { + return dictionary.ContainsKey(activityTypeName) ? dictionary[activityTypeName] : null; + } + } +} \ No newline at end of file diff --git a/src/core/Elsa.Core/ActivityInvoker.cs b/src/core/Elsa.Core/ActivityInvoker.cs new file mode 100644 index 000000000..097a6ad82 --- /dev/null +++ b/src/core/Elsa.Core/ActivityInvoker.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Elsa.Models; +using Elsa.Results; +using Microsoft.Extensions.Logging; + +namespace Elsa +{ + public class ActivityInvoker : IActivityInvoker + { + private readonly IActivityDriverRegistry driverRegistry; + + public ActivityInvoker(IActivityDriverRegistry driverRegistry) + { + this.driverRegistry = driverRegistry; + } + + public async Task ExecuteAsync(WorkflowExecutionContext workflowContext, IActivity activity, CancellationToken cancellationToken = default) + { + return await InvokeAsync(workflowContext, activity, (context, driver) => driver.ExecuteAsync(context, workflowContext, cancellationToken)); + } + + public async Task ResumeAsync(WorkflowExecutionContext workflowContext, IActivity activity, CancellationToken cancellationToken = default) + { + return await InvokeAsync(workflowContext, activity, (context, driver) => driver.ResumeAsync(context, workflowContext, cancellationToken)); + } + + private Task InvokeAsync( + WorkflowExecutionContext workflowContext, + IActivity activity, + Func> invokeAction) + { + var activityContext = workflowContext.CreateActivityExecutionContext(activity); + var driver = driverRegistry.GetDriver(activity.Name); + return invokeAction(activityContext, driver); + } + } +} \ No newline at end of file diff --git a/src/core/Elsa.Core/ActivityLibrary.cs b/src/core/Elsa.Core/ActivityLibrary.cs index f6d967f16..47c33dc0f 100644 --- a/src/core/Elsa.Core/ActivityLibrary.cs +++ b/src/core/Elsa.Core/ActivityLibrary.cs @@ -8,9 +8,9 @@ namespace Elsa { public class ActivityLibrary : IActivityLibrary { - private readonly IEnumerable providers; + private readonly IEnumerable providers; - public ActivityLibrary(IEnumerable providers) + public ActivityLibrary(IEnumerable providers) { this.providers = providers; } diff --git a/src/core/Elsa.Core/ActivityProviders/TypedActivityProvider.cs b/src/core/Elsa.Core/ActivityProviders/TypedActivityHarvester.cs similarity index 70% rename from src/core/Elsa.Core/ActivityProviders/TypedActivityProvider.cs rename to src/core/Elsa.Core/ActivityProviders/TypedActivityHarvester.cs index 0e18309ed..584fdefc9 100644 --- a/src/core/Elsa.Core/ActivityProviders/TypedActivityProvider.cs +++ b/src/core/Elsa.Core/ActivityProviders/TypedActivityHarvester.cs @@ -8,11 +8,11 @@ using Elsa.Models; namespace Elsa.ActivityProviders { - public class TypedActivityProvider : IActivityProvider + public class TypedActivityHarvester : IActivityHarvester { - private readonly IEnumerable handlers; + private readonly IEnumerable handlers; - public TypedActivityProvider(IEnumerable handlers) + public TypedActivityHarvester(IEnumerable handlers) { this.handlers = handlers; } @@ -28,10 +28,7 @@ namespace Elsa.ActivityProviders ActivityType = x.ActivityType, DisplayText = x.DisplayText, Description = x.Description, - GetEndpoints = x.GetEndpoints, - CanExecuteAsync = x.CanExecuteAsync, - ExecuteAsync = x.ExecuteAsync, - ResumeAsync = x.ResumeAsync + GetEndpoints = x.GetEndpoints }); return Task.FromResult(descriptors); diff --git a/src/core/Elsa.Core/Extensions/ServiceCollectionExtensions.cs b/src/core/Elsa.Core/Extensions/ServiceCollectionExtensions.cs index e3796deab..be822eb08 100644 --- a/src/core/Elsa.Core/Extensions/ServiceCollectionExtensions.cs +++ b/src/core/Elsa.Core/Extensions/ServiceCollectionExtensions.cs @@ -15,8 +15,7 @@ namespace Elsa.Extensions .AddSingleton() .AddScoped() .AddScoped() - .AddScoped() - .AddScoped() + .AddScoped() .AddScoped() .AddSingleton() .AddSingleton() @@ -24,7 +23,15 @@ namespace Elsa.Extensions .AddSingleton() .AddSingleton() .AddSingleton() - .AddSingleton() + .AddSingleton(); + } + + public static IServiceCollection AddWorkflowsInvoker(this IServiceCollection services) + { + return services + .AddSingleton() + .AddSingleton() + .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton(); diff --git a/src/core/Elsa.Core/Handlers/ActivityHandler.cs b/src/core/Elsa.Core/Handlers/ActivityDriver.cs similarity index 90% rename from src/core/Elsa.Core/Handlers/ActivityHandler.cs rename to src/core/Elsa.Core/Handlers/ActivityDriver.cs index d71e4bbca..96b54193b 100644 --- a/src/core/Elsa.Core/Handlers/ActivityHandler.cs +++ b/src/core/Elsa.Core/Handlers/ActivityDriver.cs @@ -4,7 +4,7 @@ using Elsa.Results; namespace Elsa.Handlers { - public abstract class ActivityHandler : ActivityHandlerBase where T : IActivity + public abstract class ActivityDriver : ActivityDriverBase where T : IActivity { protected HaltResult Halt() => new HaltResult(); protected TriggerEndpointsResult TriggerEndpoints(IEnumerable names) => new TriggerEndpointsResult(names); diff --git a/src/core/Elsa.Core/Handlers/UnknownActivityDescriptor.cs b/src/core/Elsa.Core/Handlers/UnknownActivityDescriptor.cs new file mode 100644 index 000000000..f0bbf6522 --- /dev/null +++ b/src/core/Elsa.Core/Handlers/UnknownActivityDescriptor.cs @@ -0,0 +1,22 @@ +using System.Collections.Generic; +using System.Linq; +using Elsa.Activities; +using Elsa.Models; +using Elsa.Results; +using Microsoft.Extensions.Localization; + +namespace Elsa.Handlers +{ + public class UnknownActivityDescriptor : ActivityDescriptorBase + { + public UnknownActivityDescriptor(IStringLocalizer localizer) + { + T = localizer; + } + + public IStringLocalizer T { get; } + public override LocalizedString Category => T["System"]; + protected override IEnumerable GetEndpoints() => Enumerable.Empty(); + + } +} \ No newline at end of file diff --git a/src/core/Elsa.Core/Handlers/UnknownActivityDriver.cs b/src/core/Elsa.Core/Handlers/UnknownActivityDriver.cs new file mode 100644 index 000000000..cd42ef9a6 --- /dev/null +++ b/src/core/Elsa.Core/Handlers/UnknownActivityDriver.cs @@ -0,0 +1,14 @@ +using Elsa.Activities; +using Elsa.Models; +using Elsa.Results; + +namespace Elsa.Handlers +{ + public class UnknownActivityDriver : ActivityDriver + { + protected override ActivityExecutionResult OnExecute(UnknownActivity activity, WorkflowExecutionContext workflowContext) + { + return Fault($"Unknown activity: {activity.Name}, ID: {activity.Id}"); + } + } +} \ No newline at end of file diff --git a/src/core/Elsa.Core/Handlers/UnknownActivityHandler.cs b/src/core/Elsa.Core/Handlers/UnknownActivityHandler.cs deleted file mode 100644 index 0b22574d9..000000000 --- a/src/core/Elsa.Core/Handlers/UnknownActivityHandler.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using Elsa.Activities; -using Elsa.Models; -using Elsa.Results; -using Microsoft.Extensions.Localization; - -namespace Elsa.Handlers -{ - public class UnknownActivityHandler : ActivityHandler - { - public UnknownActivityHandler(IStringLocalizer localizer) - { - T = localizer; - } - - public IStringLocalizer T { get; } - public override LocalizedString Category => T["System"]; - protected override IEnumerable GetEndpoints() => Enumerable.Empty(); - - protected override ActivityExecutionResult OnExecute(UnknownActivity activity, WorkflowExecutionContext workflowContext) - { - return Fault($"Unknown activity: {activity.Name}, ID: {activity.Id}"); - } - } -} \ No newline at end of file diff --git a/src/core/Elsa.Core/Results/HaltResult.cs b/src/core/Elsa.Core/Results/HaltResult.cs index a3384700e..0b7466b3a 100644 --- a/src/core/Elsa.Core/Results/HaltResult.cs +++ b/src/core/Elsa.Core/Results/HaltResult.cs @@ -14,8 +14,7 @@ namespace Elsa.Results if (workflowContext.IsFirstPass) { var activity = workflowContext.CurrentActivity; - var activityContext = workflowContext.CreateActivityExecutionContext(activity); - var result = await activityContext.Descriptor.ResumeAsync(activityContext, workflowContext, cancellationToken); + var result = await invoker.ActivityInvoker.ResumeAsync(workflowContext, activity, cancellationToken); workflowContext.IsFirstPass = false; await result.ExecuteAsync(invoker, workflowContext, cancellationToken); diff --git a/src/core/Elsa.Core/WorkflowInvoker.cs b/src/core/Elsa.Core/WorkflowInvoker.cs index f251210f2..f62a05399 100644 --- a/src/core/Elsa.Core/WorkflowInvoker.cs +++ b/src/core/Elsa.Core/WorkflowInvoker.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -10,21 +11,20 @@ namespace Elsa { public class WorkflowInvoker : IWorkflowInvoker { - public WorkflowInvoker(IActivityLibrary activityLibrary, ILogger logger) + private readonly ILogger logger; + + public WorkflowInvoker(IActivityInvoker activityInvoker, ILogger logger) { - this.activityLibrary = activityLibrary; + ActivityInvoker = activityInvoker; this.logger = logger; } - private readonly IActivityLibrary activityLibrary; - private readonly ILogger logger; + public IActivityInvoker ActivityInvoker { get; } public async Task InvokeAsync(Workflow workflow, IActivity startActivity = default, Variables arguments = default, CancellationToken cancellationToken = default) { workflow.Arguments = arguments ?? new Variables(); - var activityDescriptors = await activityLibrary.ListAsync(cancellationToken); - var activityDescriptorsDictionary = activityDescriptors.ToDictionary(x => x.Name); - var workflowExecutionContext = new WorkflowExecutionContext(workflow, activityDescriptorsDictionary); + var workflowExecutionContext = new WorkflowExecutionContext(workflow); var isResuming = workflowExecutionContext.Workflow.Status == WorkflowStatus.Resuming; if (startActivity != null) @@ -91,12 +91,11 @@ namespace Elsa workflowContext.Fault(ex, activity); } - private static async Task ExecuteOrResumeActivityAsync(WorkflowExecutionContext workflowContext, IActivity activity, bool isResuming, CancellationToken cancellationToken) + private async Task ExecuteOrResumeActivityAsync(WorkflowExecutionContext workflowContext, IActivity activity, bool isResuming, CancellationToken cancellationToken) { - var activityContext = workflowContext.CreateActivityExecutionContext(activity); return isResuming - ? await activityContext.Descriptor.ResumeAsync(activityContext, workflowContext, cancellationToken) - : await activityContext.Descriptor.ExecuteAsync(activityContext, workflowContext, cancellationToken); + ? await ActivityInvoker.ResumeAsync(workflowContext, activity, cancellationToken) + : await ActivityInvoker.ExecuteAsync(workflowContext, activity, cancellationToken); } } } diff --git a/src/samples/SampleHost.Web/Startup.cs b/src/samples/SampleHost.Web/Startup.cs index 1eace365d..fa5501e70 100644 --- a/src/samples/SampleHost.Web/Startup.cs +++ b/src/samples/SampleHost.Web/Startup.cs @@ -28,9 +28,9 @@ namespace SampleHost.Web .AddWorkflowsCore() .AddWorkflowsHost() .AddWorkflowsFileSystemPersistence(Configuration.GetSection("FileStore")) - .AddWorkflowsPrimitives() - .AddWorkflowsConsole() - .AddWorkflowsHttp(); + .AddPrimitiveDescriptors() + .AddConsoleDescriptors() + .AddHttpDescriptors(); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Latest); } diff --git a/src/web/modules/Elsa.Web.Abstractions/Extensions/ServiceCollectionExtensions.cs b/src/web/modules/Elsa.Web.Abstractions/Extensions/ServiceCollectionExtensions.cs index 5bc8c5f88..4eb70f5b5 100644 --- a/src/web/modules/Elsa.Web.Abstractions/Extensions/ServiceCollectionExtensions.cs +++ b/src/web/modules/Elsa.Web.Abstractions/Extensions/ServiceCollectionExtensions.cs @@ -5,13 +5,13 @@ namespace Elsa.Web.Extensions { public static class ServiceCollectionExtensions { - public static IServiceCollection AddActivity(this IServiceCollection services) - where THandler : class, IActivityHandler - where TDriver : class, IDisplayDriver + public static IServiceCollection AddActivity(this IServiceCollection services) + where TDescriptor : class, IActivityDescriptor + where TDisplayDriver : class, IDisplayDriver { return services - .AddScoped() - .AddScoped, TDriver>(); + .AddScoped() + .AddScoped, TDisplayDriver>(); } } } \ No newline at end of file diff --git a/src/web/modules/Elsa.Web.Activities.Console/Drivers/ReadLineDriver.cs b/src/web/modules/Elsa.Web.Activities.Console/Drivers/ReadLineDisplay.cs similarity index 66% rename from src/web/modules/Elsa.Web.Activities.Console/Drivers/ReadLineDriver.cs rename to src/web/modules/Elsa.Web.Activities.Console/Drivers/ReadLineDisplay.cs index c7c09ea26..e6e4b65a6 100644 --- a/src/web/modules/Elsa.Web.Activities.Console/Drivers/ReadLineDriver.cs +++ b/src/web/modules/Elsa.Web.Activities.Console/Drivers/ReadLineDisplay.cs @@ -3,7 +3,7 @@ using Elsa.Web.Drivers; namespace Elsa.Web.Activities.Console.Drivers { - public class ReadLineDriver : ActivityDisplayDriver + public class ReadLineDisplay : ActivityDisplayDriver { } } \ No newline at end of file diff --git a/src/web/modules/Elsa.Web.Activities.Console/Drivers/WriteLineDriver.cs b/src/web/modules/Elsa.Web.Activities.Console/Drivers/WriteLineDisplay.cs similarity index 87% rename from src/web/modules/Elsa.Web.Activities.Console/Drivers/WriteLineDriver.cs rename to src/web/modules/Elsa.Web.Activities.Console/Drivers/WriteLineDisplay.cs index 81e7e6270..0991fbbed 100644 --- a/src/web/modules/Elsa.Web.Activities.Console/Drivers/WriteLineDriver.cs +++ b/src/web/modules/Elsa.Web.Activities.Console/Drivers/WriteLineDisplay.cs @@ -5,7 +5,7 @@ using Elsa.Web.Drivers; namespace Elsa.Web.Activities.Console.Drivers { - public class WriteLineDriver : ActivityDisplayDriver + public class WriteLineDisplay : ActivityDisplayDriver { protected override void EditActivity(WriteLine activity, WriteLineViewModel model) { diff --git a/src/web/modules/Elsa.Web.Activities.Console/Elsa.Web.Activities.Console.csproj b/src/web/modules/Elsa.Web.Activities.Console/Elsa.Web.Activities.Console.csproj index 7dac7513a..5f45e021e 100644 --- a/src/web/modules/Elsa.Web.Activities.Console/Elsa.Web.Activities.Console.csproj +++ b/src/web/modules/Elsa.Web.Activities.Console/Elsa.Web.Activities.Console.csproj @@ -13,21 +13,21 @@ - - + + - + - - - - - - + + + + + + diff --git a/src/web/modules/Elsa.Web.Activities.Console/Startup.cs b/src/web/modules/Elsa.Web.Activities.Console/Startup.cs index 300f82152..07f472c11 100644 --- a/src/web/modules/Elsa.Web.Activities.Console/Startup.cs +++ b/src/web/modules/Elsa.Web.Activities.Console/Startup.cs @@ -1,4 +1,4 @@ -using Elsa.Activities.Console.Handlers; +using Elsa.Activities.Console.Descriptors; using Elsa.Web.Activities.Console.Drivers; using Elsa.Web.Extensions; using Microsoft.Extensions.DependencyInjection; @@ -11,8 +11,8 @@ namespace Elsa.Web.Activities.Console public override void ConfigureServices(IServiceCollection services) { services - .AddActivity() - .AddActivity(); + .AddActivity() + .AddActivity(); } } } \ No newline at end of file diff --git a/src/web/modules/Elsa.Web.Activities.Http/Drivers/HttpRequestTriggerDriver.cs b/src/web/modules/Elsa.Web.Activities.Http/Drivers/HttpRequestTriggerDisplay.cs similarity index 85% rename from src/web/modules/Elsa.Web.Activities.Http/Drivers/HttpRequestTriggerDriver.cs rename to src/web/modules/Elsa.Web.Activities.Http/Drivers/HttpRequestTriggerDisplay.cs index e23eeea82..40124d9f6 100644 --- a/src/web/modules/Elsa.Web.Activities.Http/Drivers/HttpRequestTriggerDriver.cs +++ b/src/web/modules/Elsa.Web.Activities.Http/Drivers/HttpRequestTriggerDisplay.cs @@ -4,7 +4,7 @@ using Elsa.Web.Drivers; namespace Elsa.Web.Activities.Http.Drivers { - public class HttpRequestTriggerDriver : ActivityDisplayDriver + public class HttpRequestTriggerDisplay : ActivityDisplayDriver { protected override void EditActivity(HttpRequestTrigger activity, HttpRequestTriggerViewModel model) { diff --git a/src/web/modules/Elsa.Web.Activities.Http/Elsa.Web.Activities.Http.csproj b/src/web/modules/Elsa.Web.Activities.Http/Elsa.Web.Activities.Http.csproj index 797ae4825..776b5d705 100644 --- a/src/web/modules/Elsa.Web.Activities.Http/Elsa.Web.Activities.Http.csproj +++ b/src/web/modules/Elsa.Web.Activities.Http/Elsa.Web.Activities.Http.csproj @@ -13,16 +13,16 @@ - - + + - + - + diff --git a/src/web/modules/Elsa.Web.Activities.Http/Startup.cs b/src/web/modules/Elsa.Web.Activities.Http/Startup.cs index 22083a19d..83fc69f33 100644 --- a/src/web/modules/Elsa.Web.Activities.Http/Startup.cs +++ b/src/web/modules/Elsa.Web.Activities.Http/Startup.cs @@ -1,4 +1,4 @@ -using Elsa.Activities.Http.Handlers; +using Elsa.Activities.Http.Descriptors; using Elsa.Web.Activities.Http.Drivers; using Elsa.Web.Extensions; using Microsoft.Extensions.DependencyInjection; @@ -11,7 +11,7 @@ namespace Elsa.Web.Activities.Http public override void ConfigureServices(IServiceCollection services) { services - .AddActivity(); + .AddActivity(); } } } \ No newline at end of file diff --git a/src/web/modules/Elsa.Web.Activities.Primitives/Drivers/ForEachDriver.cs b/src/web/modules/Elsa.Web.Activities.Primitives/Drivers/ForEachDisplay.cs similarity index 67% rename from src/web/modules/Elsa.Web.Activities.Primitives/Drivers/ForEachDriver.cs rename to src/web/modules/Elsa.Web.Activities.Primitives/Drivers/ForEachDisplay.cs index c1e853820..3fa4b3561 100644 --- a/src/web/modules/Elsa.Web.Activities.Primitives/Drivers/ForEachDriver.cs +++ b/src/web/modules/Elsa.Web.Activities.Primitives/Drivers/ForEachDisplay.cs @@ -3,7 +3,7 @@ using Elsa.Web.Drivers; namespace Elsa.Web.Activities.Primitives.Drivers { - public class ForEachDriver : ActivityDisplayDriver + public class ForEachDisplay : ActivityDisplayDriver { } } \ No newline at end of file diff --git a/src/web/modules/Elsa.Web.Activities.Primitives/Drivers/IfElseDriver.cs b/src/web/modules/Elsa.Web.Activities.Primitives/Drivers/IfElseDisplay.cs similarity index 68% rename from src/web/modules/Elsa.Web.Activities.Primitives/Drivers/IfElseDriver.cs rename to src/web/modules/Elsa.Web.Activities.Primitives/Drivers/IfElseDisplay.cs index 8782bd441..03638a4fa 100644 --- a/src/web/modules/Elsa.Web.Activities.Primitives/Drivers/IfElseDriver.cs +++ b/src/web/modules/Elsa.Web.Activities.Primitives/Drivers/IfElseDisplay.cs @@ -3,7 +3,7 @@ using Elsa.Web.Drivers; namespace Elsa.Web.Activities.Primitives.Drivers { - public class IfElseDriver : ActivityDisplayDriver + public class IfElseDisplay : ActivityDisplayDriver { } } \ No newline at end of file diff --git a/src/web/modules/Elsa.Web.Activities.Primitives/Drivers/UnknownActivityDriver.cs b/src/web/modules/Elsa.Web.Activities.Primitives/Drivers/UnknownActivityDisplay.cs similarity index 58% rename from src/web/modules/Elsa.Web.Activities.Primitives/Drivers/UnknownActivityDriver.cs rename to src/web/modules/Elsa.Web.Activities.Primitives/Drivers/UnknownActivityDisplay.cs index 7e44081ff..f4986afeb 100644 --- a/src/web/modules/Elsa.Web.Activities.Primitives/Drivers/UnknownActivityDriver.cs +++ b/src/web/modules/Elsa.Web.Activities.Primitives/Drivers/UnknownActivityDisplay.cs @@ -3,7 +3,7 @@ using Elsa.Web.Drivers; namespace Elsa.Web.Activities.Primitives.Drivers { - public class UnknownActivityDriver : ActivityDisplayDriver + public class UnknownActivityDisplay : ActivityDisplayDriver { } } \ No newline at end of file diff --git a/src/web/modules/Elsa.Web.Activities.Primitives/Elsa.Web.Activities.Primitives.csproj b/src/web/modules/Elsa.Web.Activities.Primitives/Elsa.Web.Activities.Primitives.csproj index cea8bfd2d..f8e74f95f 100644 --- a/src/web/modules/Elsa.Web.Activities.Primitives/Elsa.Web.Activities.Primitives.csproj +++ b/src/web/modules/Elsa.Web.Activities.Primitives/Elsa.Web.Activities.Primitives.csproj @@ -13,16 +13,16 @@ - + - - + + - + diff --git a/src/web/modules/Elsa.Web.Activities.Primitives/Startup.cs b/src/web/modules/Elsa.Web.Activities.Primitives/Startup.cs index 60999bbee..19c817b3a 100644 --- a/src/web/modules/Elsa.Web.Activities.Primitives/Startup.cs +++ b/src/web/modules/Elsa.Web.Activities.Primitives/Startup.cs @@ -1,4 +1,4 @@ -using Elsa.Activities.Primitives.Handlers; +using Elsa.Activities.Primitives.Descriptors; using Elsa.Handlers; using Elsa.Web.Activities.Primitives.Drivers; using Elsa.Web.Extensions; @@ -12,9 +12,9 @@ namespace Elsa.Web.Activities.Primitives public override void ConfigureServices(IServiceCollection services) { services - .AddActivity() - .AddActivity() - .AddActivity(); + .AddActivity() + .AddActivity() + .AddActivity(); } } } \ No newline at end of file