Merge branch 'develop'
# Conflicts: # Samples.sln # src/activities/Elsa.Activities.Timers/Elsa.Activities.Timers.csproj # src/core/Elsa.Abstractions/Services/IActivityBuilder.cs # src/core/Elsa.Core/Elsa.Core.csproj # src/core/Elsa.Core/WorkflowBuilders/ActivityBuilder.cs # src/samples/Sample17/Activities/CreatePerson.cs # src/samples/Sample17/CreatePersonWorkflow.cs # src/samples/Sample17/Program.cs # src/samples/Sample17/Sample17.csproj
This commit is contained in:
commit
bc04b00196
55
Elsa.sln
55
Elsa.sln
|
|
@ -37,8 +37,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Persistence.YesSql", "
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Activities.UserTask", "src\activities\Elsa.Activities.UserTask\Elsa.Activities.UserTask.csproj", "{BC0F57E2-AB64-4026-B6E3-E03D9133DB26}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.AutoMapper.Extensions", "src\core\Elsa.AutoMapper.Extensions\Elsa.AutoMapper.Extensions.csproj", "{6CEF6AFB-635D-4FB4-B9EC-0806DD95E1BC}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Persistence.EntityFrameworkCore", "src\persistence\Elsa.Persistence.EntityFrameworkCore\Elsa.Persistence.EntityFrameworkCore.csproj", "{349D4C87-E17F-4F51-B493-1994BF631D37}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "dashboard", "dashboard", "{8B87D79A-F0DE-4F88-81D3-8C8C69108ADB}"
|
||||
|
|
@ -53,6 +51,22 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Persistence.DocumentDb
|
|||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Activities.Dropbox", "src\activities\Elsa.Activities.Dropbox\Elsa.Activities.Dropbox.csproj", "{5A3C9D59-21FE-4BE3-A00A-FF3F198EEC97}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "utils", "utils", "{9E1AF14C-0BEC-4BC2-810C-85FC25A9DDD4}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "scripting", "scripting", "{5E230C5F-7A64-4E95-A790-DF40CC66DA31}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.AutoMapper.Extensions", "src\utils\Elsa.AutoMapper.Extensions\Elsa.AutoMapper.Extensions.csproj", "{72DA50EC-8A99-4D4F-BF61-DEF105BDAE10}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Scripting.JavaScript", "src\scripting\Elsa.Scripting.JavaScript\Elsa.Scripting.JavaScript.csproj", "{DA91DAF2-4C59-4468-8F1D-6A500D218A1E}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Scripting.Liquid", "src\scripting\Elsa.Scripting.Liquid\Elsa.Scripting.Liquid.csproj", "{9A2D1E3E-328F-4E02-86F8-84974925C1E3}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Activities.ControlFlow", "src\activities\Elsa.Activities.ControlFlow\Elsa.Activities.ControlFlow.csproj", "{3FC85C9D-CC20-4F54-9936-029F19FBFBE1}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Activities.Workflows", "src\activities\Elsa.Activities.Workflows\Elsa.Activities.Workflows.csproj", "{1BB8EC9E-AEBD-438B-9FA7-B7FA78999D7D}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa", "src\core\Elsa\Elsa.csproj", "{ED2A4FE5-821B-46F7-B72F-E66DE0D66C93}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
|
@ -95,10 +109,6 @@ Global
|
|||
{BC0F57E2-AB64-4026-B6E3-E03D9133DB26}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{BC0F57E2-AB64-4026-B6E3-E03D9133DB26}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{BC0F57E2-AB64-4026-B6E3-E03D9133DB26}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{6CEF6AFB-635D-4FB4-B9EC-0806DD95E1BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{6CEF6AFB-635D-4FB4-B9EC-0806DD95E1BC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{6CEF6AFB-635D-4FB4-B9EC-0806DD95E1BC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{6CEF6AFB-635D-4FB4-B9EC-0806DD95E1BC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{349D4C87-E17F-4F51-B493-1994BF631D37}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{349D4C87-E17F-4F51-B493-1994BF631D37}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{349D4C87-E17F-4F51-B493-1994BF631D37}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
|
|
@ -123,6 +133,30 @@ Global
|
|||
{5A3C9D59-21FE-4BE3-A00A-FF3F198EEC97}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{5A3C9D59-21FE-4BE3-A00A-FF3F198EEC97}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{5A3C9D59-21FE-4BE3-A00A-FF3F198EEC97}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{72DA50EC-8A99-4D4F-BF61-DEF105BDAE10}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{72DA50EC-8A99-4D4F-BF61-DEF105BDAE10}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{72DA50EC-8A99-4D4F-BF61-DEF105BDAE10}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{72DA50EC-8A99-4D4F-BF61-DEF105BDAE10}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{DA91DAF2-4C59-4468-8F1D-6A500D218A1E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{DA91DAF2-4C59-4468-8F1D-6A500D218A1E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{DA91DAF2-4C59-4468-8F1D-6A500D218A1E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{DA91DAF2-4C59-4468-8F1D-6A500D218A1E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{9A2D1E3E-328F-4E02-86F8-84974925C1E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9A2D1E3E-328F-4E02-86F8-84974925C1E3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9A2D1E3E-328F-4E02-86F8-84974925C1E3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{9A2D1E3E-328F-4E02-86F8-84974925C1E3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{3FC85C9D-CC20-4F54-9936-029F19FBFBE1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3FC85C9D-CC20-4F54-9936-029F19FBFBE1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3FC85C9D-CC20-4F54-9936-029F19FBFBE1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3FC85C9D-CC20-4F54-9936-029F19FBFBE1}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{1BB8EC9E-AEBD-438B-9FA7-B7FA78999D7D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{1BB8EC9E-AEBD-438B-9FA7-B7FA78999D7D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1BB8EC9E-AEBD-438B-9FA7-B7FA78999D7D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1BB8EC9E-AEBD-438B-9FA7-B7FA78999D7D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{ED2A4FE5-821B-46F7-B72F-E66DE0D66C93}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{ED2A4FE5-821B-46F7-B72F-E66DE0D66C93}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{ED2A4FE5-821B-46F7-B72F-E66DE0D66C93}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{ED2A4FE5-821B-46F7-B72F-E66DE0D66C93}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
@ -140,7 +174,6 @@ Global
|
|||
{76710230-AC6D-4E54-9A06-15F34C155118} = {DA71CDAA-8DD3-4D5F-9FBD-8E4B37A2D925}
|
||||
{4DB0741F-EAD9-4E37-862D-A1DA12462B7D} = {76710230-AC6D-4E54-9A06-15F34C155118}
|
||||
{BC0F57E2-AB64-4026-B6E3-E03D9133DB26} = {B43B546E-23F3-46E8-ACB7-D04F05CDA180}
|
||||
{6CEF6AFB-635D-4FB4-B9EC-0806DD95E1BC} = {35F44BE9-13D0-417C-A01A-F0787BEE6DC3}
|
||||
{349D4C87-E17F-4F51-B493-1994BF631D37} = {76710230-AC6D-4E54-9A06-15F34C155118}
|
||||
{8B87D79A-F0DE-4F88-81D3-8C8C69108ADB} = {DA71CDAA-8DD3-4D5F-9FBD-8E4B37A2D925}
|
||||
{493FC3E3-34FE-4F8D-AF37-38A5F5541FBD} = {8B87D79A-F0DE-4F88-81D3-8C8C69108ADB}
|
||||
|
|
@ -148,6 +181,14 @@ Global
|
|||
{120E4BF9-4A42-4BB9-A0B2-9597160D6E37} = {8B87D79A-F0DE-4F88-81D3-8C8C69108ADB}
|
||||
{39EBECE7-538B-431C-AAB7-901AB16E6D4A} = {76710230-AC6D-4E54-9A06-15F34C155118}
|
||||
{5A3C9D59-21FE-4BE3-A00A-FF3F198EEC97} = {B43B546E-23F3-46E8-ACB7-D04F05CDA180}
|
||||
{9E1AF14C-0BEC-4BC2-810C-85FC25A9DDD4} = {DA71CDAA-8DD3-4D5F-9FBD-8E4B37A2D925}
|
||||
{5E230C5F-7A64-4E95-A790-DF40CC66DA31} = {DA71CDAA-8DD3-4D5F-9FBD-8E4B37A2D925}
|
||||
{72DA50EC-8A99-4D4F-BF61-DEF105BDAE10} = {9E1AF14C-0BEC-4BC2-810C-85FC25A9DDD4}
|
||||
{DA91DAF2-4C59-4468-8F1D-6A500D218A1E} = {5E230C5F-7A64-4E95-A790-DF40CC66DA31}
|
||||
{9A2D1E3E-328F-4E02-86F8-84974925C1E3} = {5E230C5F-7A64-4E95-A790-DF40CC66DA31}
|
||||
{3FC85C9D-CC20-4F54-9936-029F19FBFBE1} = {B43B546E-23F3-46E8-ACB7-D04F05CDA180}
|
||||
{1BB8EC9E-AEBD-438B-9FA7-B7FA78999D7D} = {B43B546E-23F3-46E8-ACB7-D04F05CDA180}
|
||||
{ED2A4FE5-821B-46F7-B72F-E66DE0D66C93} = {35F44BE9-13D0-417C-A01A-F0787BEE6DC3}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {8B0975FD-7050-48B0-88C5-48C33378E158}
|
||||
|
|
|
|||
167
README.md
167
README.md
|
|
@ -10,6 +10,41 @@ Workflows can be defined not only using code but also as JSON, YAML or XML.
|
|||
|
||||
Follow the [Getting Started](https://elsa-workflows.github.io/elsa-core/docs/installing-elsa-core) instructions on the [Elsa Workflows documentation site](https://elsa-workflows.github.io/elsa-core).
|
||||
|
||||
## Roadmap
|
||||
|
||||
Version 1.0
|
||||
|
||||
- [x] Workflow Invoker
|
||||
- [x] Long-running Workflows
|
||||
- [x] Workflows as code
|
||||
- [x] Workflows as data
|
||||
- [x] Correlation
|
||||
- [x] Persistence: CosmosDB, Entity Framework Core, MongoDB, YesSQL
|
||||
- [x] HTML5 Workflow Designer Web Component
|
||||
- [x] ASP.NET Core Workflow Dashboard
|
||||
- [x] JavaScript Expressions
|
||||
- [x] Liquid Expressions
|
||||
- [x] Primitive Activities
|
||||
- [X] Control Flow Activities
|
||||
- [x] Workflow Activities
|
||||
- [x] Timer Activities
|
||||
- [x] HTTP Activities
|
||||
- [x] Email Activities
|
||||
|
||||
Version 2.0
|
||||
|
||||
- [ ] Service Bus Messaging
|
||||
- [ ] Generic Command & Event Activities
|
||||
- [ ] Workflow Host REST API
|
||||
- [ ] Workflow Host gRPC API
|
||||
- [ ] Distributed Hosting Support (support for multi-node environments)
|
||||
- [ ] Localization Support
|
||||
|
||||
Version 3.0
|
||||
|
||||
- [ ] State Machines
|
||||
- [ ] Container Activities
|
||||
|
||||
## Workflow Designer
|
||||
|
||||
Workflows can be visually designed using [Elsa Designer](https://github.com/elsa-workflows/elsa-designer-html), a reusable & extensible HTML5 web component built with [StencilJS](https://stenciljs.com/).
|
||||
|
|
@ -69,107 +104,6 @@ The following providers will be supported:
|
|||
Currently, workflows can be stored in YAML or JSON format.
|
||||
The following demonstrates a simple workflow expressed in YAML and JSON, respectively:
|
||||
|
||||
**YAML**
|
||||
```yaml
|
||||
activities:
|
||||
- name: WriteLine
|
||||
id: activity-1
|
||||
textExpression:
|
||||
syntax: PlainText
|
||||
expression: Hi! What's your name?
|
||||
- name: ReadLine
|
||||
id: activity-2
|
||||
argumentName: name
|
||||
- name: WriteLine
|
||||
id: activity-3
|
||||
textExpression:
|
||||
syntax: JavaScript
|
||||
expression: '`Nice to meet you, ${name}!`'
|
||||
connections:
|
||||
- source:
|
||||
activityId: activity-1
|
||||
name: Done
|
||||
target:
|
||||
activityId: activity-2
|
||||
- source:
|
||||
activityId: activity-2
|
||||
name: Done
|
||||
target:
|
||||
activityId: activity-3
|
||||
```
|
||||
|
||||
**JSON**
|
||||
```json
|
||||
{
|
||||
"activities": [
|
||||
{
|
||||
"name": "WriteLine",
|
||||
"id": "activity-1",
|
||||
"textExpression": {
|
||||
"syntax": "PlainText",
|
||||
"expression": "Hi! What's your name?"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "activity-2",
|
||||
"name": "ReadLine",
|
||||
"argumentName": "name"
|
||||
},
|
||||
{
|
||||
"name": "WriteLine",
|
||||
"id": "activity-3",
|
||||
"textExpression": {
|
||||
"syntax": "JavaScript",
|
||||
"expression": "`Nice to meet you, ${name}!`"
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": [
|
||||
{
|
||||
"source": {
|
||||
"activityId": "activity-1",
|
||||
"name": "Done"
|
||||
},
|
||||
"target": {
|
||||
"activityId": "activity-2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": {
|
||||
"activityId": "activity-2",
|
||||
"name": "Done"
|
||||
},
|
||||
"target": {
|
||||
"activityId": "activity-3"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
The following demonstrates loading a workflow from a YAML string:
|
||||
|
||||
```c#
|
||||
// Setup a service collection and use the FileSystemProvider for both workflow definitions and workflow instances.
|
||||
var services = new ServiceCollection()
|
||||
.AddWorkflowsInvoker()
|
||||
.AddConsoleActivities()
|
||||
.AddSingleton(Console.In)
|
||||
.BuildServiceProvider();
|
||||
|
||||
// Load the data and specify data format.
|
||||
var data = Resources.SampleWorkflowDefinition;
|
||||
var format = YamlTokenFormatter.FormatName; // "YAML"
|
||||
|
||||
// Deserialize the workflow from data.
|
||||
var serializer = services.GetService<IWorkflowSerializer>();
|
||||
var workflowDefinition = await serializer.DeserializeAsync(data, format, CancellationToken.None);
|
||||
|
||||
// Invoke the workflow.
|
||||
var invoker = services.GetService<IWorkflowInvoker>();
|
||||
await invoker.InvokeAsync(workflowDefinition);
|
||||
```
|
||||
|
||||
## Long Running Workflows
|
||||
|
||||
Elsa has native support for long-running workflows. As soon as a workflow is halted because of some blocking activity, the workflow is persisted.
|
||||
|
|
@ -240,35 +174,12 @@ TODO: describe all the steps to add packages and register services.
|
|||
|
||||
TODO: describe all the steps to add packages and register services.
|
||||
|
||||
## Running Elsa Workflows Dashboard
|
||||
### Building & Running Elsa Workflows Dashboard
|
||||
|
||||
In order to run Elsa on your local machine, follow these steps:
|
||||
In order to build & run Elsa on your local machine, follow these steps:
|
||||
|
||||
1. Clone the repository.
|
||||
2. Run NPM install on all folders containing packages.json (or run `node npm-install.js` - a script in the root that recursively installs the Node packages)
|
||||
3. Execute gulp build from the directory src\dashboard\Elsa.Dashboard\Theme\argon-dashboard
|
||||
4. Open a shell and navigate to `src/samples/SampleDashboard.Web` and run `dotnet run`.
|
||||
5. Navigate to https://localhost:44397/elsa/home
|
||||
|
||||
## Running Elsa Workflows Host
|
||||
|
||||
(TODO)
|
||||
|
||||
## Roadmap
|
||||
|
||||
(TODO)
|
||||
|
||||
- Describe all the features (core engine, runtime, webbased designer, YAML, scripting, separation of designer from invoker from engine).
|
||||
- Describe various use cases.
|
||||
- Describe how to use.
|
||||
- Describe architecture.
|
||||
- Describe how to implement (custom host, custom dashboard).
|
||||
- Implement more activities
|
||||
- Implement integration with Orchard Core (separate repo)
|
||||
- Detailed documentation
|
||||
- Open API Activity Harvester
|
||||
- MassTransit Activity Harvester
|
||||
- RabbitMQ Activities
|
||||
- Azure Service Bus Activities
|
||||
- Automatic UI for Activity Editor
|
||||
|
||||
4. Open a shell and navigate to `src/samples/Sample16` and run `dotnet run`.
|
||||
5. Navigate to https://localhost:8632/elsa/home
|
||||
62
Samples.sln
62
Samples.sln
|
|
@ -57,8 +57,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Persistence.YesSql", "
|
|||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sample10", "src\samples\Sample10\Sample10.csproj", "{E0076858-353F-4302-9690-920204E38BF6}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.AutoMapper.Extensions", "src\core\Elsa.AutoMapper.Extensions\Elsa.AutoMapper.Extensions.csproj", "{F7633BE5-0335-4148-8FB7-EAED9A2276A2}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sample11", "src\samples\Sample11\Sample11.csproj", "{0C3BB425-2FED-4ADF-8DBE-D68DF0CA5A41}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Activities.UserTask", "src\activities\Elsa.Activities.UserTask\Elsa.Activities.UserTask.csproj", "{823F80B6-E241-43F7-83BD-29FBB58A77F9}"
|
||||
|
|
@ -89,6 +87,24 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sample16", "src\samples\Sam
|
|||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sample17", "src\samples\Sample17\Sample17.csproj", "{8854DF17-D566-49C9-8210-68AB8F5659FA}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "scripting", "scripting", "{9C3C685E-3D7D-4638-A031-24F71CF74B52}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Activities.ControlFlow", "src\activities\Elsa.Activities.ControlFlow\Elsa.Activities.ControlFlow.csproj", "{1F8E7DFB-824E-4B9F-9866-482B191CF005}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Activities.Workflows", "src\activities\Elsa.Activities.Workflows\Elsa.Activities.Workflows.csproj", "{9017817D-A3D1-4068-97BF-FCA1EF3BFC50}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa", "src\core\Elsa\Elsa.csproj", "{6BB5EB72-AD9A-41ED-A6AA-0FF1093EA41B}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Scripting.JavaScript", "src\scripting\Elsa.Scripting.JavaScript\Elsa.Scripting.JavaScript.csproj", "{18BE8F72-E528-4617-B1B1-07BD35337DFC}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Scripting.Liquid", "src\scripting\Elsa.Scripting.Liquid\Elsa.Scripting.Liquid.csproj", "{01DC21DD-C6E2-4B21-864E-97D29448F777}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "utils", "utils", "{0D276728-DDA8-46A0-91A9-D44401D66DA9}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.AutoMapper.Extensions", "src\utils\Elsa.AutoMapper.Extensions\Elsa.AutoMapper.Extensions.csproj", "{102626A4-8BA6-45A8-A69C-F5EB1F155BE7}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sample18", "src\samples\Sample18\Sample18.csproj", "{616AA0BA-FBDD-4ABE-B688-A3F79F38C698}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
|
@ -167,10 +183,6 @@ Global
|
|||
{E0076858-353F-4302-9690-920204E38BF6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E0076858-353F-4302-9690-920204E38BF6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E0076858-353F-4302-9690-920204E38BF6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F7633BE5-0335-4148-8FB7-EAED9A2276A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F7633BE5-0335-4148-8FB7-EAED9A2276A2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F7633BE5-0335-4148-8FB7-EAED9A2276A2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F7633BE5-0335-4148-8FB7-EAED9A2276A2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{0C3BB425-2FED-4ADF-8DBE-D68DF0CA5A41}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0C3BB425-2FED-4ADF-8DBE-D68DF0CA5A41}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0C3BB425-2FED-4ADF-8DBE-D68DF0CA5A41}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
|
|
@ -227,6 +239,34 @@ Global
|
|||
{8854DF17-D566-49C9-8210-68AB8F5659FA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8854DF17-D566-49C9-8210-68AB8F5659FA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8854DF17-D566-49C9-8210-68AB8F5659FA}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{1F8E7DFB-824E-4B9F-9866-482B191CF005}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{1F8E7DFB-824E-4B9F-9866-482B191CF005}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1F8E7DFB-824E-4B9F-9866-482B191CF005}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1F8E7DFB-824E-4B9F-9866-482B191CF005}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{9017817D-A3D1-4068-97BF-FCA1EF3BFC50}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9017817D-A3D1-4068-97BF-FCA1EF3BFC50}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9017817D-A3D1-4068-97BF-FCA1EF3BFC50}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{9017817D-A3D1-4068-97BF-FCA1EF3BFC50}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{6BB5EB72-AD9A-41ED-A6AA-0FF1093EA41B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{6BB5EB72-AD9A-41ED-A6AA-0FF1093EA41B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{6BB5EB72-AD9A-41ED-A6AA-0FF1093EA41B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{6BB5EB72-AD9A-41ED-A6AA-0FF1093EA41B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{18BE8F72-E528-4617-B1B1-07BD35337DFC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{18BE8F72-E528-4617-B1B1-07BD35337DFC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{18BE8F72-E528-4617-B1B1-07BD35337DFC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{18BE8F72-E528-4617-B1B1-07BD35337DFC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{01DC21DD-C6E2-4B21-864E-97D29448F777}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{01DC21DD-C6E2-4B21-864E-97D29448F777}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{01DC21DD-C6E2-4B21-864E-97D29448F777}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{01DC21DD-C6E2-4B21-864E-97D29448F777}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{102626A4-8BA6-45A8-A69C-F5EB1F155BE7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{102626A4-8BA6-45A8-A69C-F5EB1F155BE7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{102626A4-8BA6-45A8-A69C-F5EB1F155BE7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{102626A4-8BA6-45A8-A69C-F5EB1F155BE7}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{616AA0BA-FBDD-4ABE-B688-A3F79F38C698}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{616AA0BA-FBDD-4ABE-B688-A3F79F38C698}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{616AA0BA-FBDD-4ABE-B688-A3F79F38C698}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{616AA0BA-FBDD-4ABE-B688-A3F79F38C698}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
@ -253,7 +293,6 @@ Global
|
|||
{600C4AE0-0585-4181-9CEC-2BB43430C713} = {DA71CDAA-8DD3-4D5F-9FBD-8E4B37A2D925}
|
||||
{905C1067-2119-443D-B5FE-DA8E027FAD62} = {600C4AE0-0585-4181-9CEC-2BB43430C713}
|
||||
{E0076858-353F-4302-9690-920204E38BF6} = {5E5E1E84-DDBC-40D6-B891-0D563A15A44A}
|
||||
{F7633BE5-0335-4148-8FB7-EAED9A2276A2} = {35F44BE9-13D0-417C-A01A-F0787BEE6DC3}
|
||||
{0C3BB425-2FED-4ADF-8DBE-D68DF0CA5A41} = {5E5E1E84-DDBC-40D6-B891-0D563A15A44A}
|
||||
{823F80B6-E241-43F7-83BD-29FBB58A77F9} = {B43B546E-23F3-46E8-ACB7-D04F05CDA180}
|
||||
{D0F68FBB-17C6-421E-B8AE-AAAFE111BF0B} = {5E5E1E84-DDBC-40D6-B891-0D563A15A44A}
|
||||
|
|
@ -270,6 +309,15 @@ Global
|
|||
{8C51A528-F9B5-464E-AAD1-1ADC44697085} = {600C4AE0-0585-4181-9CEC-2BB43430C713}
|
||||
{DFE72CF4-C77C-4932-A00F-A8D325E603CE} = {5E5E1E84-DDBC-40D6-B891-0D563A15A44A}
|
||||
{8854DF17-D566-49C9-8210-68AB8F5659FA} = {5E5E1E84-DDBC-40D6-B891-0D563A15A44A}
|
||||
{9C3C685E-3D7D-4638-A031-24F71CF74B52} = {DA71CDAA-8DD3-4D5F-9FBD-8E4B37A2D925}
|
||||
{1F8E7DFB-824E-4B9F-9866-482B191CF005} = {B43B546E-23F3-46E8-ACB7-D04F05CDA180}
|
||||
{9017817D-A3D1-4068-97BF-FCA1EF3BFC50} = {B43B546E-23F3-46E8-ACB7-D04F05CDA180}
|
||||
{6BB5EB72-AD9A-41ED-A6AA-0FF1093EA41B} = {35F44BE9-13D0-417C-A01A-F0787BEE6DC3}
|
||||
{18BE8F72-E528-4617-B1B1-07BD35337DFC} = {9C3C685E-3D7D-4638-A031-24F71CF74B52}
|
||||
{01DC21DD-C6E2-4B21-864E-97D29448F777} = {9C3C685E-3D7D-4638-A031-24F71CF74B52}
|
||||
{0D276728-DDA8-46A0-91A9-D44401D66DA9} = {DA71CDAA-8DD3-4D5F-9FBD-8E4B37A2D925}
|
||||
{102626A4-8BA6-45A8-A69C-F5EB1F155BE7} = {0D276728-DDA8-46A0-91A9-D44401D66DA9}
|
||||
{616AA0BA-FBDD-4ABE-B688-A3F79F38C698} = {5E5E1E84-DDBC-40D6-B891-0D563A15A44A}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {8B0975FD-7050-48B0-88C5-48C33378E158}
|
||||
|
|
|
|||
|
|
@ -13,11 +13,8 @@ namespace Elsa.Activities.Console.Activities
|
|||
/// </summary>
|
||||
[ActivityDefinition(
|
||||
Category = "Console",
|
||||
Description = "Read text from standard in."
|
||||
)]
|
||||
[ActivityDefinitionDesigner(
|
||||
Description =
|
||||
"a => !!a.state.variableName ? `Read text from standard in and store into <strong>${ a.state.variableName }</strong>.` : 'Read text from standard in.'",
|
||||
Description = "Read text from standard in.",
|
||||
RuntimeDescription = "a => !!a.state.variableName ? `Read text from standard in and store into <strong>${ a.state.variableName }</strong>.` : 'Read text from standard in.'",
|
||||
Outcomes = new[] { OutcomeNames.Done }
|
||||
)]
|
||||
public class ReadLine : Activity
|
||||
|
|
|
|||
|
|
@ -15,11 +15,8 @@ namespace Elsa.Activities.Console.Activities
|
|||
/// </summary>
|
||||
[ActivityDefinition(
|
||||
Category = "Console",
|
||||
Description = "Write text to standard out."
|
||||
)]
|
||||
[ActivityDefinitionDesigner(
|
||||
Description =
|
||||
"x => !!x.state.textExpression ? `Write <strong>${ x.state.textExpression.expression }</strong> to standard out.` : x.definition.description",
|
||||
Description = "Write text to standard out.",
|
||||
RuntimeDescription = "x => !!x.state.textExpression ? `Write <strong>${ x.state.textExpression.expression }</strong> to standard out.` : x.definition.description",
|
||||
Outcomes = new[] { OutcomeNames.Done }
|
||||
)]
|
||||
public class WriteLine : Activity
|
||||
|
|
|
|||
|
|
@ -17,8 +17,4 @@
|
|||
<ProjectReference Include="..\..\core\Elsa.Core\Elsa.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.CSharp" Version="4.5.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -1,70 +1,71 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Elsa.Attributes;
|
||||
using Elsa.Expressions;
|
||||
using Elsa.Extensions;
|
||||
using Elsa.Results;
|
||||
using Elsa.Services;
|
||||
using Elsa.Services.Models;
|
||||
|
||||
namespace Elsa.Activities.ControlFlow
|
||||
{
|
||||
[ActivityDefinition(Category = "Control Flow", Description = "Iterate over a collection.", Icon = "far fa-circle")]
|
||||
public class ForEach : Activity
|
||||
{
|
||||
private readonly IWorkflowExpressionEvaluator expressionEvaluator;
|
||||
|
||||
public ForEach(IWorkflowExpressionEvaluator expressionEvaluator)
|
||||
{
|
||||
this.expressionEvaluator = expressionEvaluator;
|
||||
}
|
||||
|
||||
[ActivityProperty(Hint = "Enter an expression that evaluates to an array of items to iterate over.")]
|
||||
public WorkflowExpression<IList<object>> CollectionExpression
|
||||
{
|
||||
get => GetState(() => new JavaScriptExpression<IList<object>>("[]"));
|
||||
set => SetState(value);
|
||||
}
|
||||
|
||||
[ActivityProperty(Hint = "Enter a name for the iterator variable.")]
|
||||
public string IteratorName
|
||||
{
|
||||
get => GetState(() => "CurrentValue");
|
||||
set => SetState(value);
|
||||
}
|
||||
|
||||
public int CurrentIndex
|
||||
{
|
||||
get => GetState(() => 0);
|
||||
set => SetState(value);
|
||||
}
|
||||
|
||||
protected override async Task<ActivityExecutionResult> OnExecuteAsync(
|
||||
WorkflowExecutionContext context,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var collection = await expressionEvaluator.EvaluateAsync(CollectionExpression, context, cancellationToken);
|
||||
var index = CurrentIndex;
|
||||
|
||||
if (index >= collection.Count)
|
||||
{
|
||||
context.EndScope();
|
||||
CurrentIndex = 0;
|
||||
return Done();
|
||||
}
|
||||
|
||||
var value = collection[index];
|
||||
CurrentIndex++;
|
||||
|
||||
if (index == 0)
|
||||
{
|
||||
context.BeginScope();
|
||||
}
|
||||
|
||||
context.CurrentScope.SetVariable(IteratorName, value);
|
||||
|
||||
return Outcome(OutcomeNames.Iterate);
|
||||
}
|
||||
}
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Elsa.Attributes;
|
||||
using Elsa.Expressions;
|
||||
using Elsa.Extensions;
|
||||
using Elsa.Results;
|
||||
using Elsa.Scripting.JavaScript;
|
||||
using Elsa.Services;
|
||||
using Elsa.Services.Models;
|
||||
|
||||
namespace Elsa.Activities.ControlFlow.Activities
|
||||
{
|
||||
[ActivityDefinition(Category = "Control Flow", Description = "Iterate over a collection.", Icon = "far fa-circle")]
|
||||
public class ForEach : Activity
|
||||
{
|
||||
private readonly IWorkflowExpressionEvaluator expressionEvaluator;
|
||||
|
||||
public ForEach(IWorkflowExpressionEvaluator expressionEvaluator)
|
||||
{
|
||||
this.expressionEvaluator = expressionEvaluator;
|
||||
}
|
||||
|
||||
[ActivityProperty(Hint = "Enter an expression that evaluates to an array of items to iterate over.")]
|
||||
public WorkflowExpression<IList<object>> CollectionExpression
|
||||
{
|
||||
get => GetState(() => new JavaScriptExpression<IList<object>>("[]"));
|
||||
set => SetState(value);
|
||||
}
|
||||
|
||||
[ActivityProperty(Hint = "Enter a name for the iterator variable.")]
|
||||
public string IteratorName
|
||||
{
|
||||
get => GetState(() => "CurrentValue");
|
||||
set => SetState(value);
|
||||
}
|
||||
|
||||
public int CurrentIndex
|
||||
{
|
||||
get => GetState(() => 0);
|
||||
set => SetState(value);
|
||||
}
|
||||
|
||||
protected override async Task<ActivityExecutionResult> OnExecuteAsync(
|
||||
WorkflowExecutionContext context,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var collection = await expressionEvaluator.EvaluateAsync(CollectionExpression, context, cancellationToken);
|
||||
var index = CurrentIndex;
|
||||
|
||||
if (index >= collection.Count)
|
||||
{
|
||||
context.EndScope();
|
||||
CurrentIndex = 0;
|
||||
return Done();
|
||||
}
|
||||
|
||||
var value = collection[index];
|
||||
CurrentIndex++;
|
||||
|
||||
if (index == 0)
|
||||
{
|
||||
context.BeginScope();
|
||||
}
|
||||
|
||||
context.CurrentScope.SetVariable(IteratorName, value);
|
||||
|
||||
return Outcome(OutcomeNames.Iterate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,30 +1,30 @@
|
|||
using System.Collections.Generic;
|
||||
using Elsa.Attributes;
|
||||
using Elsa.Results;
|
||||
using Elsa.Services;
|
||||
using Elsa.Services.Models;
|
||||
|
||||
namespace Elsa.Activities.ControlFlow
|
||||
{
|
||||
[ActivityDefinition(
|
||||
Category = "Control Flow",
|
||||
Description = "Fork workflow execution into multiple branches.",
|
||||
Icon = "fas fa-code-branch fa-rotate-180")]
|
||||
[ActivityDefinitionDesigner(Outcomes = "x => x.state.branches")]
|
||||
public class Fork : Activity
|
||||
{
|
||||
[ActivityProperty(
|
||||
Hint = "Enter one or more names representing branches, separated with a comma. Example: Branch 1, Branch 2"
|
||||
)]
|
||||
public IList<string> Branches
|
||||
{
|
||||
get => GetState(() => new List<string>());
|
||||
set => SetState(value);
|
||||
}
|
||||
|
||||
protected override ActivityExecutionResult OnExecute(WorkflowExecutionContext workflowContext)
|
||||
{
|
||||
return Outcomes(Branches);
|
||||
}
|
||||
}
|
||||
using System.Collections.Generic;
|
||||
using Elsa.Attributes;
|
||||
using Elsa.Results;
|
||||
using Elsa.Services;
|
||||
using Elsa.Services.Models;
|
||||
|
||||
namespace Elsa.Activities.ControlFlow.Activities
|
||||
{
|
||||
[ActivityDefinition(
|
||||
Category = "Control Flow",
|
||||
Description = "Fork workflow execution into multiple branches.",
|
||||
Icon = "fas fa-code-branch fa-rotate-180",
|
||||
Outcomes = "x => x.state.branches")]
|
||||
public class Fork : Activity
|
||||
{
|
||||
[ActivityProperty(
|
||||
Hint = "Enter one or more names representing branches, separated with a comma. Example: Branch 1, Branch 2"
|
||||
)]
|
||||
public IList<string> Branches
|
||||
{
|
||||
get => GetState(() => new List<string>());
|
||||
set => SetState(value);
|
||||
}
|
||||
|
||||
protected override ActivityExecutionResult OnExecute(WorkflowExecutionContext workflowContext)
|
||||
{
|
||||
return Outcomes(Branches);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,49 +1,47 @@
|
|||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Elsa.Attributes;
|
||||
using Elsa.Expressions;
|
||||
using Elsa.Extensions;
|
||||
using Elsa.Results;
|
||||
using Elsa.Services;
|
||||
using Elsa.Services.Models;
|
||||
|
||||
namespace Elsa.Activities.ControlFlow
|
||||
{
|
||||
[ActivityDefinition(
|
||||
DisplayName = "If/Else",
|
||||
Category = "Control Flow",
|
||||
Description = "Evaluate a Boolean expression and continue execution depending on the result."
|
||||
)]
|
||||
[ActivityDefinitionDesigner(
|
||||
Description =
|
||||
"x => !!x.state.expression ? `Evaluate <strong>${ x.state.expression.expression }</strong> and continue execution depending on the result.` : x.definition.description",
|
||||
Outcomes = new[] { OutcomeNames.True, OutcomeNames.False }
|
||||
)]
|
||||
public class IfElse : Activity
|
||||
{
|
||||
private readonly IWorkflowExpressionEvaluator expressionEvaluator;
|
||||
|
||||
public IfElse(IWorkflowExpressionEvaluator expressionEvaluator)
|
||||
{
|
||||
this.expressionEvaluator = expressionEvaluator;
|
||||
}
|
||||
|
||||
[ActivityProperty(Hint = "The expression to evaluate. The evaluated value will be used to switch on.")]
|
||||
public WorkflowExpression<bool> ConditionExpression
|
||||
{
|
||||
get => GetState(() => new JavaScriptExpression<bool>("true"));
|
||||
set => SetState(value);
|
||||
}
|
||||
|
||||
protected override async Task<ActivityExecutionResult> OnExecuteAsync(WorkflowExecutionContext workflowContext,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var result = await expressionEvaluator.EvaluateAsync(
|
||||
ConditionExpression,
|
||||
workflowContext,
|
||||
cancellationToken
|
||||
);
|
||||
return Outcome(result ? OutcomeNames.True : OutcomeNames.False);
|
||||
}
|
||||
}
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Elsa.Attributes;
|
||||
using Elsa.Expressions;
|
||||
using Elsa.Extensions;
|
||||
using Elsa.Results;
|
||||
using Elsa.Scripting.JavaScript;
|
||||
using Elsa.Services;
|
||||
using Elsa.Services.Models;
|
||||
|
||||
namespace Elsa.Activities.ControlFlow.Activities
|
||||
{
|
||||
[ActivityDefinition(
|
||||
DisplayName = "If/Else",
|
||||
Category = "Control Flow",
|
||||
Description = "Evaluate a Boolean expression and continue execution depending on the result.",
|
||||
RuntimeDescription = "x => !!x.state.expression ? `Evaluate <strong>${ x.state.expression.expression }</strong> and continue execution depending on the result.` : x.definition.description",
|
||||
Outcomes = new[] { OutcomeNames.True, OutcomeNames.False }
|
||||
)]
|
||||
public class IfElse : Activity
|
||||
{
|
||||
private readonly IWorkflowExpressionEvaluator expressionEvaluator;
|
||||
|
||||
public IfElse(IWorkflowExpressionEvaluator expressionEvaluator)
|
||||
{
|
||||
this.expressionEvaluator = expressionEvaluator;
|
||||
}
|
||||
|
||||
[ActivityProperty(Hint = "The expression to evaluate. The evaluated value will be used to switch on.")]
|
||||
public WorkflowExpression<bool> ConditionExpression
|
||||
{
|
||||
get => GetState(() => new JavaScriptExpression<bool>("true"));
|
||||
set => SetState(value);
|
||||
}
|
||||
|
||||
protected override async Task<ActivityExecutionResult> OnExecuteAsync(WorkflowExecutionContext workflowContext,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var result = await expressionEvaluator.EvaluateAsync(
|
||||
ConditionExpression,
|
||||
workflowContext,
|
||||
cancellationToken
|
||||
);
|
||||
return Outcome(result ? OutcomeNames.True : OutcomeNames.False);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,147 +1,144 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Elsa.Attributes;
|
||||
using Elsa.Design;
|
||||
using Elsa.Results;
|
||||
using Elsa.Services;
|
||||
using Elsa.Services.Extensions;
|
||||
using Elsa.Services.Models;
|
||||
|
||||
namespace Elsa.Activities.ControlFlow
|
||||
{
|
||||
[ActivityDefinition(
|
||||
Category = "Control Flow",
|
||||
Description = "Merge workflow execution back into a single branch.",
|
||||
Icon = "fas fa-code-branch"
|
||||
)]
|
||||
[ActivityDefinitionDesigner(
|
||||
Description =
|
||||
"x => !!x.state.joinMode ? `Merge workflow execution back into a single branch using mode <strong>${ x.state.joinMode }</strong>` : x.definition.description",
|
||||
Outcomes = new[] { OutcomeNames.Done }
|
||||
)]
|
||||
public class Join : Activity, IWorkflowEventHandler
|
||||
{
|
||||
public Join()
|
||||
{
|
||||
InboundTransitions = new List<string>().AsReadOnly();
|
||||
}
|
||||
|
||||
public enum JoinMode
|
||||
{
|
||||
WaitAll,
|
||||
WaitAny
|
||||
}
|
||||
|
||||
[ActivityProperty(
|
||||
Type = ActivityPropertyTypes.Select,
|
||||
Hint = "Either 'WaitAll' or 'WaitAny'")
|
||||
]
|
||||
[SelectOptions("WaitAll", "WaitAny")]
|
||||
public JoinMode Mode
|
||||
{
|
||||
get => GetState(() => JoinMode.WaitAll);
|
||||
set => SetState(value);
|
||||
}
|
||||
|
||||
public IReadOnlyCollection<string> InboundTransitions
|
||||
{
|
||||
get => GetState<IReadOnlyCollection<string>>();
|
||||
set => SetState(value);
|
||||
}
|
||||
|
||||
protected override ActivityExecutionResult OnExecute(WorkflowExecutionContext workflowContext)
|
||||
{
|
||||
var recordedInboundTransitions = InboundTransitions ?? new List<string>();
|
||||
var workflow = workflowContext.Workflow;
|
||||
var inboundConnections = workflow.GetInboundConnections(Id);
|
||||
var done = false;
|
||||
|
||||
switch (Mode)
|
||||
{
|
||||
case JoinMode.WaitAll:
|
||||
done = inboundConnections.All(x => recordedInboundTransitions.Contains(GetTransitionKey(x)));
|
||||
break;
|
||||
case JoinMode.WaitAny:
|
||||
done = inboundConnections.Any(x => recordedInboundTransitions.Contains(GetTransitionKey(x)));
|
||||
break;
|
||||
}
|
||||
|
||||
if (done)
|
||||
{
|
||||
// Remove any inbound blocking activities.
|
||||
var ancestorActivityIds = workflow.GetInboundActivityPath(Id).ToList();
|
||||
var blockingActivities =
|
||||
workflow.BlockingActivities.Where(x => ancestorActivityIds.Contains(x.Id)).ToList();
|
||||
|
||||
foreach (var blockingActivity in blockingActivities)
|
||||
{
|
||||
workflow.BlockingActivities.Remove(blockingActivity);
|
||||
}
|
||||
}
|
||||
|
||||
return done ? Done() : Noop();
|
||||
}
|
||||
|
||||
private void RecordInboundTransitions(WorkflowExecutionContext workflowContext, IActivity activity)
|
||||
{
|
||||
var workflow = workflowContext.Workflow;
|
||||
|
||||
// Get outbound connections of the executing activity.
|
||||
var outboundConnections = workflow.GetOutboundConnections(activity.Id);
|
||||
|
||||
// Get any connection that is pointing to this activity.
|
||||
var inboundTransitionsQuery =
|
||||
from connection in outboundConnections
|
||||
let destinationActivity = connection.Target.Activity
|
||||
where destinationActivity.Type == nameof(Join)
|
||||
select connection;
|
||||
|
||||
var inboundConnections = inboundTransitionsQuery.ToList();
|
||||
|
||||
// For each inbound connection, record the transition.
|
||||
foreach (var inboundConnection in inboundConnections)
|
||||
{
|
||||
var joinActivity = (Join)inboundConnection.Target.Activity;
|
||||
var inboundTransitions = joinActivity.InboundTransitions ?? new List<string>();
|
||||
joinActivity.InboundTransitions = inboundTransitions
|
||||
.Union(new[] { GetTransitionKey(inboundConnection) })
|
||||
.Distinct()
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
|
||||
private string GetTransitionKey(Connection connection)
|
||||
{
|
||||
var sourceActivityId = connection.Source.Activity.Id;
|
||||
var sourceOutcomeName = connection.Source.Outcome;
|
||||
|
||||
return $"@{sourceActivityId}_{sourceOutcomeName}";
|
||||
}
|
||||
|
||||
Task IWorkflowEventHandler.ActivityExecutedAsync(
|
||||
WorkflowExecutionContext workflowContext,
|
||||
IActivity activity,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
RecordInboundTransitions(workflowContext, activity);
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task ActivityFaultedAsync(
|
||||
WorkflowExecutionContext workflowExecutionContext,
|
||||
IActivity activity,
|
||||
string message,
|
||||
CancellationToken cancellationToken) => Task.CompletedTask;
|
||||
|
||||
Task IWorkflowEventHandler.InvokingHaltedActivitiesAsync(
|
||||
WorkflowExecutionContext workflowExecutionContext,
|
||||
CancellationToken cancellationToken) => Task.CompletedTask;
|
||||
|
||||
Task IWorkflowEventHandler.WorkflowInvokedAsync(
|
||||
WorkflowExecutionContext workflowExecutionContext,
|
||||
CancellationToken cancellationToken) => Task.CompletedTask;
|
||||
}
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Elsa.Attributes;
|
||||
using Elsa.Design;
|
||||
using Elsa.Results;
|
||||
using Elsa.Services;
|
||||
using Elsa.Services.Extensions;
|
||||
using Elsa.Services.Models;
|
||||
|
||||
namespace Elsa.Activities.ControlFlow.Activities
|
||||
{
|
||||
[ActivityDefinition(
|
||||
Category = "Control Flow",
|
||||
Description = "Merge workflow execution back into a single branch.",
|
||||
Icon = "fas fa-code-branch",
|
||||
RuntimeDescription = "x => !!x.state.joinMode ? `Merge workflow execution back into a single branch using mode <strong>${ x.state.joinMode }</strong>` : x.definition.description",
|
||||
Outcomes = new[] { OutcomeNames.Done }
|
||||
)]
|
||||
public class Join : Activity, IWorkflowEventHandler
|
||||
{
|
||||
public Join()
|
||||
{
|
||||
InboundTransitions = new List<string>().AsReadOnly();
|
||||
}
|
||||
|
||||
public enum JoinMode
|
||||
{
|
||||
WaitAll,
|
||||
WaitAny
|
||||
}
|
||||
|
||||
[ActivityProperty(
|
||||
Type = ActivityPropertyTypes.Select,
|
||||
Hint = "Either 'WaitAll' or 'WaitAny'")
|
||||
]
|
||||
[SelectOptions("WaitAll", "WaitAny")]
|
||||
public JoinMode Mode
|
||||
{
|
||||
get => GetState(() => JoinMode.WaitAll);
|
||||
set => SetState(value);
|
||||
}
|
||||
|
||||
public IReadOnlyCollection<string> InboundTransitions
|
||||
{
|
||||
get => GetState<IReadOnlyCollection<string>>();
|
||||
set => SetState(value);
|
||||
}
|
||||
|
||||
protected override ActivityExecutionResult OnExecute(WorkflowExecutionContext workflowContext)
|
||||
{
|
||||
var recordedInboundTransitions = InboundTransitions ?? new List<string>();
|
||||
var workflow = workflowContext.Workflow;
|
||||
var inboundConnections = workflow.GetInboundConnections(Id);
|
||||
var done = false;
|
||||
|
||||
switch (Mode)
|
||||
{
|
||||
case JoinMode.WaitAll:
|
||||
done = inboundConnections.All(x => recordedInboundTransitions.Contains(GetTransitionKey(x)));
|
||||
break;
|
||||
case JoinMode.WaitAny:
|
||||
done = inboundConnections.Any(x => recordedInboundTransitions.Contains(GetTransitionKey(x)));
|
||||
break;
|
||||
}
|
||||
|
||||
if (done)
|
||||
{
|
||||
// Remove any inbound blocking activities.
|
||||
var ancestorActivityIds = workflow.GetInboundActivityPath(Id).ToList();
|
||||
var blockingActivities =
|
||||
workflow.BlockingActivities.Where(x => ancestorActivityIds.Contains(x.Id)).ToList();
|
||||
|
||||
foreach (var blockingActivity in blockingActivities)
|
||||
{
|
||||
workflow.BlockingActivities.Remove(blockingActivity);
|
||||
}
|
||||
}
|
||||
|
||||
return done ? Done() : Noop();
|
||||
}
|
||||
|
||||
private void RecordInboundTransitions(WorkflowExecutionContext workflowContext, IActivity activity)
|
||||
{
|
||||
var workflow = workflowContext.Workflow;
|
||||
|
||||
// Get outbound connections of the executing activity.
|
||||
var outboundConnections = workflow.GetOutboundConnections(activity.Id);
|
||||
|
||||
// Get any connection that is pointing to this activity.
|
||||
var inboundTransitionsQuery =
|
||||
from connection in outboundConnections
|
||||
let destinationActivity = connection.Target.Activity
|
||||
where destinationActivity.Type == nameof(Join)
|
||||
select connection;
|
||||
|
||||
var inboundConnections = inboundTransitionsQuery.ToList();
|
||||
|
||||
// For each inbound connection, record the transition.
|
||||
foreach (var inboundConnection in inboundConnections)
|
||||
{
|
||||
var joinActivity = (Join)inboundConnection.Target.Activity;
|
||||
var inboundTransitions = joinActivity.InboundTransitions ?? new List<string>();
|
||||
joinActivity.InboundTransitions = inboundTransitions
|
||||
.Union(new[] { GetTransitionKey(inboundConnection) })
|
||||
.Distinct()
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
|
||||
private string GetTransitionKey(Connection connection)
|
||||
{
|
||||
var sourceActivityId = connection.Source.Activity.Id;
|
||||
var sourceOutcomeName = connection.Source.Outcome;
|
||||
|
||||
return $"@{sourceActivityId}_{sourceOutcomeName}";
|
||||
}
|
||||
|
||||
Task IWorkflowEventHandler.ActivityExecutedAsync(
|
||||
WorkflowExecutionContext workflowContext,
|
||||
IActivity activity,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
RecordInboundTransitions(workflowContext, activity);
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task ActivityFaultedAsync(
|
||||
WorkflowExecutionContext workflowExecutionContext,
|
||||
IActivity activity,
|
||||
string message,
|
||||
CancellationToken cancellationToken) => Task.CompletedTask;
|
||||
|
||||
Task IWorkflowEventHandler.InvokingHaltedActivitiesAsync(
|
||||
WorkflowExecutionContext workflowExecutionContext,
|
||||
CancellationToken cancellationToken) => Task.CompletedTask;
|
||||
|
||||
Task IWorkflowEventHandler.WorkflowInvokedAsync(
|
||||
WorkflowExecutionContext workflowExecutionContext,
|
||||
CancellationToken cancellationToken) => Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,54 +1,52 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Elsa.Attributes;
|
||||
using Elsa.Expressions;
|
||||
using Elsa.Extensions;
|
||||
using Elsa.Results;
|
||||
using Elsa.Services;
|
||||
using Elsa.Services.Models;
|
||||
|
||||
namespace Elsa.Activities.ControlFlow
|
||||
{
|
||||
[ActivityDefinition(
|
||||
Category = "Control Flow",
|
||||
Description = "Switch execution based on a given expression.",
|
||||
Icon = "far fa-list-alt"
|
||||
)]
|
||||
[ActivityDefinitionDesigner(
|
||||
Description =
|
||||
"x => !!x.state.expression ? `Switch execution based on <strong>${ x.state.expression.expression }</strong>.` : x.definition.description",
|
||||
Outcomes = "x => x.state.cases.map(c => c.toString())"
|
||||
)]
|
||||
public class Switch : Activity
|
||||
{
|
||||
private readonly IWorkflowExpressionEvaluator expressionEvaluator;
|
||||
|
||||
public Switch(IWorkflowExpressionEvaluator expressionEvaluator)
|
||||
{
|
||||
this.expressionEvaluator = expressionEvaluator;
|
||||
Cases = new List<string>();
|
||||
}
|
||||
|
||||
[ActivityProperty(Hint = "The expression to evaluate. The evaluated value will be used to switch on.")]
|
||||
public WorkflowExpression<string> Expression
|
||||
{
|
||||
get => GetState<WorkflowExpression<string>>();
|
||||
set => SetState(value);
|
||||
}
|
||||
|
||||
[ActivityProperty(Hint = "A comma-separated list of possible outcomes of the expression.")]
|
||||
public IReadOnlyCollection<string> Cases
|
||||
{
|
||||
get => GetState<IReadOnlyCollection<string>>();
|
||||
set => SetState(value);
|
||||
}
|
||||
|
||||
protected override async Task<ActivityExecutionResult> OnExecuteAsync(WorkflowExecutionContext workflowContext,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var result = await expressionEvaluator.EvaluateAsync(Expression, workflowContext, cancellationToken);
|
||||
return Outcome(result);
|
||||
}
|
||||
}
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Elsa.Attributes;
|
||||
using Elsa.Expressions;
|
||||
using Elsa.Extensions;
|
||||
using Elsa.Results;
|
||||
using Elsa.Services;
|
||||
using Elsa.Services.Models;
|
||||
|
||||
namespace Elsa.Activities.ControlFlow.Activities
|
||||
{
|
||||
[ActivityDefinition(
|
||||
Category = "Control Flow",
|
||||
Description = "Switch execution based on a given expression.",
|
||||
Icon = "far fa-list-alt",
|
||||
RuntimeDescription = "x => !!x.state.expression ? `Switch execution based on <strong>${ x.state.expression.expression }</strong>.` : x.definition.description",
|
||||
Outcomes = "x => x.state.cases.map(c => c.toString())"
|
||||
)]
|
||||
public class Switch : Activity
|
||||
{
|
||||
private readonly IWorkflowExpressionEvaluator expressionEvaluator;
|
||||
|
||||
public Switch(IWorkflowExpressionEvaluator expressionEvaluator)
|
||||
{
|
||||
this.expressionEvaluator = expressionEvaluator;
|
||||
Cases = new List<string>();
|
||||
}
|
||||
|
||||
[ActivityProperty(Hint = "The expression to evaluate. The evaluated value will be used to switch on.")]
|
||||
public WorkflowExpression<string> Expression
|
||||
{
|
||||
get => GetState<WorkflowExpression<string>>();
|
||||
set => SetState(value);
|
||||
}
|
||||
|
||||
[ActivityProperty(Hint = "A comma-separated list of possible outcomes of the expression.")]
|
||||
public IReadOnlyCollection<string> Cases
|
||||
{
|
||||
get => GetState<IReadOnlyCollection<string>>();
|
||||
set => SetState(value);
|
||||
}
|
||||
|
||||
protected override async Task<ActivityExecutionResult> OnExecuteAsync(
|
||||
WorkflowExecutionContext workflowContext,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var result = await expressionEvaluator.EvaluateAsync(Expression, workflowContext, cancellationToken);
|
||||
return Outcome(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Elsa.Attributes;
|
||||
using Elsa.Expressions;
|
||||
using Elsa.Extensions;
|
||||
using Elsa.Results;
|
||||
using Elsa.Scripting.JavaScript;
|
||||
using Elsa.Services;
|
||||
using Elsa.Services.Models;
|
||||
|
||||
namespace Elsa.Activities.ControlFlow.Activities
|
||||
{
|
||||
[ActivityDefinition(Category = "Control Flow", Description = "Execute while a given condition is true.", Icon = "far fa-circle")]
|
||||
public class While : Activity
|
||||
{
|
||||
private readonly IWorkflowExpressionEvaluator expressionEvaluator;
|
||||
|
||||
public While(IWorkflowExpressionEvaluator expressionEvaluator)
|
||||
{
|
||||
this.expressionEvaluator = expressionEvaluator;
|
||||
}
|
||||
|
||||
[ActivityProperty(Hint = "Enter an expression that evaluates to a boolean value.")]
|
||||
public WorkflowExpression<bool> ConditionExpression
|
||||
{
|
||||
get => GetState(() => new JavaScriptExpression<bool>("true"));
|
||||
set => SetState(value);
|
||||
}
|
||||
|
||||
public bool HasStarted
|
||||
{
|
||||
get => GetState(() => false);
|
||||
set => SetState(value);
|
||||
}
|
||||
|
||||
protected override async Task<ActivityExecutionResult> OnExecuteAsync(
|
||||
WorkflowExecutionContext context,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var loop = await expressionEvaluator.EvaluateAsync(ConditionExpression, context, cancellationToken);
|
||||
|
||||
if(HasStarted)
|
||||
context.EndScope();
|
||||
|
||||
if (loop)
|
||||
{
|
||||
if (!HasStarted)
|
||||
HasStarted = true;
|
||||
|
||||
context.BeginScope();
|
||||
return Outcome(OutcomeNames.Iterate);
|
||||
}
|
||||
|
||||
return Done();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\core\Elsa.Core\Elsa.Core.csproj" />
|
||||
<ProjectReference Include="..\..\scripting\Elsa.Scripting.JavaScript\Elsa.Scripting.JavaScript.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
using Elsa.Activities.ControlFlow.Activities;
|
||||
using Elsa.Services;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Elsa.Activities.ControlFlow.Extensions
|
||||
{
|
||||
public static class ControlFlowServiceCollectionExtensions
|
||||
{
|
||||
public static IServiceCollection AddControlFlowActivities(this IServiceCollection services)
|
||||
{
|
||||
return services
|
||||
.AddActivity<ForEach>()
|
||||
.AddActivity<While>()
|
||||
.AddActivity<Fork>()
|
||||
.AddActivity<Join>()
|
||||
.AddSingleton<IWorkflowEventHandler>(sp => sp.GetRequiredService<Join>())
|
||||
.AddActivity<IfElse>()
|
||||
.AddActivity<Switch>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="3.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -23,11 +23,8 @@ namespace Elsa.Activities.Http.Activities
|
|||
[ActivityDefinition(
|
||||
Category = "HTTP",
|
||||
DisplayName = "Send HTTP Request",
|
||||
Description = "Send an HTTP request."
|
||||
)]
|
||||
[ActivityDefinitionDesigner(
|
||||
Description =
|
||||
"x => !!x.state.url ? `Send HTTP <strong>${ x.state.method } ${ x.state.url.expression }</strong>.` : x.definition.description",
|
||||
Description = "Send an HTTP request.",
|
||||
RuntimeDescription = "x => !!x.state.url ? `Send HTTP <strong>${ x.state.method } ${ x.state.url.expression }</strong>.` : x.definition.description",
|
||||
Outcomes = "x => !!x.state.supportedStatusCodes ? x.state.supportedStatusCodes : []"
|
||||
)]
|
||||
public class HttpRequestAction : Activity
|
||||
|
|
|
|||
|
|
@ -20,11 +20,8 @@ namespace Elsa.Activities.Http.Activities
|
|||
[ActivityDefinition(
|
||||
Category = "HTTP",
|
||||
DisplayName = "Receive HTTP Request",
|
||||
Description = "Receive an incoming HTTP request."
|
||||
)]
|
||||
[ActivityDefinitionDesigner(
|
||||
Description =
|
||||
"x => !!x.state.path ? `Handle <strong>${ x.state.method } ${ x.state.path }</strong>.` : x.definition.description",
|
||||
Description = "Receive an incoming HTTP request.",
|
||||
RuntimeDescription = "x => !!x.state.path ? `Handle <strong>${ x.state.method } ${ x.state.path }</strong>.` : x.definition.description",
|
||||
Outcomes = new[] { OutcomeNames.Done }
|
||||
)]
|
||||
public class HttpRequestEvent : Activity
|
||||
|
|
@ -118,7 +115,7 @@ namespace Elsa.Activities.Http.Activities
|
|||
|
||||
var parser = SelectContentParser(request.ContentType);
|
||||
var content = await request.ReadContentAsBytesAsync(cancellationToken);
|
||||
model.Content = await parser.ParseAsync(content, request.ContentType);
|
||||
model.Body = await parser.ParseAsync(content, request.ContentType);
|
||||
}
|
||||
|
||||
Output["Content"] = model;
|
||||
|
|
|
|||
|
|
@ -18,11 +18,8 @@ namespace Elsa.Activities.Http.Activities
|
|||
[ActivityDefinition(
|
||||
Category = "HTTP",
|
||||
DisplayName = "Send HTTP Response",
|
||||
Description = "Send an HTTP response."
|
||||
)]
|
||||
[ActivityDefinitionDesigner(
|
||||
Description =
|
||||
"x => !!x.state.statusCode ? `Send an HTTP <strong>${ x.state.statusCode }</strong> - <strong>${ x.state.contentType }</strong> response` : x.definition.description",
|
||||
Description = "Send an HTTP response.",
|
||||
RuntimeDescription = "x => !!x.state.statusCode ? `Send an HTTP <strong>${ x.state.statusCode }</strong> - <strong>${ x.state.contentType }</strong> response` : x.definition.description",
|
||||
Outcomes = new[] { OutcomeNames.Done }
|
||||
)]
|
||||
public class HttpResponseAction : Activity
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@
|
|||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\core\Elsa.Core\Elsa.Core.csproj" />
|
||||
<ProjectReference Include="..\..\scripting\Elsa.Scripting.JavaScript\Elsa.Scripting.JavaScript.csproj" />
|
||||
<ProjectReference Include="..\..\scripting\Elsa.Scripting.Liquid\Elsa.Scripting.Liquid.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
@ -23,7 +25,6 @@
|
|||
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.2.2" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.2.5" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="3.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="3.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,55 +1,56 @@
|
|||
using System;
|
||||
using Elsa.Activities.Http.Activities;
|
||||
using Elsa.Activities.Http.Formatters;
|
||||
using Elsa.Activities.Http.Options;
|
||||
using Elsa.Activities.Http.RequestHandlers.Handlers;
|
||||
using Elsa.Activities.Http.Scripting;
|
||||
using Elsa.Activities.Http.Services;
|
||||
using Elsa.Scripting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Elsa.Activities.Http.Extensions
|
||||
{
|
||||
public static class ServiceCollectionExtensions
|
||||
{
|
||||
public static IServiceCollection AddHttpActivities(
|
||||
this IServiceCollection services,
|
||||
Action<OptionsBuilder<HttpActivityOptions>> options = null)
|
||||
{
|
||||
options?.Invoke(services.AddOptions<HttpActivityOptions>());
|
||||
|
||||
services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
|
||||
services.AddHttpClient(nameof(HttpRequestAction));
|
||||
|
||||
services
|
||||
.AddActivity<HttpRequestEvent>()
|
||||
.AddActivity<HttpResponseAction>()
|
||||
.AddActivity<HttpRequestAction>();
|
||||
|
||||
services
|
||||
.AddSingleton<ITokenService, TokenService>()
|
||||
.AddSingleton<IContentFormatter, DefaultContentFormatter>()
|
||||
.AddSingleton<IContentFormatter, JsonContentFormatter>()
|
||||
.AddSingleton<IScriptEngineConfigurator, HttpScriptEngineConfigurator>()
|
||||
.AddSingleton<IActionContextAccessor, ActionContextAccessor>()
|
||||
.AddSingleton<IAbsoluteUrlProvider, DefaultAbsoluteUrlProvider>()
|
||||
.AddHttpContextAccessor()
|
||||
.AddDataProtection();
|
||||
|
||||
return services
|
||||
.AddScoped(sp => sp.GetRequiredService<IHttpContextAccessor>().HttpContext)
|
||||
.AddRequestHandler<TriggerRequestHandler>()
|
||||
.AddRequestHandler<SignalRequestHandler>();
|
||||
}
|
||||
|
||||
public static IServiceCollection AddRequestHandler<THandler>(this IServiceCollection services)
|
||||
where THandler : class, IRequestHandler
|
||||
{
|
||||
return services.AddScoped<THandler>();
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using Elsa.Activities.Http.Activities;
|
||||
using Elsa.Activities.Http.Formatters;
|
||||
using Elsa.Activities.Http.Options;
|
||||
using Elsa.Activities.Http.RequestHandlers.Handlers;
|
||||
using Elsa.Activities.Http.Services;
|
||||
using Elsa.Scripting;
|
||||
using Elsa.Scripting.JavaScript;
|
||||
using MediatR;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Elsa.Activities.Http.Extensions
|
||||
{
|
||||
public static class HttpActivitiesServiceCollectionExtensions
|
||||
{
|
||||
public static IServiceCollection AddHttpActivities(
|
||||
this IServiceCollection services,
|
||||
Action<OptionsBuilder<HttpActivityOptions>> options = null)
|
||||
{
|
||||
options?.Invoke(services.AddOptions<HttpActivityOptions>());
|
||||
|
||||
services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
|
||||
services.AddHttpClient(nameof(HttpRequestAction));
|
||||
|
||||
services
|
||||
.AddActivity<HttpRequestEvent>()
|
||||
.AddActivity<HttpResponseAction>()
|
||||
.AddActivity<HttpRequestAction>();
|
||||
|
||||
services
|
||||
.AddSingleton<ITokenService, TokenService>()
|
||||
.AddSingleton<IContentFormatter, DefaultContentFormatter>()
|
||||
.AddSingleton<IContentFormatter, JsonContentFormatter>()
|
||||
.AddSingleton<IActionContextAccessor, ActionContextAccessor>()
|
||||
.AddSingleton<IAbsoluteUrlProvider, DefaultAbsoluteUrlProvider>()
|
||||
.AddHttpContextAccessor()
|
||||
.AddMediatR(typeof(HttpActivitiesServiceCollectionExtensions))
|
||||
.AddDataProtection();
|
||||
|
||||
return services
|
||||
.AddScoped(sp => sp.GetRequiredService<IHttpContextAccessor>().HttpContext)
|
||||
.AddRequestHandler<TriggerRequestHandler>()
|
||||
.AddRequestHandler<SignalRequestHandler>();
|
||||
}
|
||||
|
||||
public static IServiceCollection AddRequestHandler<THandler>(this IServiceCollection services)
|
||||
where THandler : class, IRequestHandler
|
||||
{
|
||||
return services.AddScoped<THandler>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,31 +1,36 @@
|
|||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Elsa.Activities.Http.Models;
|
||||
using Elsa.Activities.Http.Services;
|
||||
using Elsa.Scripting;
|
||||
using Elsa.Scripting.JavaScript.Messages;
|
||||
using Elsa.Services.Models;
|
||||
using Jint;
|
||||
using MediatR;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace Elsa.Activities.Http.Scripting
|
||||
namespace Elsa.Activities.Http.Handlers
|
||||
{
|
||||
public class HttpScriptEngineConfigurator : IScriptEngineConfigurator
|
||||
public class HttpJavaScriptHandler : INotificationHandler<EvaluatingJavaScriptExpression>
|
||||
{
|
||||
private readonly ITokenService _tokenService;
|
||||
private readonly ITokenService tokenService;
|
||||
private readonly IAbsoluteUrlProvider absoluteUrlProvider;
|
||||
private readonly IHttpContextAccessor httpContextAccessor;
|
||||
|
||||
public HttpScriptEngineConfigurator(
|
||||
public HttpJavaScriptHandler(
|
||||
ITokenService tokenService,
|
||||
IAbsoluteUrlProvider absoluteUrlProvider,
|
||||
IHttpContextAccessor httpContextAccessor)
|
||||
{
|
||||
this._tokenService = tokenService;
|
||||
this.tokenService = tokenService;
|
||||
this.absoluteUrlProvider = absoluteUrlProvider;
|
||||
this.httpContextAccessor = httpContextAccessor;
|
||||
}
|
||||
|
||||
public void Configure(Engine engine, WorkflowExecutionContext workflowExecutionContext)
|
||||
|
||||
public Task Handle(EvaluatingJavaScriptExpression notification, CancellationToken cancellationToken)
|
||||
{
|
||||
var engine = notification.Engine;
|
||||
var workflowExecutionContext = notification.WorkflowExecutionContext;
|
||||
|
||||
engine.SetValue(
|
||||
"queryString",
|
||||
(Func<string, string>) (key => httpContextAccessor.HttpContext.Request.Query[key].ToString())
|
||||
|
|
@ -38,13 +43,15 @@ namespace Elsa.Activities.Http.Scripting
|
|||
"signalUrl",
|
||||
(Func<string, string>) (signal => GenerateUrl(signal, workflowExecutionContext))
|
||||
);
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private string GenerateUrl(string signal, WorkflowExecutionContext workflowExecutionContext)
|
||||
{
|
||||
var workflowInstanceId = workflowExecutionContext.Workflow.Id;
|
||||
var payload = new Signal(signal, workflowInstanceId);
|
||||
var token = _tokenService.CreateToken(payload);
|
||||
var token = tokenService.CreateToken(payload);
|
||||
var url = $"/workflows/signal?token={token}";
|
||||
|
||||
return absoluteUrlProvider.ToAbsoluteUrl(url).ToString();
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Elsa.Activities.Http.Models;
|
||||
using Elsa.Scripting.Liquid.Messages;
|
||||
using Fluid;
|
||||
using MediatR;
|
||||
|
||||
namespace Elsa.Activities.Http.Handlers
|
||||
{
|
||||
public class HttpLiquidHandler : INotificationHandler<EvaluatingLiquidExpression>
|
||||
{
|
||||
public Task Handle(EvaluatingLiquidExpression notification, CancellationToken cancellationToken)
|
||||
{
|
||||
var context = notification.TemplateContext;
|
||||
|
||||
context.MemberAccessStrategy.Register<HttpRequestModel>();
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -9,7 +9,7 @@ namespace Elsa.Activities.Http.Models
|
|||
public string Method { get; set; }
|
||||
public IDictionary<string, StringValuesModel> QueryString { get; set; }
|
||||
public IDictionary<string, StringValuesModel> Headers { get; set; }
|
||||
public object Content { get; set; }
|
||||
public object Body { get; set; }
|
||||
public IDictionary<string, StringValuesModel> Form { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -14,9 +14,9 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MassTransit.AspNetCore" Version="5.5.2" />
|
||||
<PackageReference Include="MassTransit.Extensions.DependencyInjection" Version="5.5.2" />
|
||||
<PackageReference Include="MassTransit.RabbitMQ" Version="5.5.2" />
|
||||
<PackageReference Include="MassTransit.AspNetCore" Version="5.5.6" />
|
||||
<PackageReference Include="MassTransit.Extensions.DependencyInjection" Version="5.5.6" />
|
||||
<PackageReference Include="MassTransit.RabbitMQ" Version="5.5.6" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -13,11 +13,8 @@ namespace Elsa.Activities.Timers.Activities
|
|||
{
|
||||
[ActivityDefinition(
|
||||
Category = "Timers",
|
||||
Description = "Triggers periodically based on a specified CRON expression."
|
||||
)]
|
||||
[ActivityDefinitionDesigner(
|
||||
Description =
|
||||
"x => !!x.state.cronExpression ? `<strong>${ x.state.cronExpression.expression }</strong>.` : x.definition.description",
|
||||
Description = "Triggers periodically based on a specified CRON expression.",
|
||||
RuntimeDescription = "x => !!x.state.cronExpression ? `<strong>${ x.state.cronExpression.expression }</strong>.` : x.definition.description",
|
||||
Outcomes = new[] { OutcomeNames.Done }
|
||||
)]
|
||||
public class CronEvent : Activity
|
||||
|
|
@ -43,7 +40,7 @@ namespace Elsa.Activities.Timers.Activities
|
|||
get => GetState<Instant?>();
|
||||
set => SetState(value);
|
||||
}
|
||||
|
||||
|
||||
protected override async Task<bool> OnCanExecuteAsync(WorkflowExecutionContext context, CancellationToken cancellationToken)
|
||||
{
|
||||
return StartTime == null || await IsExpiredAsync(context, cancellationToken);
|
||||
|
|
@ -54,7 +51,8 @@ namespace Elsa.Activities.Timers.Activities
|
|||
return Halt();
|
||||
}
|
||||
|
||||
protected override async Task<ActivityExecutionResult> OnResumeAsync(WorkflowExecutionContext context,
|
||||
protected override async Task<ActivityExecutionResult> OnResumeAsync(
|
||||
WorkflowExecutionContext context,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
if (await IsExpiredAsync(context, cancellationToken))
|
||||
|
|
@ -62,11 +60,12 @@ namespace Elsa.Activities.Timers.Activities
|
|||
StartTime = null;
|
||||
return Done();
|
||||
}
|
||||
|
||||
|
||||
return Halt();
|
||||
}
|
||||
|
||||
private async Task<bool> IsExpiredAsync(WorkflowExecutionContext workflowContext,
|
||||
private async Task<bool> IsExpiredAsync(
|
||||
WorkflowExecutionContext workflowContext,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var cronExpression = await expressionEvaluator.EvaluateAsync(
|
||||
|
|
@ -76,10 +75,10 @@ namespace Elsa.Activities.Timers.Activities
|
|||
);
|
||||
var schedule = CrontabSchedule.Parse(cronExpression);
|
||||
var now = clock.GetCurrentInstant();
|
||||
|
||||
|
||||
if (StartTime == null)
|
||||
StartTime = now;
|
||||
|
||||
|
||||
var nextOccurrence = schedule.GetNextOccurrence(StartTime.Value.ToDateTimeUtc());
|
||||
|
||||
return now.ToDateTimeUtc() >= nextOccurrence;
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="3.0.0" />
|
||||
<PackageReference Include="NCrontab" Version="3.3.1" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ using Elsa.Results;
|
|||
using Elsa.Services;
|
||||
using Elsa.Services.Models;
|
||||
|
||||
namespace Elsa.Activities.Workflows
|
||||
namespace Elsa.Activities.Workflows.Activities
|
||||
{
|
||||
/// <summary>
|
||||
/// Sets the CorrelationId of the workflow to a given value.
|
||||
|
|
@ -5,10 +5,11 @@ using Elsa.Expressions;
|
|||
using Elsa.Extensions;
|
||||
using Elsa.Models;
|
||||
using Elsa.Results;
|
||||
using Elsa.Scripting.JavaScript;
|
||||
using Elsa.Services;
|
||||
using Elsa.Services.Models;
|
||||
|
||||
namespace Elsa.Activities.Workflows
|
||||
namespace Elsa.Activities.Workflows.Activities
|
||||
{
|
||||
[ActivityDefinition(
|
||||
Category = "Workflows",
|
||||
|
|
@ -7,7 +7,7 @@ using Elsa.Results;
|
|||
using Elsa.Services;
|
||||
using Elsa.Services.Models;
|
||||
|
||||
namespace Elsa.Activities.Workflows
|
||||
namespace Elsa.Activities.Workflows.Activities
|
||||
{
|
||||
/// <summary>
|
||||
/// Halts workflow execution until the specified signal is received.
|
||||
|
|
@ -3,7 +3,7 @@ using Elsa.Results;
|
|||
using Elsa.Services;
|
||||
using Elsa.Services.Models;
|
||||
|
||||
namespace Elsa.Activities.Workflows
|
||||
namespace Elsa.Activities.Workflows.Activities
|
||||
{
|
||||
[ActivityDefinition(
|
||||
Category = "Workflows",
|
||||
|
|
@ -5,10 +5,12 @@ using Elsa.Expressions;
|
|||
using Elsa.Extensions;
|
||||
using Elsa.Models;
|
||||
using Elsa.Results;
|
||||
using Elsa.Scripting.JavaScript;
|
||||
using Elsa.Scripting.JavaScript.Services;
|
||||
using Elsa.Services;
|
||||
using Elsa.Services.Models;
|
||||
|
||||
namespace Elsa.Activities.Workflows
|
||||
namespace Elsa.Activities.Workflows.Activities
|
||||
{
|
||||
/// <summary>
|
||||
/// Triggers the specified signal.
|
||||
|
|
@ -41,7 +43,7 @@ namespace Elsa.Activities.Workflows
|
|||
)]
|
||||
public WorkflowExpression<Variables> Input
|
||||
{
|
||||
get => GetState(() => new WorkflowExpression<Variables>(JavaScriptEvaluator.SyntaxName, "{}"));
|
||||
get => GetState(() => new WorkflowExpression<Variables>(JavaScriptExpressionEvaluator.SyntaxName, "{}"));
|
||||
set => SetState(value);
|
||||
}
|
||||
|
||||
|
|
@ -6,10 +6,11 @@ using Elsa.Expressions;
|
|||
using Elsa.Extensions;
|
||||
using Elsa.Models;
|
||||
using Elsa.Results;
|
||||
using Elsa.Scripting.JavaScript;
|
||||
using Elsa.Services;
|
||||
using Elsa.Services.Models;
|
||||
|
||||
namespace Elsa.Activities.Workflows
|
||||
namespace Elsa.Activities.Workflows.Activities
|
||||
{
|
||||
[ActivityDefinition(
|
||||
Category = "Workflows",
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\core\Elsa.Core\Elsa.Core.csproj" />
|
||||
<ProjectReference Include="..\..\scripting\Elsa.Scripting.JavaScript\Elsa.Scripting.JavaScript.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
using Elsa.Activities.Workflows.Activities;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Elsa.Activities.Workflows.Extensions
|
||||
{
|
||||
public static class WorkflowActivityServiceCollectionExtensions
|
||||
{
|
||||
public static IServiceCollection AddWorkflowActivities(this IServiceCollection services)
|
||||
{
|
||||
return services
|
||||
.AddActivity<TriggerWorkflow>()
|
||||
.AddActivity<Correlate>()
|
||||
.AddActivity<Signaled>()
|
||||
.AddActivity<Trigger>()
|
||||
.AddActivity<Start>()
|
||||
.AddActivity<Finish>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -8,7 +8,9 @@ namespace Elsa.Attributes
|
|||
public string Type { get; set; }
|
||||
public string DisplayName { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string RuntimeDescription { get; set; }
|
||||
public string Category { get; set; }
|
||||
public string Icon { get; set; }
|
||||
public object Outcomes { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
using System;
|
||||
|
||||
namespace Elsa.Attributes
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class ActivityDefinitionDesignerAttribute : Attribute
|
||||
{
|
||||
public string Description { get; set; }
|
||||
public object Outcomes { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -15,7 +15,6 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Jint" Version="3.0.0-beta-1612" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="3.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="3.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Primitives" Version="3.0.0" />
|
||||
|
|
@ -25,4 +24,8 @@
|
|||
<PackageReference Include="System.ComponentModel.Annotations" Version="4.6.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Scripting" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ namespace Elsa.Models
|
|||
|
||||
public ActivityDefinition()
|
||||
{
|
||||
State = new JObject();
|
||||
}
|
||||
|
||||
public ActivityDefinition(string id, string type, JObject state, int left = 0, int top = 0)
|
||||
|
|
@ -25,6 +26,15 @@ namespace Elsa.Models
|
|||
|
||||
public string Id { get; set; }
|
||||
public string Type { get; set; }
|
||||
|
||||
public string Name
|
||||
{
|
||||
get => State.ContainsKey(nameof(Name)) ? State[nameof(Name)].Value<string>() : default;
|
||||
set => State[nameof(Name)] = value;
|
||||
}
|
||||
|
||||
public string DisplayName { get; set; }
|
||||
public string Description { get; set; }
|
||||
public int Left { get; set; }
|
||||
public int Top { get; set; }
|
||||
public JObject State { get; set; }
|
||||
|
|
|
|||
|
|
@ -1,10 +0,0 @@
|
|||
using Elsa.Services.Models;
|
||||
using Jint;
|
||||
|
||||
namespace Elsa.Scripting
|
||||
{
|
||||
public interface IScriptEngineConfigurator
|
||||
{
|
||||
void Configure(Engine engine, WorkflowExecutionContext workflowExecutionContext);
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Elsa.Attributes;
|
||||
using Elsa.Extensions;
|
||||
using Elsa.Models;
|
||||
using Elsa.Results;
|
||||
|
|
@ -12,15 +13,36 @@ using Newtonsoft.Json.Linq;
|
|||
namespace Elsa.Services
|
||||
{
|
||||
public abstract class ActivityBase : IActivity
|
||||
{
|
||||
{
|
||||
public JObject State { get; set; } = new JObject();
|
||||
public Variables Output { get; set; } = new Variables();
|
||||
|
||||
|
||||
[JsonIgnore]
|
||||
public Variables TransientOutput { get; } = new Variables();
|
||||
|
||||
|
||||
public virtual string Type => GetType().Name;
|
||||
|
||||
public string Id { get; set; }
|
||||
|
||||
[ActivityProperty(Label = "Name", Hint = "Optionally provide a name for this activity. You can reference named activities from expressions.")]
|
||||
public string Name {
|
||||
get => GetState<string>();
|
||||
set => SetState(value);
|
||||
}
|
||||
|
||||
[ActivityProperty(Hint = "Optionally provide a custom title for this activity.")]
|
||||
public string Title
|
||||
{
|
||||
get => GetState<string>();
|
||||
set => SetState(value);
|
||||
}
|
||||
|
||||
[ActivityProperty(Hint = "Optionally provide a custom description for this activity.")]
|
||||
public string Description
|
||||
{
|
||||
get => GetState<string>();
|
||||
set => SetState(value);
|
||||
}
|
||||
|
||||
public Task<bool> CanExecuteAsync(WorkflowExecutionContext context, CancellationToken cancellationToken) => OnCanExecuteAsync(context, cancellationToken);
|
||||
public Task<ActivityExecutionResult> ExecuteAsync(WorkflowExecutionContext context, CancellationToken cancellationToken) => OnExecuteAsync(context, cancellationToken);
|
||||
|
|
|
|||
|
|
@ -7,13 +7,16 @@ namespace Elsa.Services
|
|||
public interface IActivityBuilder
|
||||
{
|
||||
string Id { get; set; }
|
||||
string Name { get; set; }
|
||||
ActivityDefinition Activity { get; }
|
||||
IActivityBuilder StartWith<T>(Action<T> setup = default, string id = default) where T: class, IActivity;
|
||||
IActivityBuilder Add<T>(Action<T> setup = default, string id = null) where T : class, IActivity;
|
||||
IActivityBuilder StartWith<T>(Action<T> setup = default, string name = null) where T: class, IActivity;
|
||||
IActivityBuilder Add<T>(Action<T> setup = default, string name = null) where T : class, IActivity;
|
||||
IOutcomeBuilder When(string outcome);
|
||||
IActivityBuilder Then<T>(Action<T> setup = null, Action<IActivityBuilder> branch = null, string id = null) where T : class, IActivity;
|
||||
IActivityBuilder WithId(string id);
|
||||
IWorkflowBuilder Then(string activityId);
|
||||
IActivityBuilder Then<T>(Action<T> setup = null, Action<IActivityBuilder> branch = null, string name = null) where T : class, IActivity;
|
||||
IActivityBuilder WithDisplayName(string displayName);
|
||||
IActivityBuilder WithDescription(string description);
|
||||
IWorkflowBuilder Then(string activityName);
|
||||
IActivityBuilder Then(IActivityBuilder targetActivity);
|
||||
WorkflowDefinitionVersion Build();
|
||||
ActivityDefinition BuildActivity();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ namespace Elsa.Services
|
|||
{
|
||||
IActivityBuilder Source { get; }
|
||||
string Outcome { get; }
|
||||
IActivityBuilder Then<T>(Action<T> setup = default, Action<IActivityBuilder> branch = null, string id = default) where T : class, IActivity;
|
||||
IActivityBuilder Then<T>(Action<T> setup = default, Action<IActivityBuilder> branch = default, string name = default) where T : class, IActivity;
|
||||
WorkflowDefinitionVersion Build();
|
||||
IConnectionBuilder Then(string activityId);
|
||||
IConnectionBuilder Then(string activityName);
|
||||
}
|
||||
}
|
||||
|
|
@ -14,8 +14,8 @@ namespace Elsa.Services
|
|||
IWorkflowBuilder WithName(string name);
|
||||
IWorkflowBuilder WithDescription(string description);
|
||||
IWorkflowBuilder AsSingleton(bool value = true);
|
||||
IActivityBuilder Add<T>(Action<T> setupActivity = default, string id = default) where T : class, IActivity;
|
||||
IActivityBuilder StartWith<T>(Action<T> setup = default, string id = default) where T: class, IActivity;
|
||||
IActivityBuilder Add<T>(Action<T> setupActivity = default, string name = default) where T : class, IActivity;
|
||||
IActivityBuilder StartWith<T>(Action<T> setup = default, string name = default) where T: class, IActivity;
|
||||
IConnectionBuilder Connect(IActivityBuilder source, IActivityBuilder target, string outcome = default);
|
||||
IConnectionBuilder Connect(Func<IActivityBuilder> source, Func<IActivityBuilder> target, string outcome = default);
|
||||
WorkflowDefinitionVersion Build();
|
||||
|
|
|
|||
|
|
@ -28,10 +28,15 @@ namespace Elsa.Services.Models
|
|||
string Type { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Unique identifier of this activity
|
||||
/// Unique identifier of this activity.
|
||||
/// </summary>
|
||||
string Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Name identifier of this activity.
|
||||
/// </summary>
|
||||
string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns a value of whether the specified activity can execute.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -12,8 +12,7 @@ namespace Elsa.Services.Models
|
|||
{
|
||||
public Workflow(
|
||||
string id,
|
||||
string definitionId,
|
||||
int version,
|
||||
WorkflowDefinitionVersion definition,
|
||||
Instant createdAt,
|
||||
IEnumerable<IActivity> activities,
|
||||
IEnumerable<Connection> connections,
|
||||
|
|
@ -21,8 +20,7 @@ namespace Elsa.Services.Models
|
|||
string correlationId = default) : this()
|
||||
{
|
||||
Id = id;
|
||||
DefinitionId = definitionId;
|
||||
Version = version;
|
||||
Definition = definition;
|
||||
CreatedAt = createdAt;
|
||||
CorrelationId = correlationId;
|
||||
Activities = activities.ToList();
|
||||
|
|
@ -30,6 +28,8 @@ namespace Elsa.Services.Models
|
|||
Input = new Variables(input ?? Variables.Empty);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public Workflow()
|
||||
{
|
||||
Scopes = new Stack<WorkflowExecutionScope>(new[] { new WorkflowExecutionScope() });
|
||||
|
|
@ -38,8 +38,7 @@ namespace Elsa.Services.Models
|
|||
}
|
||||
|
||||
public string Id { get; set; }
|
||||
public string DefinitionId { get; }
|
||||
public int Version { get; }
|
||||
public WorkflowDefinitionVersion Definition { get; }
|
||||
public string CorrelationId { get; set; }
|
||||
public WorkflowStatus Status { get; set; }
|
||||
public Instant CreatedAt { get; set; }
|
||||
|
|
@ -63,8 +62,8 @@ namespace Elsa.Services.Models
|
|||
return new WorkflowInstance
|
||||
{
|
||||
Id = Id,
|
||||
DefinitionId = DefinitionId,
|
||||
Version = Version,
|
||||
DefinitionId = Definition.DefinitionId,
|
||||
Version = Definition.Version,
|
||||
CorrelationId = CorrelationId,
|
||||
Status = Status,
|
||||
CreatedAt = CreatedAt,
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ namespace Elsa.Services.Models
|
|||
public WorkflowExecutionScope CurrentScope => Workflow.Scopes.Peek();
|
||||
public Variables TransientState { get; } = new Variables();
|
||||
public IActivity CurrentActivity { get; private set; }
|
||||
public void ScheduleActivities(params IActivity[] activities) => ScheduleActivities((IEnumerable<IActivity>) activities);
|
||||
public void ScheduleActivities(params IActivity[] activities) => ScheduleActivities((IEnumerable<IActivity>)activities);
|
||||
|
||||
public void ScheduleActivities(IEnumerable<IActivity> activities)
|
||||
{
|
||||
|
|
@ -43,7 +43,7 @@ namespace Elsa.Services.Models
|
|||
|
||||
public void BeginScope() => Workflow.Scopes.Push(new WorkflowExecutionScope());
|
||||
public void EndScope() => Workflow.Scopes.Pop();
|
||||
|
||||
|
||||
public void ScheduleActivity(IActivity activity)
|
||||
{
|
||||
scheduledActivities.Push(activity);
|
||||
|
|
@ -53,8 +53,28 @@ namespace Elsa.Services.Models
|
|||
public IActivity PopScheduledActivity() => CurrentActivity = scheduledActivities.Pop();
|
||||
public void ScheduleHaltingActivity(IActivity activity) => scheduledHaltingActivities.Push(activity);
|
||||
public IActivity PopScheduledHaltingActivity() => scheduledHaltingActivities.Pop();
|
||||
public void SetVariable(string name, object value) => CurrentScope.SetVariable(name, value);
|
||||
public T GetVariable<T>(string name) => CurrentScope.GetVariable<T>(name);
|
||||
|
||||
public void SetVariable(string name, object value)
|
||||
{
|
||||
// Get the first scope (starting from the oldest one) containing the variable (existing variable). Otherwise use the current scope (new variable declaration)
|
||||
var scope = Workflow.Scopes.Reverse().FirstOrDefault(x => x.Variables.ContainsKey(name)) ?? CurrentScope;
|
||||
scope.SetVariable(name, value);
|
||||
}
|
||||
|
||||
public T GetVariable<T>(string name)
|
||||
{
|
||||
// Get the first scope (starting from the newest one) containing the variable.
|
||||
var scope = Workflow.Scopes.FirstOrDefault(x => x.Variables.ContainsKey(name)) ?? CurrentScope;
|
||||
return scope.GetVariable<T>(name);
|
||||
}
|
||||
|
||||
public object GetVariable(string name)
|
||||
{
|
||||
// Get the first scope (starting from the newest one) containing the variable.
|
||||
var scope = Workflow.Scopes.FirstOrDefault(x => x.Variables.ContainsKey(name)) ?? CurrentScope;
|
||||
return scope.GetVariable(name);
|
||||
}
|
||||
|
||||
public void SetLastResult(object value) => CurrentScope.LastResult = value;
|
||||
|
||||
public void Start()
|
||||
|
|
@ -62,7 +82,7 @@ namespace Elsa.Services.Models
|
|||
Workflow.StartedAt = clock.GetCurrentInstant();
|
||||
Workflow.Status = WorkflowStatus.Executing;
|
||||
}
|
||||
|
||||
|
||||
public void Fault(IActivity activity, Exception exception) => Fault(activity, exception.Message);
|
||||
|
||||
public void Fault(IActivity activity, string errorMessage)
|
||||
|
|
@ -88,11 +108,16 @@ namespace Elsa.Services.Models
|
|||
Workflow.Status = WorkflowStatus.Finished;
|
||||
Workflow.BlockingActivities.Clear();
|
||||
}
|
||||
|
||||
|
||||
public void Abort()
|
||||
{
|
||||
Workflow.AbortedAt = clock.GetCurrentInstant();
|
||||
Workflow.Status = WorkflowStatus.Aborted;
|
||||
}
|
||||
|
||||
public Variables GetVariables() => Workflow.Scopes
|
||||
.Reverse()
|
||||
.Select(x => x.Variables)
|
||||
.Aggregate(Variables.Empty, (x, y) => new Variables(x.Union(y)));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,58 +1,55 @@
|
|||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Elsa.Attributes;
|
||||
using Elsa.Expressions;
|
||||
using Elsa.Results;
|
||||
using Elsa.Services;
|
||||
using Elsa.Services.Models;
|
||||
|
||||
namespace Elsa.Activities.Primitives
|
||||
{
|
||||
[ActivityDefinition(
|
||||
DisplayName = "Set Variable",
|
||||
Description = "Set variable on the workflow.",
|
||||
Category = "Primitives"
|
||||
)]
|
||||
[ActivityDefinitionDesigner(
|
||||
Description =
|
||||
"x => !!x.state.variableName ? `<strong>${x.state.variableName}</strong> = <strong>${x.state.valueExpression.expression}</strong><br/>${x.state.valueExpression.syntax}` : x.definition.description",
|
||||
Outcomes = new[] { OutcomeNames.Done }
|
||||
)]
|
||||
public class SetVariable : Activity
|
||||
{
|
||||
private readonly IWorkflowExpressionEvaluator expressionEvaluator;
|
||||
|
||||
public SetVariable(IWorkflowExpressionEvaluator expressionEvaluator)
|
||||
{
|
||||
this.expressionEvaluator = expressionEvaluator;
|
||||
}
|
||||
|
||||
[ActivityProperty(Hint = "The name of the variable to store the value into.")]
|
||||
public string VariableName
|
||||
{
|
||||
get => GetState<string>();
|
||||
set => SetState(value);
|
||||
}
|
||||
|
||||
[ActivityProperty(Hint = "An expression that evaluates to the value to store in the variable.")]
|
||||
public WorkflowExpression ValueExpression
|
||||
{
|
||||
get => GetState<WorkflowExpression>();
|
||||
set => SetState(value);
|
||||
}
|
||||
|
||||
protected override async Task<ActivityExecutionResult> OnExecuteAsync(
|
||||
WorkflowExecutionContext workflowContext,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var value = await expressionEvaluator.EvaluateAsync(
|
||||
ValueExpression,
|
||||
ValueExpression.Type,
|
||||
workflowContext,
|
||||
cancellationToken
|
||||
);
|
||||
workflowContext.CurrentScope.SetVariable(VariableName, value);
|
||||
return Done();
|
||||
}
|
||||
}
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Elsa.Attributes;
|
||||
using Elsa.Expressions;
|
||||
using Elsa.Results;
|
||||
using Elsa.Services;
|
||||
using Elsa.Services.Models;
|
||||
|
||||
namespace Elsa.Activities
|
||||
{
|
||||
[ActivityDefinition(
|
||||
DisplayName = "Set Variable",
|
||||
Description = "Set variable on the workflow.",
|
||||
Category = "Primitives",
|
||||
RuntimeDescription = "x => !!x.state.variableName ? `<strong>${x.state.variableName}</strong> = <strong>${x.state.valueExpression.expression}</strong><br/>${x.state.valueExpression.syntax}` : x.definition.description",
|
||||
Outcomes = new[] { OutcomeNames.Done }
|
||||
)]
|
||||
public class SetVariable : Activity
|
||||
{
|
||||
private readonly IWorkflowExpressionEvaluator expressionEvaluator;
|
||||
|
||||
public SetVariable(IWorkflowExpressionEvaluator expressionEvaluator)
|
||||
{
|
||||
this.expressionEvaluator = expressionEvaluator;
|
||||
}
|
||||
|
||||
[ActivityProperty(Hint = "The name of the variable to store the value into.")]
|
||||
public string VariableName
|
||||
{
|
||||
get => GetState<string>();
|
||||
set => SetState(value);
|
||||
}
|
||||
|
||||
[ActivityProperty(Hint = "An expression that evaluates to the value to store in the variable.")]
|
||||
public WorkflowExpression ValueExpression
|
||||
{
|
||||
get => GetState<WorkflowExpression>();
|
||||
set => SetState(value);
|
||||
}
|
||||
|
||||
protected override async Task<ActivityExecutionResult> OnExecuteAsync(
|
||||
WorkflowExecutionContext workflowContext,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var value = await expressionEvaluator.EvaluateAsync(
|
||||
ValueExpression,
|
||||
ValueExpression.Type,
|
||||
workflowContext,
|
||||
cancellationToken
|
||||
);
|
||||
workflowContext.SetVariable(VariableName, value);
|
||||
return Done();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<LangVersion>8</LangVersion>
|
||||
<RootNamespace>Elsa</RootNamespace>
|
||||
<PackageVersion>1.0.0</PackageVersion>
|
||||
<Authors>Sipke Schoorstra</Authors>
|
||||
|
|
@ -16,10 +16,11 @@
|
|||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AutoMapper" Version="9.0.0" />
|
||||
<PackageReference Include="Humanizer.Core" Version="2.7.9" />
|
||||
<PackageReference Include="MediatR" Version="7.0.0" />
|
||||
<PackageReference Include="MediatR.Extensions.Microsoft.DependencyInjection" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Hosting.Server.Abstractions" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.CSharp" Version="4.5.0" />
|
||||
<PackageReference Include="Microsoft.CSharp" Version="4.6.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="3.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="3.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.0.0" />
|
||||
|
|
@ -29,14 +30,14 @@
|
|||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="3.0.0" />
|
||||
<PackageReference Include="NodaTime.Serialization.JsonNet" Version="2.2.0" />
|
||||
<PackageReference Include="Elsa.Scrutor" Version="3.0.2.25" />
|
||||
<PackageReference Include="Elsa.Scrutor" Version="3.0.2.26" />
|
||||
|
||||
<PackageReference Include="YamlDotNet.NetStandard" Version="4.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\utils\Elsa.AutoMapper.Extensions\Elsa.AutoMapper.Extensions.csproj" />
|
||||
<ProjectReference Include="..\Elsa.Abstractions\Elsa.Abstractions.csproj" />
|
||||
<ProjectReference Include="..\Elsa.AutoMapper.Extensions\Elsa.AutoMapper.Extensions.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -2,16 +2,13 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Elsa;
|
||||
using Elsa.Activities.ControlFlow;
|
||||
using Elsa.Activities.Primitives;
|
||||
using Elsa.Activities.Workflows;
|
||||
using Elsa.Activities;
|
||||
using Elsa.AutoMapper.Extensions;
|
||||
using Elsa.Caching;
|
||||
using Elsa.Expressions;
|
||||
using Elsa.Mapping;
|
||||
using Elsa.Persistence;
|
||||
using Elsa.Persistence.Memory;
|
||||
using Elsa.Scripting;
|
||||
using Elsa.Serialization;
|
||||
using Elsa.Serialization.Formatters;
|
||||
using Elsa.Services;
|
||||
|
|
@ -28,7 +25,7 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
{
|
||||
public static class ElsaServiceCollectionExtensions
|
||||
{
|
||||
public static IServiceCollection AddWorkflows(
|
||||
public static IServiceCollection AddElsaCore(
|
||||
this IServiceCollection services,
|
||||
Action<ElsaBuilder> configure = null)
|
||||
{
|
||||
|
|
@ -115,12 +112,9 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
.TryAddProvider<ITokenFormatter, YamlTokenFormatter>(ServiceLifetime.Singleton)
|
||||
.TryAddProvider<ITokenFormatter, XmlTokenFormatter>(ServiceLifetime.Singleton)
|
||||
.TryAddProvider<IExpressionEvaluator, LiteralEvaluator>(ServiceLifetime.Singleton)
|
||||
.TryAddProvider<IExpressionEvaluator, JavaScriptEvaluator>(ServiceLifetime.Singleton)
|
||||
.AddSingleton<IScriptEngineConfigurator, CommonScriptEngineConfigurator>()
|
||||
.AddSingleton<IScriptEngineConfigurator, DateTimeScriptEngineConfigurator>()
|
||||
.AddScoped<IWorkflowFactory, WorkflowFactory>()
|
||||
.AddSingleton<IActivityInvoker, ActivityInvoker>()
|
||||
.AddSingleton<IWorkflowExpressionEvaluator, WorkflowExpressionEvaluator>()
|
||||
.AddScoped<IWorkflowExpressionEvaluator, WorkflowExpressionEvaluator>()
|
||||
.AddSingleton<IWorkflowSerializerProvider, WorkflowSerializerProvider>()
|
||||
.AddSingleton<IWorkflowRegistry, WorkflowRegistry>()
|
||||
.AddScoped<IWorkflowEventHandler, PersistenceWorkflowEventHandler>()
|
||||
|
|
@ -133,9 +127,7 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
.AddTransient<IWorkflowBuilder, WorkflowBuilder>()
|
||||
.AddTransient<Func<IWorkflowBuilder>>(sp => sp.GetRequiredService<IWorkflowBuilder>)
|
||||
.AddAutoMapperProfile<WorkflowDefinitionProfile>(ServiceLifetime.Singleton)
|
||||
.AddPrimitiveActivities()
|
||||
.AddControlFlowActivities()
|
||||
.AddWorkflowActivities();
|
||||
.AddPrimitiveActivities();
|
||||
|
||||
return configuration;
|
||||
}
|
||||
|
|
@ -170,27 +162,5 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
return services
|
||||
.AddActivity<SetVariable>();
|
||||
}
|
||||
|
||||
private static IServiceCollection AddControlFlowActivities(this IServiceCollection services)
|
||||
{
|
||||
return services
|
||||
.AddActivity<ForEach>()
|
||||
.AddActivity<Fork>()
|
||||
.AddActivity<Join>()
|
||||
.AddSingleton<IWorkflowEventHandler>(sp => sp.GetRequiredService<Join>())
|
||||
.AddActivity<IfElse>()
|
||||
.AddActivity<Switch>();
|
||||
}
|
||||
|
||||
private static IServiceCollection AddWorkflowActivities(this IServiceCollection services)
|
||||
{
|
||||
return services
|
||||
.AddActivity<TriggerWorkflow>()
|
||||
.AddActivity<Correlate>()
|
||||
.AddActivity<Signaled>()
|
||||
.AddActivity<Trigger>()
|
||||
.AddActivity<Start>()
|
||||
.AddActivity<Finish>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,22 +7,20 @@ using Elsa.Attributes;
|
|||
using Elsa.Design;
|
||||
using Elsa.Expressions;
|
||||
using Elsa.Services.Models;
|
||||
using Elsa.WorkflowDesigner.Models;
|
||||
using Humanizer;
|
||||
|
||||
namespace Elsa.WorkflowDesigner
|
||||
namespace Elsa.Metadata
|
||||
{
|
||||
public static class ActivityDescriber
|
||||
{
|
||||
public static ActivityDefinitionModel Describe<T>() where T : IActivity
|
||||
public static ActivityDescriptor Describe<T>() where T : IActivity
|
||||
{
|
||||
return Describe(typeof(T));
|
||||
}
|
||||
|
||||
public static ActivityDefinitionModel Describe(Type activityType)
|
||||
|
||||
public static ActivityDescriptor Describe(Type activityType)
|
||||
{
|
||||
var activityDefinitionAttribute = activityType.GetCustomAttribute<ActivityDefinitionAttribute>();
|
||||
var activityDesignerAttribute = activityType.GetCustomAttribute<ActivityDefinitionDesignerAttribute>();
|
||||
var typeName = activityDefinitionAttribute?.Type ?? activityType.Name;
|
||||
|
||||
var displayName =
|
||||
|
|
@ -30,25 +28,22 @@ namespace Elsa.WorkflowDesigner
|
|||
activityType.Name.Humanize(LetterCasing.Title);
|
||||
|
||||
var description = activityDefinitionAttribute?.Description;
|
||||
var runtimeDescription = activityDefinitionAttribute?.RuntimeDescription;
|
||||
var category = activityDefinitionAttribute?.Category ?? "Miscellaneous";
|
||||
var icon = activityDefinitionAttribute?.Icon;
|
||||
var designerDescription = activityDesignerAttribute?.Description;
|
||||
var designerOutcomes = activityDesignerAttribute?.Outcomes ?? new[] { OutcomeNames.Done };
|
||||
var outcomes = activityDefinitionAttribute?.Outcomes ?? new[] { OutcomeNames.Done };
|
||||
var properties = DescribeProperties(activityType);
|
||||
|
||||
return new ActivityDefinitionModel
|
||||
return new ActivityDescriptor
|
||||
{
|
||||
Type = typeName.Pascalize(),
|
||||
DisplayName = displayName,
|
||||
Description = description,
|
||||
RuntimeDescription = runtimeDescription,
|
||||
Category = category,
|
||||
Icon = icon,
|
||||
Properties = properties.ToArray(),
|
||||
Designer = new ActivityDesignerSettings
|
||||
{
|
||||
Description = designerDescription,
|
||||
Outcomes = designerOutcomes
|
||||
}
|
||||
Outcomes = outcomes
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -61,7 +56,7 @@ namespace Elsa.WorkflowDesigner
|
|||
var activityProperty = propertyInfo.GetCustomAttribute<ActivityPropertyAttribute>();
|
||||
|
||||
if (activityProperty == null)
|
||||
yield break;
|
||||
continue;
|
||||
|
||||
yield return new ActivityPropertyDescriptor
|
||||
(
|
||||
|
|
@ -1,23 +1,24 @@
|
|||
namespace Elsa.WorkflowDesigner.Models
|
||||
namespace Elsa.Metadata
|
||||
{
|
||||
public class ActivityDefinitionModel
|
||||
public class ActivityDescriptor
|
||||
{
|
||||
public ActivityDefinitionModel()
|
||||
public ActivityDescriptor()
|
||||
{
|
||||
Type = "Activity";
|
||||
Properties = new ActivityPropertyDescriptor[0];
|
||||
Category = "Miscellaneous";
|
||||
DisplayName = "Activity";
|
||||
Properties = new ActivityPropertyDescriptor[0];
|
||||
Designer = new ActivityDesignerSettings();
|
||||
Outcomes = null;
|
||||
}
|
||||
|
||||
public string Type { get; set; }
|
||||
public string DisplayName { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public string? RuntimeDescription { get; set; }
|
||||
public string Category { get; set; }
|
||||
public string? Icon { get; set; }
|
||||
public object? Outcomes { get; set; }
|
||||
public ActivityPropertyDescriptor[] Properties { get; set; }
|
||||
public ActivityDesignerSettings Designer { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
namespace Elsa.WorkflowDesigner.Models
|
||||
namespace Elsa.Metadata
|
||||
{
|
||||
public class ActivityPropertyDescriptor
|
||||
{
|
||||
|
|
@ -52,8 +52,7 @@ namespace Elsa.Services
|
|||
var id = idGenerator.Generate();
|
||||
var workflow = new Workflow(
|
||||
id,
|
||||
definition.DefinitionId,
|
||||
definition.Version,
|
||||
definition,
|
||||
clock.GetCurrentInstant(),
|
||||
activities,
|
||||
connections,
|
||||
|
|
|
|||
|
|
@ -8,25 +8,27 @@ namespace Elsa.WorkflowBuilders
|
|||
{
|
||||
public class ActivityBuilder : IActivityBuilder
|
||||
{
|
||||
public ActivityBuilder(WorkflowBuilder workflowBuilder, ActivityDefinition activity, string id)
|
||||
public ActivityBuilder(WorkflowBuilder workflowBuilder, ActivityDefinition activity)
|
||||
{
|
||||
WorkflowBuilder = workflowBuilder;
|
||||
Activity = activity;
|
||||
Id = id;
|
||||
}
|
||||
|
||||
public WorkflowBuilder WorkflowBuilder { get; }
|
||||
public ActivityDefinition Activity { get; }
|
||||
public string Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string DisplayName { get; set; }
|
||||
|
||||
public IActivityBuilder StartWith<T>(Action<T> setup = default, string id = default) where T : class, IActivity
|
||||
public IActivityBuilder StartWith<T>(Action<T> setup = default, string name = default) where T : class, IActivity
|
||||
{
|
||||
return Add(setup, id);
|
||||
return Add(setup, name);
|
||||
}
|
||||
|
||||
public IActivityBuilder Add<T>(Action<T> setup = default, string id = null) where T : class, IActivity
|
||||
public IActivityBuilder Add<T>(Action<T> setup = default, string name = default) where T : class, IActivity
|
||||
{
|
||||
return WorkflowBuilder.Add(setup, id);
|
||||
return WorkflowBuilder.Add(setup, name);
|
||||
}
|
||||
|
||||
public IOutcomeBuilder When(string outcome)
|
||||
|
|
@ -34,31 +36,53 @@ namespace Elsa.WorkflowBuilders
|
|||
return new OutcomeBuilder(WorkflowBuilder, this, outcome);
|
||||
}
|
||||
|
||||
public IActivityBuilder Then<T>(Action<T> setup = null, Action<IActivityBuilder> branch = null, string id = null) where T : class, IActivity
|
||||
public IActivityBuilder Then<T>(Action<T> setup = null, Action<IActivityBuilder> branch = null, string name = default) where T : class, IActivity
|
||||
{
|
||||
var activityBuilder = When(null).Then(setup, branch, id);
|
||||
var activityBuilder = When(null).Then(setup, branch, name);
|
||||
return activityBuilder;
|
||||
}
|
||||
|
||||
public IActivityBuilder WithId(string id)
|
||||
public IActivityBuilder WithName(string name)
|
||||
{
|
||||
Id = id;
|
||||
Name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IActivityBuilder WithDisplayName(string displayName)
|
||||
{
|
||||
DisplayName = displayName;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IWorkflowBuilder Then(string activityId)
|
||||
public IActivityBuilder WithDescription(string description)
|
||||
{
|
||||
Description = description;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IWorkflowBuilder Then(string activityName)
|
||||
{
|
||||
WorkflowBuilder.Connect(
|
||||
() => this,
|
||||
() => WorkflowBuilder.Activities.First(x => x.Id == activityId)
|
||||
() => WorkflowBuilder.Activities.First(x => x.Name== activityName)
|
||||
);
|
||||
|
||||
return WorkflowBuilder;
|
||||
}
|
||||
|
||||
public IActivityBuilder Then(IActivityBuilder targetActivity)
|
||||
{
|
||||
WorkflowBuilder.Connect(this, targetActivity);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ActivityDefinition BuildActivity()
|
||||
{
|
||||
Activity.Id = Id;
|
||||
Activity.Name = Name;
|
||||
Activity.DisplayName = Name;
|
||||
Activity.Description = Description;
|
||||
Activity.DisplayName = DisplayName;
|
||||
return Activity;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,9 +19,9 @@ namespace Elsa.WorkflowBuilders
|
|||
public IActivityBuilder Source { get; }
|
||||
public string Outcome { get; }
|
||||
|
||||
public IActivityBuilder Then<T>(Action<T> setup = default, Action<IActivityBuilder> branch = null, string id = default) where T : class, IActivity
|
||||
public IActivityBuilder Then<T>(Action<T> setup = default, Action<IActivityBuilder> branch = default, string name = default) where T : class, IActivity
|
||||
{
|
||||
var target = WorkflowBuilder.Add(setup, id);
|
||||
var target = WorkflowBuilder.Add(setup, name);
|
||||
branch?.Invoke(target);
|
||||
|
||||
WorkflowBuilder.Connect(Source, target, Outcome);
|
||||
|
|
@ -30,11 +30,11 @@ namespace Elsa.WorkflowBuilders
|
|||
|
||||
public WorkflowDefinitionVersion Build() => WorkflowBuilder.Build();
|
||||
|
||||
public IConnectionBuilder Then(string activityId)
|
||||
public IConnectionBuilder Then(string activityName)
|
||||
{
|
||||
return WorkflowBuilder.Connect(
|
||||
() => Source,
|
||||
() => WorkflowBuilder.Activities.First(x => x.Id == activityId),
|
||||
() => WorkflowBuilder.Activities.First(x => x.Name == activityName),
|
||||
Outcome);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Elsa.Metadata;
|
||||
using Elsa.Models;
|
||||
using Elsa.Services;
|
||||
using Elsa.Services.Models;
|
||||
|
|
@ -59,30 +60,29 @@ namespace Elsa.WorkflowBuilders
|
|||
IsSingleton = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public IWorkflowBuilder Disable()
|
||||
{
|
||||
IsDisabled = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public IWorkflowBuilder Enable()
|
||||
{
|
||||
IsDisabled = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IActivityBuilder Add<T>(
|
||||
Action<T> setupActivity = default,
|
||||
string id = default) where T : class, IActivity
|
||||
public IActivityBuilder Add<T>(Action<T> setupActivity = default, string name = default) where T : class, IActivity
|
||||
{
|
||||
var activity = activityResolver.ResolveActivity(setupActivity);
|
||||
var activityBlueprint = ActivityDefinition.FromActivity(activity);
|
||||
var activityBuilder = new ActivityBuilder(this, activityBlueprint, id);
|
||||
|
||||
if (id != null)
|
||||
activity.Id = id;
|
||||
|
||||
var activityBuilder = new ActivityBuilder(this, activityBlueprint);
|
||||
var activityDescriptor = ActivityDescriber.Describe<T>();
|
||||
|
||||
activity.Name = name;
|
||||
activityBuilder.DisplayName = activityDescriptor.DisplayName;
|
||||
activityBuilder.Description = activityDescriptor.Description;
|
||||
activityBuilders.Add(activityBuilder);
|
||||
return activityBuilder;
|
||||
}
|
||||
|
|
@ -107,11 +107,9 @@ namespace Elsa.WorkflowBuilders
|
|||
}
|
||||
|
||||
|
||||
public IActivityBuilder StartWith<T>(
|
||||
Action<T> setupActivity,
|
||||
string id = null) where T : class, IActivity
|
||||
public IActivityBuilder StartWith<T>(Action<T> setupActivity, string name = default) where T : class, IActivity
|
||||
{
|
||||
return Add(setupActivity, id);
|
||||
return Add(setupActivity, name);
|
||||
}
|
||||
|
||||
public WorkflowDefinitionVersion Build()
|
||||
|
|
@ -139,7 +137,11 @@ namespace Elsa.WorkflowBuilders
|
|||
connections,
|
||||
IsSingleton,
|
||||
IsDisabled,
|
||||
Variables.Empty);
|
||||
Variables.Empty)
|
||||
{
|
||||
IsPublished = true,
|
||||
IsLatest = true
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
19
src/core/Elsa/Elsa.csproj
Normal file
19
src/core/Elsa/Elsa.csproj
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\activities\Elsa.Activities.Console\Elsa.Activities.Console.csproj" />
|
||||
<ProjectReference Include="..\..\activities\Elsa.Activities.ControlFlow\Elsa.Activities.ControlFlow.csproj" />
|
||||
<ProjectReference Include="..\..\activities\Elsa.Activities.Email\Elsa.Activities.Email.csproj" />
|
||||
<ProjectReference Include="..\..\activities\Elsa.Activities.Http\Elsa.Activities.Http.csproj" />
|
||||
<ProjectReference Include="..\..\activities\Elsa.Activities.Timers\Elsa.Activities.Timers.csproj" />
|
||||
<ProjectReference Include="..\..\activities\Elsa.Activities.UserTask\Elsa.Activities.UserTask.csproj" />
|
||||
<ProjectReference Include="..\..\activities\Elsa.Activities.Workflows\Elsa.Activities.Workflows.csproj" />
|
||||
<ProjectReference Include="..\..\scripting\Elsa.Scripting.Liquid\Elsa.Scripting.Liquid.csproj" />
|
||||
<ProjectReference Include="..\Elsa.Core\Elsa.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
29
src/core/Elsa/ElsaServiceCollectionExtensions.cs
Normal file
29
src/core/Elsa/ElsaServiceCollectionExtensions.cs
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
using System;
|
||||
using Elsa;
|
||||
using Elsa.Activities.ControlFlow.Extensions;
|
||||
using Elsa.Activities.UserTask.Extensions;
|
||||
using Elsa.Activities.Workflows.Extensions;
|
||||
using Elsa.Scripting.JavaScript;
|
||||
using Elsa.Scripting.JavaScript.Extensions;
|
||||
using Elsa.Scripting.Liquid;
|
||||
using Elsa.Scripting.Liquid.Extensions;
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
namespace Microsoft.Extensions.DependencyInjection
|
||||
{
|
||||
public static class ElsaServiceCollectionExtensions
|
||||
{
|
||||
public static IServiceCollection AddElsa(
|
||||
this IServiceCollection services,
|
||||
Action<ElsaBuilder> configure = null)
|
||||
{
|
||||
return services
|
||||
.AddElsaCore(configure)
|
||||
.AddJavaScriptExpressionEvaluator()
|
||||
.AddLiquidExpressionEvaluator()
|
||||
.AddControlFlowActivities()
|
||||
.AddWorkflowActivities()
|
||||
.AddUserTaskActivities();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
using Elsa.Metadata;
|
||||
using Elsa.WorkflowDesigner.Models;
|
||||
|
||||
namespace Elsa.Dashboard.Areas.Elsa.ViewModels
|
||||
|
|
@ -11,7 +12,7 @@ namespace Elsa.Dashboard.Areas.Elsa.ViewModels
|
|||
public string Description { get; set; }
|
||||
public bool IsSingleton { get; set; }
|
||||
public bool IsDisabled { get; set; }
|
||||
public ActivityDefinitionModel[] ActivityDefinitions { get; set; }
|
||||
public ActivityDescriptor[] ActivityDefinitions { get; set; }
|
||||
public WorkflowModel WorkflowModel { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Elsa.Metadata;
|
||||
using Elsa.Models;
|
||||
using Elsa.WorkflowDesigner.Models;
|
||||
|
||||
|
|
@ -11,7 +12,7 @@ namespace Elsa.Dashboard.Areas.Elsa.ViewModels
|
|||
WorkflowInstance workflowInstance,
|
||||
WorkflowDefinitionVersion workflowDefinition,
|
||||
WorkflowModel workflowModel,
|
||||
IEnumerable<ActivityDefinitionModel> activityDefinitions,
|
||||
IEnumerable<ActivityDescriptor> activityDefinitions,
|
||||
string returnUrl)
|
||||
{
|
||||
WorkflowInstance = workflowInstance;
|
||||
|
|
@ -24,7 +25,7 @@ namespace Elsa.Dashboard.Areas.Elsa.ViewModels
|
|||
public WorkflowInstance WorkflowInstance { get; }
|
||||
public WorkflowDefinitionVersion WorkflowDefinition { get; }
|
||||
public WorkflowModel WorkflowModel { get; }
|
||||
public ActivityDefinitionModel[] ActivityDefinitions { get; }
|
||||
public ActivityDescriptor[] ActivityDefinitions { get; }
|
||||
public string ReturnUrl { get; }
|
||||
}
|
||||
}
|
||||
|
|
@ -32,8 +32,8 @@
|
|||
<!-- CSS Files -->
|
||||
<link href="~/_content/Elsa.Dashboard/assets/css/argon-dashboard.css?v=1.1.0" rel="stylesheet"/>
|
||||
<link href="~/_content/Elsa.Dashboard/assets/css/elsa.css?v=1.1.0" rel="stylesheet"/>
|
||||
<script type="module" src="https://unpkg.com/@@elsa-workflows/elsa-workflow-designer@0.0.59/dist/elsa-workflow-designer/elsa-workflow-designer.esm.js"></script>
|
||||
<script nomodule="" src="https://unpkg.com/@@elsa-workflows/elsa-workflow-designer@0.0.59/dist/elsa-workflow-designer/elsa-workflow-designer.js"></script>
|
||||
<script type="module" src="https://unpkg.com/@@elsa-workflows/elsa-workflow-designer@0.0.61/dist/elsa-workflow-designer/elsa-workflow-designer.esm.js"></script>
|
||||
<script nomodule="" src="https://unpkg.com/@@elsa-workflows/elsa-workflow-designer@0.0.61/dist/elsa-workflow-designer/elsa-workflow-designer.js"></script>
|
||||
@await RenderSectionAsync("HeadScripts", false)
|
||||
</head>
|
||||
|
||||
|
|
|
|||
|
|
@ -12,9 +12,6 @@
|
|||
</div>
|
||||
<div class="col-4 text-right">
|
||||
<a href="#!" class="btn btn-secondary" onclick="exportWorkflow()">Download</a>
|
||||
<a href="#!" class="btn btn-secondary" data-toggle="modal" data-target="#workflow-properties-modal">
|
||||
<i class="ni ni-settings-gear-65"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using Elsa.Dashboard.Options;
|
||||
using Elsa.Metadata;
|
||||
using Elsa.Services.Models;
|
||||
using Elsa.WorkflowDesigner;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
|
|
|||
|
|
@ -1,25 +1,26 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Elsa.Metadata;
|
||||
using Elsa.WorkflowDesigner.Models;
|
||||
|
||||
namespace Elsa.Dashboard.Options
|
||||
{
|
||||
public class ActivityDefinitionList : IEnumerable<ActivityDefinitionModel>
|
||||
public class ActivityDefinitionList : IEnumerable<ActivityDescriptor>
|
||||
{
|
||||
public ActivityDefinitionList()
|
||||
{
|
||||
Items = new Dictionary<string, ActivityDefinitionModel>();
|
||||
Items = new Dictionary<string, ActivityDescriptor>();
|
||||
}
|
||||
|
||||
private IDictionary<string, ActivityDefinitionModel> Items { get; }
|
||||
private IDictionary<string, ActivityDescriptor> Items { get; }
|
||||
|
||||
public ActivityDefinitionList Add(ActivityDefinitionModel item)
|
||||
public ActivityDefinitionList Add(ActivityDescriptor item)
|
||||
{
|
||||
Items[item.Type] = item;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IEnumerator<ActivityDefinitionModel> GetEnumerator() => Items.Values.GetEnumerator();
|
||||
public IEnumerator<ActivityDescriptor> GetEnumerator() => Items.Values.GetEnumerator();
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -15,12 +15,12 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Humanizer.Core" Version="2.7.2" />
|
||||
<PackageReference Include="Humanizer.Core" Version="2.7.9" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\core\Elsa.Abstractions\Elsa.Abstractions.csproj" />
|
||||
<ProjectReference Include="..\..\core\Elsa.Core\Elsa.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
namespace Elsa.WorkflowDesigner.Models
|
||||
{
|
||||
public class ActivityDesignerSettings
|
||||
{
|
||||
public object? Description { get; set; }
|
||||
public object? Outcomes { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
using Elsa.Metadata;
|
||||
using Elsa.WorkflowDesigner.Models;
|
||||
using Elsa.WorkflowDesigner.ViewModels;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
|
@ -10,13 +11,13 @@ namespace Elsa.WorkflowDesigner.ViewComponents
|
|||
{
|
||||
public IViewComponentResult Invoke(
|
||||
string id,
|
||||
ActivityDefinitionModel[]? activityDefinitions = null,
|
||||
ActivityDescriptor[]? activityDefinitions = null,
|
||||
WorkflowModel? workflow = null,
|
||||
bool? isReadonly = null)
|
||||
{
|
||||
var model = new WorkflowDesignerViewComponentModel(
|
||||
id,
|
||||
Serialize(activityDefinitions ?? new ActivityDefinitionModel[0]),
|
||||
Serialize(activityDefinitions ?? new ActivityDescriptor[0]),
|
||||
Serialize(workflow ?? new WorkflowModel()),
|
||||
isReadonly.GetValueOrDefault()
|
||||
);
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Azure.DocumentDB.Core" Version="2.6.0" />
|
||||
<PackageReference Include="Microsoft.Azure.DocumentDB.Core" Version="2.8.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<PackageVersion>1.0.0</PackageVersion>
|
||||
<Authors>Sipke Schoorstra</Authors>
|
||||
|
|
@ -15,11 +15,11 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FlexLabs.EntityFrameworkCore.Upsert" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.2.6" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.2.6" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.2.6" />
|
||||
<PackageReference Include="FlexLabs.EntityFrameworkCore.Upsert" Version="3.0.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.0.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.0.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="3.0.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\core\Elsa.AutoMapper.Extensions\Elsa.AutoMapper.Extensions.csproj" />
|
||||
<ProjectReference Include="..\..\core\Elsa.Core\Elsa.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Elsa.Persistence.MongoDb.Extensions
|
||||
namespace Elsa.Persistence.MongoDb
|
||||
{
|
||||
public class MongoElsaBuilder : ElsaBuilder
|
||||
{
|
||||
|
|
|
|||
|
|
@ -15,17 +15,16 @@
|
|||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\core\Elsa.Abstractions\Elsa.Abstractions.csproj" />
|
||||
<ProjectReference Include="..\..\core\Elsa.AutoMapper.Extensions\Elsa.AutoMapper.Extensions.csproj" />
|
||||
<ProjectReference Include="..\..\core\Elsa.Core\Elsa.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="3.0.0" />
|
||||
<PackageReference Include="YesSql.Core" Version="2.0.0-beta-1395" />
|
||||
<PackageReference Include="YesSql.Provider.MySql" Version="1.0.0-beta-1395" />
|
||||
<PackageReference Include="YesSql.Provider.PostgreSql" Version="1.0.0-beta-1395" />
|
||||
<PackageReference Include="YesSql.Provider.Sqlite" Version="1.0.0-beta-1395" />
|
||||
<PackageReference Include="YesSql.Provider.SqlServer" Version="1.0.0-beta-1395" />
|
||||
<PackageReference Include="YesSql.Core" Version="2.0.0-beta-1437" />
|
||||
<PackageReference Include="YesSql.Provider.MySql" Version="1.0.0-beta-1437" />
|
||||
<PackageReference Include="YesSql.Provider.PostgreSql" Version="1.0.0-beta-1437" />
|
||||
<PackageReference Include="YesSql.Provider.Sqlite" Version="1.0.0-beta-1437" />
|
||||
<PackageReference Include="YesSql.Provider.SqlServer" Version="1.0.0-beta-1437" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ namespace Sample01
|
|||
{
|
||||
// Setup a service collection.
|
||||
var services = new ServiceCollection()
|
||||
.AddWorkflows()
|
||||
.AddElsa()
|
||||
.AddActivity<HelloWorld>()
|
||||
.AddActivity<GoodByeWorld>()
|
||||
.BuildServiceProvider();
|
||||
|
|
|
|||
|
|
@ -2,12 +2,11 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\activities\Elsa.Activities.Console\Elsa.Activities.Console.csproj" />
|
||||
<ProjectReference Include="..\..\core\Elsa.Core\Elsa.Core.csproj" />
|
||||
<ProjectReference Include="..\..\core\Elsa\Elsa.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ namespace Sample02
|
|||
{
|
||||
// Setup a service collection.
|
||||
var services = new ServiceCollection()
|
||||
.AddWorkflows()
|
||||
.AddElsa()
|
||||
.AddConsoleActivities()
|
||||
.BuildServiceProvider();
|
||||
|
||||
|
|
|
|||
|
|
@ -2,12 +2,11 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\activities\Elsa.Activities.Console\Elsa.Activities.Console.csproj" />
|
||||
<ProjectReference Include="..\..\core\Elsa.Core\Elsa.Core.csproj" />
|
||||
<ProjectReference Include="..\..\core\Elsa\Elsa.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ namespace Sample03
|
|||
{
|
||||
// Setup a service collection.
|
||||
var services = new ServiceCollection()
|
||||
.AddWorkflows()
|
||||
.AddElsa()
|
||||
.AddConsoleActivities()
|
||||
.BuildServiceProvider();
|
||||
|
||||
|
|
|
|||
|
|
@ -2,12 +2,11 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\activities\Elsa.Activities.Console\Elsa.Activities.Console.csproj" />
|
||||
<ProjectReference Include="..\..\core\Elsa.Core\Elsa.Core.csproj" />
|
||||
<ProjectReference Include="..\..\core\Elsa\Elsa.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
using Elsa;
|
||||
using Elsa.Activities;
|
||||
using Elsa.Activities.Console.Activities;
|
||||
using Elsa.Activities.ControlFlow;
|
||||
using Elsa.Activities.ControlFlow.Activities;
|
||||
using Elsa.Expressions;
|
||||
using Elsa.Scripting.JavaScript;
|
||||
using Elsa.Services;
|
||||
using Elsa.Services.Models;
|
||||
using Sample04.Activities;
|
||||
|
|
@ -13,57 +16,65 @@ namespace Sample04
|
|||
public void Build(IWorkflowBuilder builder)
|
||||
{
|
||||
builder
|
||||
.StartWith<WriteLine>(x => x.TextExpression = new LiteralExpression("Welcome to Calculator Workflow!"), "welcome")
|
||||
.Then<WriteLine>(x => x.TextExpression = new LiteralExpression("Enter number 1:"), id: "enter-first-number-prompt")
|
||||
.Then<ReadLine>(x => x.VariableName = "number1", id: "read-first-number")
|
||||
.Then<WriteLine>(x => x.TextExpression = new LiteralExpression("Enter number 2:"), id: "enter-second-number-prompt")
|
||||
.Then<ReadLine>(x => x.VariableName = "number2", id: "read-second-number")
|
||||
.Then<WriteLine>(x => x.TextExpression = new LiteralExpression("Now enter the operation you wish to apply. Options are: add, subtract, multiply or divide:"), id: "enter-operation-prompt")
|
||||
.Then<ReadLine>(x => x.VariableName = "operation", id: "read-operation")
|
||||
.Then<Switch>(@switch =>
|
||||
.StartWith<WriteLine>(x => x.TextExpression = new LiteralExpression("Welcome to Calculator Workflow!")).WithDisplayName("Welcome")
|
||||
.Then<SetVariable>(
|
||||
x =>
|
||||
{
|
||||
@switch.Expression = new JavaScriptExpression<string>("operation");
|
||||
@switch.Cases = new[] { "add", "subtract", "multiply", "divide" };
|
||||
},
|
||||
@switch =>
|
||||
x.VariableName = "Exit";
|
||||
x.ValueExpression = new JavaScriptExpression<bool>("false");
|
||||
}).WithDisplayName("Initialize Exit Variable")
|
||||
.Then<While>(
|
||||
x => x.ConditionExpression = new JavaScriptExpression<bool>("!Exit"),
|
||||
whileActivity =>
|
||||
{
|
||||
@switch
|
||||
.When("add")
|
||||
.Then<Sum>(SetupOperation, id: "perform-sum")
|
||||
.Then("show-result");
|
||||
|
||||
@switch
|
||||
.When("subtract")
|
||||
.Then<Subtract>(SetupOperation, id: "perform-subtract")
|
||||
.Then("show-result");
|
||||
|
||||
@switch
|
||||
.When("multiply")
|
||||
.Then<Multiply>(SetupOperation, id: "perform-multiply")
|
||||
.Then("show-result");
|
||||
|
||||
@switch
|
||||
.When("divide")
|
||||
.Then<Divide>(SetupOperation, id: "perform-divide")
|
||||
.Then("show-result");
|
||||
},
|
||||
"inspect-selected-operation"
|
||||
)
|
||||
.Add<WriteLine>(x => x.TextExpression = new JavaScriptExpression<string>("`Result: ${result}`"), "show-result")
|
||||
.Then<WriteLine>(x => x.TextExpression = new LiteralExpression("Try again? (y/n)"), id: "try-again-prompt")
|
||||
.Then<ReadLine>(x => x.VariableName = "retry", id: "read-try-again")
|
||||
.Then<IfElse>(
|
||||
x => x.ConditionExpression = new JavaScriptExpression<bool>("retry.toLowerCase() === 'y'"),
|
||||
ifElse =>
|
||||
{
|
||||
ifElse
|
||||
.When(OutcomeNames.True)
|
||||
.Then("enter-first-number-prompt");
|
||||
|
||||
ifElse
|
||||
.When(OutcomeNames.False)
|
||||
.Then<WriteLine>(x => x.TextExpression = new LiteralExpression("Bye!"), id: "say-good-bye");
|
||||
}, id: "inspect-retry");
|
||||
whileActivity
|
||||
.When(OutcomeNames.Iterate)
|
||||
.Then<WriteLine>(x => x.TextExpression = new LiteralExpression("Enter number 1:"))
|
||||
.Then<ReadLine>(x => x.VariableName = "number1")
|
||||
.Then<WriteLine>(x => x.TextExpression = new LiteralExpression("Enter number 2:"))
|
||||
.Then<ReadLine>(x => x.VariableName = "number2")
|
||||
.Then<WriteLine>(x => x.TextExpression = new LiteralExpression("Now enter the operation you wish to apply. Options are: add, subtract, multiply or divide:"))
|
||||
.Then<ReadLine>(x => x.VariableName = "operation")
|
||||
.Then<Switch>(
|
||||
@switch =>
|
||||
{
|
||||
@switch.Expression = new JavaScriptExpression<string>("operation");
|
||||
@switch.Cases = new[] { "add", "subtract", "multiply", "divide" };
|
||||
},
|
||||
@switch =>
|
||||
{
|
||||
@switch
|
||||
.When("add")
|
||||
.Then<Sum>(SetupOperation).WithName("PerformSum")
|
||||
.Then("ShowResult");
|
||||
|
||||
@switch
|
||||
.When("subtract")
|
||||
.Then<Subtract>(SetupOperation).WithName("PerformSubtract")
|
||||
.Then("ShowResult");
|
||||
|
||||
@switch
|
||||
.When("multiply")
|
||||
.Then<Multiply>(SetupOperation).WithName("PerformMultiply")
|
||||
.Then("ShowResult");
|
||||
|
||||
@switch
|
||||
.When("divide")
|
||||
.Then<Divide>(SetupOperation).WithName("PerformDivide")
|
||||
.Then("ShowResult");
|
||||
}
|
||||
).WithName("InspectSelectedOperation")
|
||||
.Add<WriteLine>(x => x.TextExpression = new JavaScriptExpression<string>("`Result: ${result}`")).WithName("ShowResult")
|
||||
.Then<WriteLine>(x => x.TextExpression = new LiteralExpression("Try again? (y/n)"))
|
||||
.Then<ReadLine>().WithName("TryAgain")
|
||||
.Then<SetVariable>(x =>
|
||||
{
|
||||
x.VariableName = "Exit";
|
||||
x.ValueExpression = new JavaScriptExpression<bool>("TryAgain.Input !== 'y' && TryAgain.Input !== 'Y'");
|
||||
})
|
||||
.Then(whileActivity);
|
||||
}).WithDisplayName("While")
|
||||
.Then<WriteLine>(x => x.TextExpression = new LiteralExpression("Bye!"));
|
||||
}
|
||||
|
||||
private void SetupOperation(ArithmeticOperation operation)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Elsa.Activities.Console.Extensions;
|
||||
using Elsa.Services;
|
||||
|
|
@ -16,7 +17,8 @@ namespace Sample04
|
|||
{
|
||||
// Setup a service collection.
|
||||
var services = new ServiceCollection()
|
||||
.AddWorkflows()
|
||||
.AddSingleton(Console.In)
|
||||
.AddElsa()
|
||||
.AddConsoleActivities()
|
||||
.AddActivity<Sum>()
|
||||
.AddActivity<Subtract>()
|
||||
|
|
@ -35,7 +37,8 @@ namespace Sample04
|
|||
Console.WriteLine("Workflow has ended. Here are the activities that have executed:");
|
||||
foreach (var logEntry in workflow.ExecutionLog)
|
||||
{
|
||||
Console.WriteLine("{0}: {1}", logEntry.Timestamp, logEntry.ActivityId);
|
||||
var activity = workflow.Definition.Activities.First(x => x.Id == logEntry.ActivityId);
|
||||
Console.WriteLine("{0}: {1}", logEntry.Timestamp, activity.DisplayName);
|
||||
}
|
||||
Console.ReadLine();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,8 +6,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\activities\Elsa.Activities.Console\Elsa.Activities.Console.csproj" />
|
||||
<ProjectReference Include="..\..\core\Elsa.Core\Elsa.Core.csproj" />
|
||||
<ProjectReference Include="..\..\core\Elsa\Elsa.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -31,9 +31,9 @@ namespace Sample05
|
|||
private static void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services
|
||||
.AddWorkflows()
|
||||
.AddWorkflow<RecurringWorkflow>()
|
||||
.AddElsa()
|
||||
.AddConsoleActivities()
|
||||
.AddWorkflow<RecurringWorkflow>()
|
||||
.AddTimerActivities(options => options.Configure(x => x.SweepInterval = Period.FromSeconds(1)));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ using System;
|
|||
using Elsa.Activities.Console.Activities;
|
||||
using Elsa.Activities.Timers.Activities;
|
||||
using Elsa.Expressions;
|
||||
using Elsa.Scripting.JavaScript;
|
||||
using Elsa.Services;
|
||||
using Elsa.Services.Models;
|
||||
|
||||
|
|
|
|||
|
|
@ -6,9 +6,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\activities\Elsa.Activities.Console\Elsa.Activities.Console.csproj" />
|
||||
<ProjectReference Include="..\..\activities\Elsa.Activities.Timers\Elsa.Activities.Timers.csproj" />
|
||||
<ProjectReference Include="..\..\core\Elsa.Core\Elsa.Core.csproj" />
|
||||
<ProjectReference Include="..\..\core\Elsa\Elsa.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -5,8 +5,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\activities\Elsa.Activities.Http\Elsa.Activities.Http.csproj" />
|
||||
<ProjectReference Include="..\..\core\Elsa.Core\Elsa.Core.csproj" />
|
||||
<ProjectReference Include="..\..\core\Elsa\Elsa.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ namespace Sample06
|
|||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services
|
||||
.AddWorkflows()
|
||||
.AddElsa()
|
||||
.AddHttpActivities()
|
||||
.AddWorkflow<HelloWorldWorkflow>();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,13 +2,16 @@ using System;
|
|||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using Elsa;
|
||||
using Elsa.Activities;
|
||||
using Elsa.Activities.Email.Activities;
|
||||
using Elsa.Activities.Http.Activities;
|
||||
using Elsa.Activities.ControlFlow;
|
||||
using Elsa.Activities.Primitives;
|
||||
using Elsa.Activities.ControlFlow.Activities;
|
||||
using Elsa.Activities.Timers.Activities;
|
||||
using Elsa.Activities.Workflows;
|
||||
using Elsa.Activities.Workflows.Activities;
|
||||
using Elsa.Expressions;
|
||||
using Elsa.Scripting.JavaScript;
|
||||
using Elsa.Services;
|
||||
using Elsa.Services.Models;
|
||||
|
||||
|
|
@ -25,14 +28,13 @@ namespace Sample07
|
|||
x.Method = HttpMethod.Post.Method;
|
||||
x.Path = new Uri("/documents", UriKind.Relative);
|
||||
x.ReadContent = true;
|
||||
},
|
||||
"WaitForDocument"
|
||||
)
|
||||
}
|
||||
).WithName("WaitForDocument")
|
||||
.Then<SetVariable>(
|
||||
x =>
|
||||
{
|
||||
x.VariableName = "Document";
|
||||
x.ValueExpression = new JavaScriptExpression<object>("lastResult().Content");
|
||||
x.ValueExpression = new JavaScriptExpression<object>("WaitForDocument.Content");
|
||||
}
|
||||
)
|
||||
.Then<SendEmail>(
|
||||
|
|
@ -83,9 +85,8 @@ namespace Sample07
|
|||
fork
|
||||
.When("Remind")
|
||||
.Then<TimerEvent>(
|
||||
x => x.TimeoutExpression = new LiteralExpression<TimeSpan>("00:00:10"),
|
||||
id: "RemindTimer"
|
||||
)
|
||||
x => x.TimeoutExpression = new LiteralExpression<TimeSpan>("00:00:10")
|
||||
).WithName("RemindTimer")
|
||||
.Then<IfElse>(
|
||||
x => x.ConditionExpression = new JavaScriptExpression<bool>("!!Approved"),
|
||||
ifElse =>
|
||||
|
|
@ -112,7 +113,7 @@ namespace Sample07
|
|||
);
|
||||
}
|
||||
)
|
||||
.Then<Join>(x => x.Mode = Join.JoinMode.WaitAny, id: "Join")
|
||||
.Then<Join>(x => x.Mode = Join.JoinMode.WaitAny).WithName("Join")
|
||||
.Then<SetVariable>(
|
||||
x =>
|
||||
{
|
||||
|
|
|
|||
|
|
@ -5,10 +5,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\activities\Elsa.Activities.Email\Elsa.Activities.Email.csproj" />
|
||||
<ProjectReference Include="..\..\activities\Elsa.Activities.Http\Elsa.Activities.Http.csproj" />
|
||||
<ProjectReference Include="..\..\activities\Elsa.Activities.Timers\Elsa.Activities.Timers.csproj" />
|
||||
<ProjectReference Include="..\..\core\Elsa.Core\Elsa.Core.csproj" />
|
||||
<ProjectReference Include="..\..\core\Elsa\Elsa.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ namespace Sample07
|
|||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services
|
||||
.AddWorkflows()
|
||||
.AddElsa()
|
||||
.AddTaskExecutingServer()
|
||||
.AddHttpActivities(options => options.Bind(Configuration.GetSection("Http")))
|
||||
.AddEmailActivities(options => options.Bind(Configuration.GetSection("Smtp")))
|
||||
|
|
|
|||
|
|
@ -5,15 +5,12 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MassTransit.AspNetCore" Version="5.5.2" />
|
||||
<PackageReference Include="MassTransit.AspNetCore" Version="5.5.6" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\activities\Elsa.Activities.Email\Elsa.Activities.Email.csproj" />
|
||||
<ProjectReference Include="..\..\activities\Elsa.Activities.Http\Elsa.Activities.Http.csproj" />
|
||||
<ProjectReference Include="..\..\activities\Elsa.Activities.MassTransit\Elsa.Activities.MassTransit.csproj" />
|
||||
<ProjectReference Include="..\..\activities\Elsa.Activities.Timers\Elsa.Activities.Timers.csproj" />
|
||||
<ProjectReference Include="..\..\core\Elsa.Core\Elsa.Core.csproj" />
|
||||
<ProjectReference Include="..\..\core\Elsa\Elsa.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ namespace Sample08
|
|||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services
|
||||
.AddWorkflows()
|
||||
.AddElsa()
|
||||
.AddTaskExecutingServer()
|
||||
.AddHttpActivities()
|
||||
.AddTimerActivities(options => options.Configure(x => x.SweepInterval = Period.FromSeconds(10)))
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using Elsa.Activities;
|
||||
using Elsa.Activities.Email.Activities;
|
||||
using Elsa.Activities.Http.Activities;
|
||||
using Elsa.Activities.MassTransit.Activities;
|
||||
using Elsa.Activities.ControlFlow;
|
||||
using Elsa.Activities.Primitives;
|
||||
using Elsa.Activities.ControlFlow.Activities;
|
||||
using Elsa.Expressions;
|
||||
using Elsa.Scripting.JavaScript;
|
||||
using Elsa.Services;
|
||||
using Elsa.Services.Models;
|
||||
using Sample08.Messages;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
using System;
|
||||
using Elsa.Activities;
|
||||
using Elsa.Activities.MassTransit.Activities;
|
||||
using Elsa.Activities.Timers.Activities;
|
||||
using Elsa.Activities.Primitives;
|
||||
using Elsa.Expressions;
|
||||
using Elsa.Scripting.JavaScript;
|
||||
using Elsa.Services;
|
||||
using Elsa.Services.Models;
|
||||
using Sample08.Messages;
|
||||
|
|
|
|||
|
|
@ -30,18 +30,17 @@ namespace Sample09
|
|||
private static IServiceProvider BuildServices()
|
||||
{
|
||||
return new ServiceCollection()
|
||||
.AddWorkflows()
|
||||
.AddElsa()
|
||||
.AddConsoleActivities()
|
||||
.AddSingleton(Console.In)
|
||||
.BuildServiceProvider();
|
||||
}
|
||||
|
||||
private static async Task<string> ReadEmbeddedResourceAsync(string resourceName)
|
||||
{
|
||||
var assembly = typeof(Program).GetTypeInfo().Assembly;
|
||||
using (var reader = new StreamReader(assembly.GetManifestResourceStream(resourceName)))
|
||||
{
|
||||
return await reader.ReadToEndAsync();
|
||||
}
|
||||
using var reader = new StreamReader(assembly.GetManifestResourceStream(resourceName));
|
||||
return await reader.ReadToEndAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,8 +7,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\activities\Elsa.Activities.Console\Elsa.Activities.Console.csproj"/>
|
||||
<ProjectReference Include="..\..\core\Elsa.Core\Elsa.Core.csproj"/>
|
||||
<ProjectReference Include="..\..\core\Elsa\Elsa.csproj"/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -25,46 +25,44 @@ namespace Sample10
|
|||
var startupRunner = services.GetRequiredService<IStartupRunner>();
|
||||
await startupRunner.StartupAsync();
|
||||
|
||||
using (var scope = services.CreateScope())
|
||||
{
|
||||
var definitionStore = scope.ServiceProvider.GetRequiredService<IWorkflowDefinitionStore>();
|
||||
var workflowDefinitionId = nameof(HelloWorldWorkflow);
|
||||
using var scope = services.CreateScope();
|
||||
var definitionStore = scope.ServiceProvider.GetRequiredService<IWorkflowDefinitionStore>();
|
||||
const string workflowDefinitionId = nameof(HelloWorldWorkflow);
|
||||
|
||||
// When running this program multiple times, we should delete the created workflow definition before adding it to the store again.
|
||||
await definitionStore.DeleteAsync(workflowDefinitionId);
|
||||
// When running this program multiple times, we should delete the created workflow definition before adding it to the store again.
|
||||
await definitionStore.DeleteAsync(workflowDefinitionId);
|
||||
|
||||
// Create a workflow definition.
|
||||
var registry = services.GetService<IWorkflowRegistry>();
|
||||
var workflowDefinition = await registry.GetWorkflowDefinitionAsync<HelloWorldWorkflow>();
|
||||
// Create a workflow definition.
|
||||
var registry = services.GetService<IWorkflowRegistry>();
|
||||
var workflowDefinition = await registry.GetWorkflowDefinitionAsync<HelloWorldWorkflow>();
|
||||
|
||||
// Mark this definition as the "latest" version.
|
||||
workflowDefinition.IsLatest = true;
|
||||
workflowDefinition.Version = 1;
|
||||
// Mark this definition as the "latest" version.
|
||||
workflowDefinition.IsLatest = true;
|
||||
workflowDefinition.Version = 1;
|
||||
|
||||
// Persist the workflow definition.
|
||||
// Persist the workflow definition.
|
||||
|
||||
await definitionStore.SaveAsync(workflowDefinition);
|
||||
await definitionStore.SaveAsync(workflowDefinition);
|
||||
|
||||
// Load the workflow definition.
|
||||
workflowDefinition = await definitionStore.GetByIdAsync(
|
||||
workflowDefinition.DefinitionId,
|
||||
VersionOptions.Latest);
|
||||
// Load the workflow definition.
|
||||
workflowDefinition = await definitionStore.GetByIdAsync(
|
||||
workflowDefinition.DefinitionId,
|
||||
VersionOptions.Latest);
|
||||
|
||||
// Execute the workflow.
|
||||
var invoker = scope.ServiceProvider.GetRequiredService<IWorkflowInvoker>();
|
||||
var executionContext = await invoker.StartAsync(workflowDefinition);
|
||||
// Execute the workflow.
|
||||
var invoker = scope.ServiceProvider.GetRequiredService<IWorkflowInvoker>();
|
||||
var executionContext = await invoker.StartAsync(workflowDefinition);
|
||||
|
||||
// Persist the workflow instance.
|
||||
var instanceStore = scope.ServiceProvider.GetRequiredService<IWorkflowInstanceStore>();
|
||||
var workflowInstance = executionContext.Workflow.ToInstance();
|
||||
await instanceStore.SaveAsync(workflowInstance);
|
||||
}
|
||||
// Persist the workflow instance.
|
||||
var instanceStore = scope.ServiceProvider.GetRequiredService<IWorkflowInstanceStore>();
|
||||
var workflowInstance = executionContext.Workflow.ToInstance();
|
||||
await instanceStore.SaveAsync(workflowInstance);
|
||||
}
|
||||
|
||||
private static IServiceProvider BuildServices()
|
||||
{
|
||||
return new ServiceCollection()
|
||||
.AddWorkflows(
|
||||
.AddElsa(
|
||||
x => x.AddYesSqlStores(
|
||||
options => options
|
||||
.UseSqLite(
|
||||
|
|
|
|||
|
|
@ -7,11 +7,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\activities\Elsa.Activities.Console\Elsa.Activities.Console.csproj"/>
|
||||
<ProjectReference Include="..\..\activities\Elsa.Activities.Email\Elsa.Activities.Email.csproj"/>
|
||||
<ProjectReference Include="..\..\activities\Elsa.Activities.Http\Elsa.Activities.Http.csproj"/>
|
||||
<ProjectReference Include="..\..\activities\Elsa.Activities.Timers\Elsa.Activities.Timers.csproj"/>
|
||||
<ProjectReference Include="..\..\core\Elsa.Core\Elsa.Core.csproj"/>
|
||||
<ProjectReference Include="..\..\core\Elsa\Elsa.csproj"/>
|
||||
<ProjectReference Include="..\..\persistence\Elsa.Persistence.YesSql\Elsa.Persistence.YesSql.csproj"/>
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
using Elsa.Activities.Console.Activities;
|
||||
using Elsa.Activities.Workflows;
|
||||
using Elsa.Activities.Workflows.Activities;
|
||||
using Elsa.Expressions;
|
||||
using Elsa.Scripting.JavaScript;
|
||||
using Elsa.Services;
|
||||
using Elsa.Services.Models;
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ using System.Linq;
|
|||
using System.Threading.Tasks;
|
||||
using Elsa.Activities.Console.Extensions;
|
||||
using Elsa.Activities.Workflows;
|
||||
using Elsa.Activities.Workflows.Activities;
|
||||
using Elsa.Extensions;
|
||||
using Elsa.Models;
|
||||
using Elsa.Services;
|
||||
|
|
@ -49,7 +50,7 @@ namespace Sample11
|
|||
private static IServiceProvider BuildServices()
|
||||
{
|
||||
return new ServiceCollection()
|
||||
.AddWorkflows()
|
||||
.AddElsa()
|
||||
.AddConsoleActivities()
|
||||
.AddWorkflow<CorrelationWorkflow>()
|
||||
.BuildServiceProvider();
|
||||
|
|
|
|||
|
|
@ -6,8 +6,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\activities\Elsa.Activities.Console\Elsa.Activities.Console.csproj" />
|
||||
<ProjectReference Include="..\..\core\Elsa.Core\Elsa.Core.csproj" />
|
||||
<ProjectReference Include="..\..\core\Elsa\Elsa.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue