Skip to content

Commit e557ec3

Browse files
authored
If step (danielgerlag#34)
* if step * Sequence step * skip step * when step * outcome switch * tests
1 parent 47d14b1 commit e557ec3

File tree

78 files changed

+2011
-120
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

78 files changed

+2011
-120
lines changed

WorkflowCore.sln

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WorkflowCore.Sample09", "sr
7878
EndProject
7979
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WorkflowCore.Sample10", "src\samples\WorkflowCore.Sample10\WorkflowCore.Sample10.csproj", "{5E792455-4C4C-460F-849E-50A5DCED454D}"
8080
EndProject
81+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WorkflowCore.Sample11", "src\samples\WorkflowCore.Sample11\WorkflowCore.Sample11.csproj", "{58D0480F-D05D-4348-86D9-B0A7255700E6}"
82+
EndProject
83+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WorkflowCore.Sample12", "src\samples\WorkflowCore.Sample12\WorkflowCore.Sample12.csproj", "{BB776411-D279-419F-8697-5C6F52BCD5CD}"
84+
EndProject
85+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WorkflowCore.Tests.Sqlite", "test\WorkflowCore.Tests.Sqlite\WorkflowCore.Tests.Sqlite.csproj", "{F9F8F9CD-01D9-468B-856D-6A87F0762A01}"
86+
EndProject
8187
Global
8288
GlobalSection(SolutionConfigurationPlatforms) = preSolution
8389
Debug|Any CPU = Debug|Any CPU
@@ -204,6 +210,18 @@ Global
204210
{5E792455-4C4C-460F-849E-50A5DCED454D}.Debug|Any CPU.Build.0 = Debug|Any CPU
205211
{5E792455-4C4C-460F-849E-50A5DCED454D}.Release|Any CPU.ActiveCfg = Release|Any CPU
206212
{5E792455-4C4C-460F-849E-50A5DCED454D}.Release|Any CPU.Build.0 = Release|Any CPU
213+
{58D0480F-D05D-4348-86D9-B0A7255700E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
214+
{58D0480F-D05D-4348-86D9-B0A7255700E6}.Debug|Any CPU.Build.0 = Debug|Any CPU
215+
{58D0480F-D05D-4348-86D9-B0A7255700E6}.Release|Any CPU.ActiveCfg = Release|Any CPU
216+
{58D0480F-D05D-4348-86D9-B0A7255700E6}.Release|Any CPU.Build.0 = Release|Any CPU
217+
{BB776411-D279-419F-8697-5C6F52BCD5CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
218+
{BB776411-D279-419F-8697-5C6F52BCD5CD}.Debug|Any CPU.Build.0 = Debug|Any CPU
219+
{BB776411-D279-419F-8697-5C6F52BCD5CD}.Release|Any CPU.ActiveCfg = Release|Any CPU
220+
{BB776411-D279-419F-8697-5C6F52BCD5CD}.Release|Any CPU.Build.0 = Release|Any CPU
221+
{F9F8F9CD-01D9-468B-856D-6A87F0762A01}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
222+
{F9F8F9CD-01D9-468B-856D-6A87F0762A01}.Debug|Any CPU.Build.0 = Debug|Any CPU
223+
{F9F8F9CD-01D9-468B-856D-6A87F0762A01}.Release|Any CPU.ActiveCfg = Release|Any CPU
224+
{F9F8F9CD-01D9-468B-856D-6A87F0762A01}.Release|Any CPU.Build.0 = Release|Any CPU
207225
EndGlobalSection
208226
GlobalSection(SolutionProperties) = preSolution
209227
HideSolutionNode = FALSE
@@ -242,5 +260,8 @@ Global
242260
{FBF8D151-A3BF-4EB3-8F80-D71618696362} = {6803696C-B19A-4B27-9193-082A02B6F205}
243261
{50E1AFAC-0B58-43A8-8F03-3A63AAC681FA} = {5080DB09-CBE8-4C45-9957-C3BB7651755E}
244262
{5E792455-4C4C-460F-849E-50A5DCED454D} = {5080DB09-CBE8-4C45-9957-C3BB7651755E}
263+
{58D0480F-D05D-4348-86D9-B0A7255700E6} = {5080DB09-CBE8-4C45-9957-C3BB7651755E}
264+
{BB776411-D279-419F-8697-5C6F52BCD5CD} = {5080DB09-CBE8-4C45-9957-C3BB7651755E}
265+
{F9F8F9CD-01D9-468B-856D-6A87F0762A01} = {E6CEAD8D-F565-471E-A0DC-676F54EAEDEB}
245266
EndGlobalSection
246267
EndGlobal
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
5+
namespace WorkflowCore.Interface
6+
{
7+
public interface IContainerStepBuilder<TData, TStepBody, TReturnStep>
8+
where TStepBody : IStepBody
9+
where TReturnStep : IStepBody
10+
{
11+
IStepBuilder<TData, TReturnStep> Do(Action<IWorkflowBuilder<TData>> builder);
12+
}
13+
}

src/WorkflowCore/Interface/IParentStepBuilder.cs

Lines changed: 0 additions & 12 deletions
This file was deleted.

src/WorkflowCore/Interface/IStepBuilder.cs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Linq.Expressions;
44
using WorkflowCore.Interface;
55
using WorkflowCore.Models;
6+
using WorkflowCore.Primitives;
67

78
namespace WorkflowCore.Interface
89
{
@@ -49,6 +50,7 @@ public interface IStepBuilder<TData, TStepBody>
4950
/// </summary>
5051
/// <param name="outcomeValue"></param>
5152
/// <returns></returns>
53+
[Obsolete]
5254
IStepOutcomeBuilder<TData> When(object outcomeValue, string label = null);
5355

5456
/// <summary>
@@ -87,8 +89,17 @@ public interface IStepBuilder<TData, TStepBody>
8789
/// <returns></returns>
8890
IStepBuilder<TData, TStepBody> EndWorkflow();
8991

90-
IParentStepBuilder<TData, Foreach> ForEach(Expression<Func<TData, IEnumerable>> collection);
92+
IContainerStepBuilder<TData, Foreach, Foreach> ForEach(Expression<Func<TData, IEnumerable>> collection);
9193

92-
IParentStepBuilder<TData, While> While(Expression<Func<TData, bool>> condition);
94+
IContainerStepBuilder<TData, While, While> While(Expression<Func<TData, bool>> condition);
95+
96+
IContainerStepBuilder<TData, If, If> If(Expression<Func<TData, bool>> condition);
97+
98+
/// <summary>
99+
/// Configure an outcome for this step, then wire it to a sequence
100+
/// </summary>
101+
/// <param name="outcomeValue"></param>
102+
/// <returns></returns>
103+
IContainerStepBuilder<TData, When, OutcomeSwitch> When(Expression<Func<TData, object>> outcomeValue, string label = null);
93104
}
94105
}

src/WorkflowCore/Interface/IStepOutcomeBuilder.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using WorkflowCore.Interface;
33
using WorkflowCore.Models;
4+
using WorkflowCore.Primitives;
45

56
namespace WorkflowCore.Interface
67
{

src/WorkflowCore/Interface/IWorkflowBuilder.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.Generic;
33
using WorkflowCore.Interface;
44
using WorkflowCore.Models;
5+
using WorkflowCore.Primitives;
56

67
namespace WorkflowCore.Interface
78
{

src/WorkflowCore/Models/ExecutionPointer.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,5 +41,6 @@ public class ExecutionPointer
4141

4242
public string PredecessorId { get; set; }
4343

44+
public object Outcome { get; set; }
4445
}
4546
}
Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,31 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Linq;
4+
using System.Linq.Expressions;
45
using System.Threading.Tasks;
56
using WorkflowCore.Interface;
67

78
namespace WorkflowCore.Models
89
{
910
public class StepOutcome
1011
{
11-
public object Value { get; set; }
12+
private Expression<Func<object, object>> _value;
13+
14+
public Expression<Func<object, object>> Value
15+
{
16+
set { _value = value; }
17+
}
1218

1319
public int NextStep { get; set; }
1420

1521
public string Label { get; set; }
22+
23+
public object GetValue(object data)
24+
{
25+
if (_value == null)
26+
return null;
27+
28+
return _value.Compile().Invoke(data);
29+
}
1630
}
1731
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
using System;
2+
using System.Linq;
3+
using System.Collections;
4+
using System.Collections.Generic;
5+
using System.Linq.Expressions;
6+
using System.Text;
7+
using WorkflowCore.Interface;
8+
using WorkflowCore.Models;
9+
10+
namespace WorkflowCore.Primitives
11+
{
12+
public abstract class ContainerStepBody : StepBody
13+
{
14+
protected bool IsBranchComplete(IEnumerable<ExecutionPointer> pointers, string rootId)
15+
{
16+
//TODO: move to own class
17+
var root = pointers.First(x => x.Id == rootId);
18+
19+
if (root.EndTime == null)
20+
return false;
21+
22+
var list = pointers.Where(x => x.PredecessorId == rootId).ToList();
23+
24+
bool result = true;
25+
26+
foreach (var item in list)
27+
result = result && IsBranchComplete(pointers, item.Id);
28+
29+
return result;
30+
}
31+
}
32+
}

src/WorkflowCore/Models/ControlStructures/EndStep.cs renamed to src/WorkflowCore/Primitives/EndStep.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
using System.Collections.Generic;
33
using System.Text;
44
using WorkflowCore.Interface;
5+
using WorkflowCore.Models;
56

6-
namespace WorkflowCore.Models
7+
namespace WorkflowCore.Primitives
78
{
89
public class EndStep : WorkflowStep
910
{

src/WorkflowCore/Models/ControlStructures/Foreach.cs renamed to src/WorkflowCore/Primitives/Foreach.cs

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@
55
using System.Linq.Expressions;
66
using System.Text;
77
using WorkflowCore.Interface;
8+
using WorkflowCore.Models;
89

9-
namespace WorkflowCore.Models
10+
namespace WorkflowCore.Primitives
1011
{
11-
public class Foreach : StepBody
12+
public class Foreach : ContainerStepBody
1213
{
1314
public IEnumerable Collection { get; set; }
1415

@@ -34,24 +35,6 @@ public override ExecutionResult Run(IStepExecutionContext context)
3435
}
3536

3637
return ExecutionResult.Persist(context.PersistenceData);
37-
}
38-
39-
private bool IsBranchComplete(IEnumerable<ExecutionPointer> pointers, string rootId)
40-
{
41-
var root = pointers.First(x => x.Id == rootId);
42-
43-
if (root.EndTime == null)
44-
return false;
45-
46-
var list = pointers.Where(x => x.PredecessorId == rootId).ToList();
47-
48-
bool result = true;
49-
50-
foreach (var item in list)
51-
result = result && IsBranchComplete(pointers, item.Id);
52-
53-
return result;
54-
}
55-
38+
}
5639
}
5740
}

src/WorkflowCore/Primitives/If.cs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
using System;
2+
using System.Linq;
3+
using System.Collections;
4+
using System.Collections.Generic;
5+
using System.Linq.Expressions;
6+
using System.Text;
7+
using WorkflowCore.Interface;
8+
using WorkflowCore.Models;
9+
10+
namespace WorkflowCore.Primitives
11+
{
12+
public class If : ContainerStepBody
13+
{
14+
public bool ConditionResult { get; set; }
15+
16+
public override ExecutionResult Run(IStepExecutionContext context)
17+
{
18+
if (context.PersistenceData == null)
19+
{
20+
if (ConditionResult)
21+
return ExecutionResult.Branch(new List<object>() { null }, new ControlPersistenceData() { ChildrenActive = true });
22+
else
23+
return ExecutionResult.Next();
24+
}
25+
26+
if ((context.PersistenceData is ControlPersistenceData) && ((context.PersistenceData as ControlPersistenceData).ChildrenActive))
27+
{
28+
bool complete = true;
29+
foreach (var childId in context.ExecutionPointer.Children)
30+
complete = complete && IsBranchComplete(context.Workflow.ExecutionPointers, childId);
31+
32+
if (complete)
33+
return ExecutionResult.Next();
34+
else
35+
return ExecutionResult.Persist(context.PersistenceData);
36+
}
37+
38+
throw new Exception("Corrupt persistence data");
39+
}
40+
}
41+
}

src/WorkflowCore/Models/InlineStepBody.cs renamed to src/WorkflowCore/Primitives/InlineStepBody.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44
using System.Linq.Expressions;
55
using System.Threading.Tasks;
66
using WorkflowCore.Interface;
7+
using WorkflowCore.Models;
78

8-
namespace WorkflowCore.Models
9+
namespace WorkflowCore.Primitives
910
{
1011
public class InlineStepBody : StepBody
1112
{
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
using System;
2+
using System.Linq;
3+
using System.Collections;
4+
using System.Collections.Generic;
5+
using System.Linq.Expressions;
6+
using System.Text;
7+
using WorkflowCore.Interface;
8+
using WorkflowCore.Models;
9+
10+
namespace WorkflowCore.Primitives
11+
{
12+
public class OutcomeSwitch : ContainerStepBody
13+
{
14+
public override ExecutionResult Run(IStepExecutionContext context)
15+
{
16+
if (context.PersistenceData == null)
17+
{
18+
var result = ExecutionResult.Branch(new List<object>() { null }, new ControlPersistenceData() { ChildrenActive = true });
19+
result.OutcomeValue = GetPreviousOutcome(context);
20+
return result;
21+
}
22+
23+
if ((context.PersistenceData is ControlPersistenceData) && ((context.PersistenceData as ControlPersistenceData).ChildrenActive))
24+
{
25+
bool complete = true;
26+
foreach (var childId in context.ExecutionPointer.Children)
27+
complete = complete && IsBranchComplete(context.Workflow.ExecutionPointers, childId);
28+
29+
if (complete)
30+
return ExecutionResult.Next();
31+
else
32+
{
33+
var result = ExecutionResult.Persist(context.PersistenceData);
34+
result.OutcomeValue = GetPreviousOutcome(context);
35+
return result;
36+
}
37+
}
38+
39+
throw new Exception("Corrupt persistence data");
40+
}
41+
42+
private object GetPreviousOutcome(IStepExecutionContext context)
43+
{
44+
var prevPointer = context.Workflow.ExecutionPointers.First(x => x.Id == context.ExecutionPointer.PredecessorId);
45+
return prevPointer.Outcome;
46+
}
47+
48+
}
49+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
using System;
2+
using System.Linq;
3+
using System.Collections;
4+
using System.Collections.Generic;
5+
using System.Linq.Expressions;
6+
using System.Text;
7+
using WorkflowCore.Interface;
8+
using WorkflowCore.Models;
9+
10+
namespace WorkflowCore.Primitives
11+
{
12+
public class Sequence : ContainerStepBody
13+
{
14+
public override ExecutionResult Run(IStepExecutionContext context)
15+
{
16+
if (context.PersistenceData == null)
17+
return ExecutionResult.Branch(new List<object>() { null }, new ControlPersistenceData() { ChildrenActive = true });
18+
19+
if ((context.PersistenceData is ControlPersistenceData) && ((context.PersistenceData as ControlPersistenceData).ChildrenActive))
20+
{
21+
bool complete = true;
22+
foreach (var childId in context.ExecutionPointer.Children)
23+
complete = complete && IsBranchComplete(context.Workflow.ExecutionPointers, childId);
24+
25+
if (complete)
26+
return ExecutionResult.Next();
27+
else
28+
return ExecutionResult.Persist(context.PersistenceData);
29+
}
30+
31+
throw new Exception("Corrupt persistence data");
32+
}
33+
}
34+
}

src/WorkflowCore/Models/SubWorkflowStepBody.cs renamed to src/WorkflowCore/Primitives/SubWorkflowStepBody.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
using System.Collections.Generic;
33
using System.Text;
44
using WorkflowCore.Interface;
5+
using WorkflowCore.Models;
56

6-
namespace WorkflowCore.Models
7+
namespace WorkflowCore.Primitives
78
{
89
public class SubWorkflowStepBody : StepBody
910
{

0 commit comments

Comments
 (0)