diff --git a/ActionFlow.Tests/ActionFlow.Tests.csproj b/ActionFlow.Tests/ActionFlow.Tests.csproj
index aaf7cd2..b193972 100644
--- a/ActionFlow.Tests/ActionFlow.Tests.csproj
+++ b/ActionFlow.Tests/ActionFlow.Tests.csproj
@@ -10,6 +10,7 @@
+
@@ -24,4 +25,10 @@
+
+
+ Always
+
+
+
diff --git a/ActionFlow.Tests/Extensions/ServiceCollectionExtensionsTests.cs b/ActionFlow.Tests/Extensions/ServiceCollectionExtensionsTests.cs
index 5538f9d..604dff3 100644
--- a/ActionFlow.Tests/Extensions/ServiceCollectionExtensionsTests.cs
+++ b/ActionFlow.Tests/Extensions/ServiceCollectionExtensionsTests.cs
@@ -23,10 +23,10 @@ public void When_using_action_flow_engine_it_should_register_all_required_servic
//Assert
Assert.IsNotNull(provider.GetRequiredService());
- Assert.IsNotNull(provider.GetRequiredService());
Assert.IsNotNull(provider.GetRequiredService());
Assert.IsNotNull(provider.GetRequiredService());
Assert.IsNotNull(provider.GetRequiredService());
+ Assert.IsNotNull(provider.GetRequiredService());
Assert.IsNotNull(provider.GetRequiredService>());
var stepActionFactory = provider.GetRequiredService();
diff --git a/ActionFlow.Tests/Providers/WorkflowProviderBuiltinExtensionsTests.cs b/ActionFlow.Tests/Providers/WorkflowProviderBuiltinExtensionsTests.cs
new file mode 100644
index 0000000..0ac97d3
--- /dev/null
+++ b/ActionFlow.Tests/Providers/WorkflowProviderBuiltinExtensionsTests.cs
@@ -0,0 +1,72 @@
+using ActionFlow.Domain.Engine;
+using ActionFlow.Engine.Providers;
+using ActionFlow.Engine.Providers.Extensions;
+using FluentAssertions;
+using Microsoft.Extensions.DependencyInjection;
+using System.Text.Json;
+
+namespace ActionFlow.Tests.Providers;
+
+[TestClass]
+public class WorkflowProviderBuiltinExtensionsTests
+{
+ [TestMethod]
+ public void When_using_from_json_it_should_add_workflow()
+ {
+ //Arrange
+ var workflows = new List
+ {
+ new("Test",
+ [
+ new("initialize", "Variable", new Dictionary
+ {
+ { "age", "1" },
+ { "canWalk", "true" },
+ }),
+ new("test variable value", "Variable", [], "age == 1 && canWalk == true")
+ ])
+ };
+
+ var workflowJson = JsonSerializer.SerializeToNode(workflows);
+ var services = new ServiceCollection();
+ services.AddJsonWorkflowProvider(workflowJson!.AsArray());
+
+ //Act
+ var provider = services.BuildServiceProvider();
+
+ //Assert
+ var workflowProvider = provider.GetRequiredService();
+ var result = workflowProvider.GetAllWorkflows();
+ result.Should().BeEquivalentTo(workflows);
+ }
+
+ [TestMethod]
+ public void When_using_from_json_file_it_should_add_workflow()
+ {
+ //Arrange
+ var expected = new List
+ {
+ new("Test",
+ [
+ new("initialize", "Variable", new Dictionary
+ {
+ { "age", "1" },
+ { "canWalk", "true" },
+ }),
+ new("test variable value", "Variable", [], "age == 1 && canWalk == true")
+ ])
+ };
+
+ var services = new ServiceCollection();
+ var path = Path.Combine(Environment.CurrentDirectory, @"Providers\workflows.json");
+ services.AddJsonWorkflowProvider(path);
+
+ //Act
+ var provider = services.BuildServiceProvider();
+
+ //Assert
+ var workflowProvider = provider.GetRequiredService();
+ var result = workflowProvider.GetAllWorkflows();
+ result.Should().BeEquivalentTo(expected);
+ }
+}
diff --git a/ActionFlow.Tests/Providers/WorkflowProviderTests.cs b/ActionFlow.Tests/Providers/WorkflowProviderTests.cs
new file mode 100644
index 0000000..d38b811
--- /dev/null
+++ b/ActionFlow.Tests/Providers/WorkflowProviderTests.cs
@@ -0,0 +1,26 @@
+using ActionFlow.Domain.Engine;
+using ActionFlow.Engine.Providers;
+
+namespace ActionFlow.Tests.Providers;
+
+[TestClass]
+public class WorkflowProviderTests
+{
+ [TestMethod]
+ public void When_getting_all_workflows_it_should_return_a_list()
+ {
+ //Arrange
+ var testWorkflows = new List
+ {
+ new("test", [])
+ };
+ var sut = new WorkflowProvider(testWorkflows);
+
+ //Act
+ var result = sut.GetAllWorkflows();
+
+ //Assert
+ Assert.IsInstanceOfType(result, typeof(List));
+ Assert.IsTrue(result.Contains(testWorkflows[0]));
+ }
+}
diff --git a/ActionFlow.Tests/Providers/workflows.json b/ActionFlow.Tests/Providers/workflows.json
new file mode 100644
index 0000000..30994cc
--- /dev/null
+++ b/ActionFlow.Tests/Providers/workflows.json
@@ -0,0 +1,23 @@
+[
+ {
+ "WorkflowName": "Test",
+ "Steps": [
+ {
+ "Name": "initialize",
+ "ActionType": "Variable",
+ "ConditionExpression": null,
+ "Properties": {
+ "age": "1",
+ "canWalk": "true"
+ }
+ },
+ {
+ "Name": "test variable value",
+ "ActionType": "Variable",
+ "ConditionExpression": "age == 1 \u0026\u0026 canWalk == true",
+ "Properties": {}
+ }
+ ],
+ "OutputParameters": null
+ }
+]
\ No newline at end of file
diff --git a/ActionFlow/Domain/Engine/Step.cs b/ActionFlow/Domain/Engine/Step.cs
index 5a80826..047e747 100644
--- a/ActionFlow/Domain/Engine/Step.cs
+++ b/ActionFlow/Domain/Engine/Step.cs
@@ -1,18 +1,19 @@
namespace ActionFlow.Domain.Engine
{
- public class Step
- {
- public Step(string name, string actionType, Dictionary? properties = null, string? conditionExpression = null)
- {
- Name = name;
- ActionType = actionType;
- Properties = properties ?? [];
- ConditionExpression = conditionExpression;
- }
+ public class Step
+ {
+ public Step(string name, string actionType, Dictionary? properties = null, string? conditionExpression = null)
+ {
+ Name = name;
+ ActionType = actionType;
+ Properties = properties ?? [];
+ ConditionExpression = conditionExpression;
+ }
- public string Name { get; }
- public string ActionType { get; }
- public string? ConditionExpression { get; }
- public Dictionary? Properties { get; }
- }
+ public string Name { get; }
+ public string ActionType { get; }
+ public string? ConditionExpression { get; }
+
+ public Dictionary? Properties { get; }
+ }
}
diff --git a/ActionFlow/Engine/Providers/Extensions/WorkflowProviderBuiltinExtensions.cs b/ActionFlow/Engine/Providers/Extensions/WorkflowProviderBuiltinExtensions.cs
index 2086481..22f9dc2 100644
--- a/ActionFlow/Engine/Providers/Extensions/WorkflowProviderBuiltinExtensions.cs
+++ b/ActionFlow/Engine/Providers/Extensions/WorkflowProviderBuiltinExtensions.cs
@@ -1,28 +1,59 @@
using ActionFlow.Domain.Engine;
+using Microsoft.Extensions.DependencyInjection;
using System.Text.Json;
using System.Text.Json.Nodes;
+using System.Text.Json.Serialization;
namespace ActionFlow.Engine.Providers.Extensions;
public static class WorkflowProviderBuiltinExtensions
{
- public static void UseFromJson(this IWorkflowProvider workflowProvider, JsonArray workflowsJson)
+ public static void AddJsonWorkflowProvider(this IServiceCollection services, string jsonPath)
{
- var workflows = workflowsJson.Deserialize();
+ var jsonString = File.ReadAllText(jsonPath);
+ var workflowsJson = JsonArray.Parse(jsonString)?.AsArray();
+
+ services.AddJsonWorkflowProvider(workflowsJson!);
+ }
+
+ public static void AddJsonWorkflowProvider(this IServiceCollection services, JsonArray workflowsJson)
+ {
+ var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
+ options.Converters.Add(new ObjectToStringConverter());
+
+ var workflows = workflowsJson.Deserialize>(options);
if (workflows != null)
{
- foreach (var workflow in workflows)
+ services.AddScoped(x =>
{
- workflowProvider.AddWorkflow(workflow);
- }
+ return new WorkflowProvider([.. workflows]);
+ });
}
}
- public static void UseFromJson(this IWorkflowProvider workflowProvider, string jsonPath)
+ public class ObjectToStringConverter : JsonConverter