diff --git a/Samples.sln b/Samples.sln index 90abf9a99..6e021562c 100644 --- a/Samples.sln +++ b/Samples.sln @@ -88,6 +88,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Server.GraphQL", "src\ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Samples.Serialization", "src\samples\Elsa.Samples.Serialization\Elsa.Samples.Serialization.csproj", "{DF47517F-9029-44DF-A29F-F2DE15041473}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Samples.HelloWorldConsole", "src\samples\Elsa.Samples.HelloWorldConsole\Elsa.Samples.HelloWorldConsole.csproj", "{E224F8CF-F9F5-4E99-B405-758F3C02C47A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Samples.HelloWorldHttp", "src\samples\Elsa.Samples.HelloWorldHttp\Elsa.Samples.HelloWorldHttp.csproj", "{A11D79AE-F4C9-4595-9B73-0E0AB221B90D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Samples.CustomActivities", "src\samples\Elsa.Samples.CustomActivities\Elsa.Samples.CustomActivities.csproj", "{554C21D7-10BE-48E6-B0EF-9FCA43B32A0F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Samples.TimeSheetApproval", "src\samples\Elsa.Samples.TimeSheetApproval\Elsa.Samples.TimeSheetApproval.csproj", "{1678743A-9095-4683-8DCD-5763F41924E2}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -198,6 +206,22 @@ Global {DF47517F-9029-44DF-A29F-F2DE15041473}.Debug|Any CPU.Build.0 = Debug|Any CPU {DF47517F-9029-44DF-A29F-F2DE15041473}.Release|Any CPU.ActiveCfg = Release|Any CPU {DF47517F-9029-44DF-A29F-F2DE15041473}.Release|Any CPU.Build.0 = Release|Any CPU + {E224F8CF-F9F5-4E99-B405-758F3C02C47A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E224F8CF-F9F5-4E99-B405-758F3C02C47A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E224F8CF-F9F5-4E99-B405-758F3C02C47A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E224F8CF-F9F5-4E99-B405-758F3C02C47A}.Release|Any CPU.Build.0 = Release|Any CPU + {A11D79AE-F4C9-4595-9B73-0E0AB221B90D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A11D79AE-F4C9-4595-9B73-0E0AB221B90D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A11D79AE-F4C9-4595-9B73-0E0AB221B90D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A11D79AE-F4C9-4595-9B73-0E0AB221B90D}.Release|Any CPU.Build.0 = Release|Any CPU + {554C21D7-10BE-48E6-B0EF-9FCA43B32A0F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {554C21D7-10BE-48E6-B0EF-9FCA43B32A0F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {554C21D7-10BE-48E6-B0EF-9FCA43B32A0F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {554C21D7-10BE-48E6-B0EF-9FCA43B32A0F}.Release|Any CPU.Build.0 = Release|Any CPU + {1678743A-9095-4683-8DCD-5763F41924E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1678743A-9095-4683-8DCD-5763F41924E2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1678743A-9095-4683-8DCD-5763F41924E2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1678743A-9095-4683-8DCD-5763F41924E2}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -238,6 +262,10 @@ Global {150EF356-E8BC-4922-91C2-362017479409} = {600C4AE0-0585-4181-9CEC-2BB43430C713} {12D29DDC-A885-4CAA-908C-106D845B10C0} = {468E498C-59DB-4541-8D8A-0D89DE9083AB} {DF47517F-9029-44DF-A29F-F2DE15041473} = {5E5E1E84-DDBC-40D6-B891-0D563A15A44A} + {E224F8CF-F9F5-4E99-B405-758F3C02C47A} = {5E5E1E84-DDBC-40D6-B891-0D563A15A44A} + {A11D79AE-F4C9-4595-9B73-0E0AB221B90D} = {5E5E1E84-DDBC-40D6-B891-0D563A15A44A} + {554C21D7-10BE-48E6-B0EF-9FCA43B32A0F} = {5E5E1E84-DDBC-40D6-B891-0D563A15A44A} + {1678743A-9095-4683-8DCD-5763F41924E2} = {5E5E1E84-DDBC-40D6-B891-0D563A15A44A} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {8B0975FD-7050-48B0-88C5-48C33378E158} diff --git a/src/core/Elsa.Abstractions/Models/Variable.cs b/src/core/Elsa.Abstractions/Models/Variable.cs index 986a283a2..375a906f7 100644 --- a/src/core/Elsa.Abstractions/Models/Variable.cs +++ b/src/core/Elsa.Abstractions/Models/Variable.cs @@ -17,6 +17,5 @@ } public object? Value { get; set; } - public string Test { get; set; } = "Test"; } } \ No newline at end of file diff --git a/src/core/Elsa.Abstractions/Results/OutcomeResult.cs b/src/core/Elsa.Abstractions/Results/OutcomeResult.cs index bad6cfd40..f67ac7b50 100644 --- a/src/core/Elsa.Abstractions/Results/OutcomeResult.cs +++ b/src/core/Elsa.Abstractions/Results/OutcomeResult.cs @@ -25,7 +25,9 @@ namespace Elsa.Results protected override void Execute(ActivityExecutionContext activityExecutionContext) { - activityExecutionContext.Output = Output; + if(Output != null) + activityExecutionContext.Output = Output; + activityExecutionContext.Outcomes = Outcomes.ToList(); var workflowExecutionContext = activityExecutionContext.WorkflowExecutionContext; diff --git a/src/core/Elsa.Core/Expressions/CodeExpression.cs b/src/core/Elsa.Core/Expressions/CodeExpression.cs index 0e3107da0..da757ad58 100644 --- a/src/core/Elsa.Core/Expressions/CodeExpression.cs +++ b/src/core/Elsa.Core/Expressions/CodeExpression.cs @@ -22,11 +22,11 @@ namespace Elsa.Expressions public class CodeExpression : CodeExpression, IWorkflowExpression { - public CodeExpression(Func expression) : base(context => expression(context)) + public CodeExpression(Func expression) : base(context => expression != null ? expression(context) : default) { } - public CodeExpression(Func expression) : base(context => expression()) + public CodeExpression(Func expression) : base(context => expression != null ? expression() : default) { } diff --git a/src/core/Elsa.Core/Expressions/ExpressionEvaluator.cs b/src/core/Elsa.Core/Expressions/ExpressionEvaluator.cs index 6210c8e01..b636c0673 100644 --- a/src/core/Elsa.Core/Expressions/ExpressionEvaluator.cs +++ b/src/core/Elsa.Core/Expressions/ExpressionEvaluator.cs @@ -48,6 +48,6 @@ namespace Elsa.Expressions IWorkflowExpression expression, ActivityExecutionContext context, CancellationToken cancellationToken = default) - => (T)await EvaluateAsync((IWorkflowExpression)expression, typeof(T), context, cancellationToken); + => (T)await EvaluateAsync(expression, typeof(T), context, cancellationToken); } } \ No newline at end of file diff --git a/src/core/Elsa.Core/Extensions/ElsaServiceCollectionExtensions.cs b/src/core/Elsa.Core/Extensions/ElsaServiceCollectionExtensions.cs index 844af438d..8fce03bda 100644 --- a/src/core/Elsa.Core/Extensions/ElsaServiceCollectionExtensions.cs +++ b/src/core/Elsa.Core/Extensions/ElsaServiceCollectionExtensions.cs @@ -116,8 +116,8 @@ namespace Microsoft.Extensions.DependencyInjection .AddTransient() .AddTransient() .AddTransient() - .AddTransient() - .AddTransient>(sp => sp.GetRequiredService) + .AddTransient() + .AddTransient>(sp => sp.GetRequiredService) .AddStartupTask() .AddConsumer() .AddAutoMapperProfile(ServiceLifetime.Singleton) diff --git a/src/core/Elsa.Core/WorkflowProviders/CodeWorkflowProvider.cs b/src/core/Elsa.Core/WorkflowProviders/CodeWorkflowProvider.cs index e68b89a4a..29a72ff82 100644 --- a/src/core/Elsa.Core/WorkflowProviders/CodeWorkflowProvider.cs +++ b/src/core/Elsa.Core/WorkflowProviders/CodeWorkflowProvider.cs @@ -15,9 +15,9 @@ namespace Elsa.WorkflowProviders public class CodeWorkflowProvider : IWorkflowProvider { private readonly IEnumerable workflows; - private readonly Func workflowBuilder; + private readonly Func workflowBuilder; - public CodeWorkflowProvider(IEnumerable workflows, Func workflowBuilder) + public CodeWorkflowProvider(IEnumerable workflows, Func workflowBuilder) { this.workflows = workflows; this.workflowBuilder = workflowBuilder; diff --git a/src/samples/Elsa.Samples.CustomActivities/EchoQueryStringWorkflow.cs b/src/samples/Elsa.Samples.CustomActivities/EchoQueryStringWorkflow.cs new file mode 100644 index 000000000..73289ad98 --- /dev/null +++ b/src/samples/Elsa.Samples.CustomActivities/EchoQueryStringWorkflow.cs @@ -0,0 +1,28 @@ +using System.Linq; +using System.Net; +using Elsa.Activities.Http; +using Elsa.Builders; +using Elsa.Services.Models; +using Microsoft.AspNetCore.Http; + +namespace Elsa.Samples.CustomActivities +{ + public class EchoQueryStringWorkflow : IWorkflow + { + public void Build(IWorkflowBuilder builder) + { + builder + .ReceiveHttpRequest("/hello") + .Then() + .WriteHttpResponse(HttpStatusCode.OK, GenerateSomeHtml, "text/html"); + } + + private string GenerateSomeHtml(ActivityExecutionContext context) + { + var query = (IQueryCollection) context.Input.Value; // the output of the previous activity will be available as input to this one. + var items = query.Select(x => $"
  • {x.Key}: {x.Value}
  • "); + + return $"
      {string.Join("\n", items)}
    "; + } + } +} \ No newline at end of file diff --git a/src/samples/Elsa.Samples.CustomActivities/Elsa.Samples.CustomActivities.csproj b/src/samples/Elsa.Samples.CustomActivities/Elsa.Samples.CustomActivities.csproj new file mode 100644 index 000000000..851e92b7e --- /dev/null +++ b/src/samples/Elsa.Samples.CustomActivities/Elsa.Samples.CustomActivities.csproj @@ -0,0 +1,11 @@ + + + + netcoreapp3.1 + + + + + + + diff --git a/src/samples/Elsa.Samples.CustomActivities/Program.cs b/src/samples/Elsa.Samples.CustomActivities/Program.cs new file mode 100644 index 000000000..b736a08be --- /dev/null +++ b/src/samples/Elsa.Samples.CustomActivities/Program.cs @@ -0,0 +1,14 @@ +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Hosting; + +namespace Elsa.Samples.CustomActivities +{ + public class Program + { + public static void Main(string[] args) => CreateHostBuilder(args).Build().Run(); + + public static IHostBuilder CreateHostBuilder(string[] args) => + Host.CreateDefaultBuilder(args) + .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup(); }); + } +} \ No newline at end of file diff --git a/src/samples/Elsa.Samples.CustomActivities/ReadQueryString.cs b/src/samples/Elsa.Samples.CustomActivities/ReadQueryString.cs new file mode 100644 index 000000000..e9fccb653 --- /dev/null +++ b/src/samples/Elsa.Samples.CustomActivities/ReadQueryString.cs @@ -0,0 +1,28 @@ +using Elsa.Models; +using Elsa.Results; +using Elsa.Services; +using Elsa.Services.Models; +using Microsoft.AspNetCore.Http; + +namespace Elsa.Samples.CustomActivities +{ + /// + /// A basic activity that simply reads the query string and returns them as an output value for consumption by other activities. + /// + public class ReadQueryString : Activity + { + private readonly IHttpContextAccessor _httpContextAccessor; + + public ReadQueryString(IHttpContextAccessor httpContextAccessor) + { + _httpContextAccessor = httpContextAccessor; + } + + protected override IActivityExecutionResult OnExecute(ActivityExecutionContext context) + { + var query = _httpContextAccessor.HttpContext.Request.Query; + + return Done(Variable.From(query)); + } + } +} \ No newline at end of file diff --git a/src/samples/Elsa.Samples.CustomActivities/Startup.cs b/src/samples/Elsa.Samples.CustomActivities/Startup.cs new file mode 100644 index 000000000..5d14c48a1 --- /dev/null +++ b/src/samples/Elsa.Samples.CustomActivities/Startup.cs @@ -0,0 +1,22 @@ +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.DependencyInjection; + +namespace Elsa.Samples.CustomActivities +{ + public class Startup + { + public void ConfigureServices(IServiceCollection services) + { + services + .AddElsa() + .AddHttp() + .AddActivity() + .AddWorkflow(); + } + + public void Configure(IApplicationBuilder app) + { + app.UseHttpActivities(); + } + } +} \ No newline at end of file diff --git a/src/samples/Elsa.Samples.CustomActivities/hello.http b/src/samples/Elsa.Samples.CustomActivities/hello.http new file mode 100644 index 000000000..3369a5b04 --- /dev/null +++ b/src/samples/Elsa.Samples.CustomActivities/hello.http @@ -0,0 +1 @@ +GET http://localhost:5000/hello?foo=bar&bar=baz \ No newline at end of file diff --git a/src/samples/Elsa.Samples.HelloWorldConsole/Elsa.Samples.HelloWorldConsole.csproj b/src/samples/Elsa.Samples.HelloWorldConsole/Elsa.Samples.HelloWorldConsole.csproj new file mode 100644 index 000000000..8510c0cd1 --- /dev/null +++ b/src/samples/Elsa.Samples.HelloWorldConsole/Elsa.Samples.HelloWorldConsole.csproj @@ -0,0 +1,16 @@ + + + + Exe + netcoreapp3.1 + + + + + + + + + + + diff --git a/src/samples/Elsa.Samples.HelloWorldConsole/Program.cs b/src/samples/Elsa.Samples.HelloWorldConsole/Program.cs new file mode 100644 index 000000000..70eac4752 --- /dev/null +++ b/src/samples/Elsa.Samples.HelloWorldConsole/Program.cs @@ -0,0 +1,36 @@ +using System; +using System.Threading.Tasks; +using Elsa.Activities.Console; +using Elsa.Builders; +using Elsa.Services; +using Microsoft.Extensions.DependencyInjection; + +namespace Elsa.Samples.HelloWorldConsole +{ + class Program + { + static async Task Main(string[] args) + { + // Create a service container with Elsa services. + var services = new ServiceCollection() + .AddElsa() + .AddConsoleActivities() + .AddSingleton(Console.In) + .BuildServiceProvider(); + + // Build a new workflow. + var workflow = services.GetService() + .WriteLine("Hello World!") + .WriteLine("What's your name?") + .ReadLine() + .WriteLine(context => $"Greetings, {context.Input.Value}!") + .Build(); + + // Get the workflow host. + var workflowHost = services.GetService(); + + // Execute the workflow. + await workflowHost.RunWorkflowAsync(workflow); + } + } +} \ No newline at end of file diff --git a/src/samples/Elsa.Samples.HelloWorldHttp/Elsa.Samples.HelloWorldHttp.csproj b/src/samples/Elsa.Samples.HelloWorldHttp/Elsa.Samples.HelloWorldHttp.csproj new file mode 100644 index 000000000..876533012 --- /dev/null +++ b/src/samples/Elsa.Samples.HelloWorldHttp/Elsa.Samples.HelloWorldHttp.csproj @@ -0,0 +1,11 @@ + + + + netcoreapp3.1 + + + + + + + diff --git a/src/samples/Elsa.Samples.HelloWorldHttp/HelloHttpWorkflow.cs b/src/samples/Elsa.Samples.HelloWorldHttp/HelloHttpWorkflow.cs new file mode 100644 index 000000000..a5ef65982 --- /dev/null +++ b/src/samples/Elsa.Samples.HelloWorldHttp/HelloHttpWorkflow.cs @@ -0,0 +1,17 @@ +using System.Net; +using Elsa.Activities.Http; +using Elsa.Activities.Primitives; +using Elsa.Builders; + +namespace Elsa.Samples.HelloWorldHttp +{ + public class HelloHttpWorkflow : IWorkflow + { + public void Build(IWorkflowBuilder builder) + { + builder + .ReceiveHttpRequest("/hello") + .WriteHttpResponse(HttpStatusCode.OK, "Hello World!"); + } + } +} \ No newline at end of file diff --git a/src/samples/Elsa.Samples.HelloWorldHttp/Program.cs b/src/samples/Elsa.Samples.HelloWorldHttp/Program.cs new file mode 100644 index 000000000..973003035 --- /dev/null +++ b/src/samples/Elsa.Samples.HelloWorldHttp/Program.cs @@ -0,0 +1,14 @@ +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Hosting; + +namespace Elsa.Samples.HelloWorldHttp +{ + public class Program + { + public static void Main(string[] args) => CreateHostBuilder(args).Build().Run(); + + public static IHostBuilder CreateHostBuilder(string[] args) => + Host.CreateDefaultBuilder(args) + .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup(); }); + } +} \ No newline at end of file diff --git a/src/samples/Elsa.Samples.HelloWorldHttp/Startup.cs b/src/samples/Elsa.Samples.HelloWorldHttp/Startup.cs new file mode 100644 index 000000000..413a012fa --- /dev/null +++ b/src/samples/Elsa.Samples.HelloWorldHttp/Startup.cs @@ -0,0 +1,21 @@ +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.DependencyInjection; + +namespace Elsa.Samples.HelloWorldHttp +{ + public class Startup + { + public void ConfigureServices(IServiceCollection services) + { + services + .AddElsa() + .AddHttp() + .AddWorkflow(); + } + + public void Configure(IApplicationBuilder app) + { + app.UseHttpActivities(); + } + } +} \ No newline at end of file diff --git a/src/samples/Elsa.Samples.HelloWorldHttp/hello.http b/src/samples/Elsa.Samples.HelloWorldHttp/hello.http new file mode 100644 index 000000000..f2e1bd7d3 --- /dev/null +++ b/src/samples/Elsa.Samples.HelloWorldHttp/hello.http @@ -0,0 +1 @@ +GET http://localhost:5000/hello \ No newline at end of file diff --git a/src/samples/Elsa.Samples.Serialization/Program.cs b/src/samples/Elsa.Samples.Serialization/Program.cs index e7558ee61..62ca32e34 100644 --- a/src/samples/Elsa.Samples.Serialization/Program.cs +++ b/src/samples/Elsa.Samples.Serialization/Program.cs @@ -18,8 +18,10 @@ namespace Elsa.Samples.Serialization .AddElsa() .AddConsoleActivities() .BuildServiceProvider(); + var activityResolver = services.GetRequiredService(); var writeLine = activityResolver.ResolveActivity().WithText(new LiteralExpression("Foo")); + var workflowDefinition = new WorkflowDefinitionVersion { Activities = new List { ActivityDefinition.FromActivity(writeLine) } @@ -30,8 +32,6 @@ namespace Elsa.Samples.Serialization Console.WriteLine(json); - var workflowDefinition2 = serializer.Deserialize(json, JsonTokenFormatter.FormatName); - } } } \ No newline at end of file diff --git a/src/samples/Elsa.Samples.TimeSheetApproval/Elsa.Samples.TimeSheetApproval.csproj b/src/samples/Elsa.Samples.TimeSheetApproval/Elsa.Samples.TimeSheetApproval.csproj new file mode 100644 index 000000000..2c0dacc01 --- /dev/null +++ b/src/samples/Elsa.Samples.TimeSheetApproval/Elsa.Samples.TimeSheetApproval.csproj @@ -0,0 +1,8 @@ + + + + Exe + netcoreapp3.1 + + + diff --git a/src/samples/Elsa.Samples.TimeSheetApproval/Program.cs b/src/samples/Elsa.Samples.TimeSheetApproval/Program.cs new file mode 100644 index 000000000..cbed6b7a5 --- /dev/null +++ b/src/samples/Elsa.Samples.TimeSheetApproval/Program.cs @@ -0,0 +1,12 @@ +using System; + +namespace Elsa.Samples.TimeSheetApproval +{ + class Program + { + static void Main(string[] args) + { + Console.WriteLine("Hello World!"); + } + } +} \ No newline at end of file