diff --git a/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Implementations/Transformer.cs b/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Implementations/Transformer.cs deleted file mode 100644 index 6b6fa4103..000000000 --- a/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Implementations/Transformer.cs +++ /dev/null @@ -1,95 +0,0 @@ -using Elsa.Workflows.Core.Activities.Flowchart.Extensions; -using Elsa.Workflows.Core.Activities.Flowchart.Models; -using Elsa.Workflows.Core.Activities.Flowchart.Services; -using Elsa.Workflows.Core.Services; - -namespace Elsa.Workflows.Core.Activities.Flowchart.Implementations; - -using Flowchart = Activities.Flowchart; - -public class Transformer : ITransformer -{ - private readonly IActivityNodeDescriber _activityNodeDescriber; - private readonly IIdentityGenerator _identityGenerator; - - public Transformer(IActivityNodeDescriber activityNodeDescriber, IIdentityGenerator identityGenerator) - { - _activityNodeDescriber = activityNodeDescriber; - _identityGenerator = identityGenerator; - } - - public void Transpose(Flowchart flowchart) - { - var start = flowchart.Start; - - if (start == null) - return; - - var activities = flowchart.Activities; - var activityTypes = activities.Select(x => x.GetType()).Distinct().ToList(); - var activityDescriptors = activityTypes.Select(_activityNodeDescriber.DescribeActivity).ToDictionary(x => x.ActivityRuntimeType); - - TransposeInternal(flowchart, activityDescriptors); - } - - private void TransposeInternal(Flowchart flowchart, IDictionary descriptors) - { - var connections = flowchart.Connections.ToList(); - - foreach (var connection in connections) - { - var portName = connection.SourcePort; - - // If the connection has no source port name, it cannot be mapped to an outbound port property on an activity. - if (portName == null) - continue; - - var source = connection.Source; - var sourceType = source.GetType(); - var sourceDescriptor = descriptors[sourceType]; - var sourcePort = sourceDescriptor.OutPorts.FirstOrDefault(x => x.Name == portName); - - // If the connection source port does not match any outbound port properties on the source activity, the target cannot be transposed onto it. - if (sourcePort == null) - continue; - - var target = connection.Target; - var descendantConnections = connections.Descendants(target).ToList(); - - // Remove all descendant connections and activities from the current flowchart level. - // They are either no longer necessary because they are transposed, or they will be added to a child flowchart. - flowchart.Connections.Remove(connection); - flowchart.Activities.Remove(target); - - if (!descendantConnections.Any()) - { - // There were no descendant connections, which means we can transpose the current target as-is. - source.SetPropertyValue(portName, target); - } - else - { - // There was at least one descendant, which means we need to capture them into a child flow. - // TODO: Add logic to try and determine if we can add a sequence instead. - var activities = descendantConnections.Select(x => x.Source).Concat(descendantConnections.Select(x => x.Target)).ToHashSet(); - - var subFlow = new Flowchart - { - Id = _identityGenerator.GenerateId(), - Activities = activities, - Connections = descendantConnections, - Start = target - }; - - // Remove transported connections and activities from the current flowchart. - flowchart.Connections = flowchart.Connections.Except(descendantConnections).ToList(); - flowchart.Activities = flowchart.Activities.Except(activities).ToHashSet(); - - // Transpose the child flow into the current source. - source.SetPropertyValue(portName, subFlow); - - // Recurse into the subflow. - TransposeInternal(subFlow, descriptors); - } - } - } -} \ No newline at end of file diff --git a/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Serialization/FlowchartJsonConverter.cs b/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Serialization/FlowchartJsonConverter.cs index 5896033e7..6ff64d498 100644 --- a/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Serialization/FlowchartJsonConverter.cs +++ b/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Serialization/FlowchartJsonConverter.cs @@ -11,13 +11,6 @@ public class FlowchartJsonConverter : JsonConverter private const string AllActivitiesKey = "AllActivities"; private const string AllConnectionsKey = "AllConnections"; - private readonly ITransformer _transformer; - - public FlowchartJsonConverter(ITransformer transformer) - { - _transformer = transformer; - } - public override Activities.Flowchart Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (!JsonDocument.TryParseValue(ref reader, out var doc)) @@ -50,8 +43,6 @@ public class FlowchartJsonConverter : JsonConverter [AllConnectionsKey] = connections.ToList() } }; - - _transformer.Transpose(flowChart); return flowChart; } diff --git a/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Services/ITransformer.cs b/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Services/ITransformer.cs deleted file mode 100644 index 07158f297..000000000 --- a/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Services/ITransformer.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Elsa.Workflows.Core.Activities.Flowchart.Services; -using Flowchart = Activities.Flowchart; - -/// -/// Transforms the specified into a sequential structure by transposing connected activities into outbound activity properties of the source activity. -/// -public interface ITransformer -{ - void Transpose(Flowchart flowchart); -} \ No newline at end of file diff --git a/src/modules/Elsa.Workflows.Core/Features/FlowchartFeature.cs b/src/modules/Elsa.Workflows.Core/Features/FlowchartFeature.cs index afa265c9c..2b3dd9340 100644 --- a/src/modules/Elsa.Workflows.Core/Features/FlowchartFeature.cs +++ b/src/modules/Elsa.Workflows.Core/Features/FlowchartFeature.cs @@ -17,10 +17,6 @@ public class FlowchartFeature : FeatureBase public override void Apply() { Services - //.AddSingleton() - //.AddSingleton() - //.AddSingleton() - .AddSingleton() .AddSingleton() .AddSingleton() ; diff --git a/test/Elsa.IntegrationTests/Activities/Flowchart/Services/TransformerTests.cs b/test/Elsa.IntegrationTests/Activities/Flowchart/Services/TransformerTests.cs deleted file mode 100644 index df0e6d239..000000000 --- a/test/Elsa.IntegrationTests/Activities/Flowchart/Services/TransformerTests.cs +++ /dev/null @@ -1,73 +0,0 @@ -using System.Linq; -using System.Threading.Tasks; -using Elsa.Testing.Shared; -using Elsa.Workflows.Core.Activities.Flowchart.Services; -using Elsa.Workflows.Core.Services; -using Microsoft.Extensions.DependencyInjection; -using Xunit; -using Xunit.Abstractions; - -namespace Elsa.IntegrationTests.Activities.Flowchart.Services; - -using Flowchart = Workflows.Core.Activities.Flowchart.Activities.Flowchart; - -public class TransformerTests -{ - private readonly ITransformer _transformer; - private readonly CapturingTextWriter _capturingTextWriter = new(); - private readonly IWorkflowRunner _workflowRunner; - private readonly IWorkflowDefinitionBuilderFactory _workflowBuilderFactory; - - public TransformerTests(ITestOutputHelper testOutputHelper) - { - var services = new TestApplicationBuilder(testOutputHelper).WithCapturingTextWriter(_capturingTextWriter).Build(); - _transformer = services.GetRequiredService(); - _workflowBuilderFactory = services.GetRequiredService(); - _workflowRunner = services.GetRequiredService(); - } - - [Fact(DisplayName = "Transforming a flowchart correctly transposes connected nodes")] - public async Task Test1() - { - var languages = new[] { "C#", "Rust", "Go" }; - var builder = _workflowBuilderFactory.CreateBuilder(); - var workflow = await builder.BuildWorkflowAsync(new Workflow1(languages)); - var flowchart = (Flowchart)workflow.Root; - _transformer.Transpose(flowchart); - await _workflowRunner.RunAsync(workflow); - var lines = _capturingTextWriter.Lines.ToList(); - var expectedLines = new[] { "Start!", "Current Item", "C#", "Current Item", "Rust", "Current Item", "Go", "Done!" }; - - Assert.Equal(expectedLines, lines); - } - - [Fact(DisplayName = "Transforming a flowchart correctly transposes connected nodes")] - public async Task Test2() - { - var languages = new[] { "C#", "Rust", "Go" }; - var builder = _workflowBuilderFactory.CreateBuilder(); - var workflow = await builder.BuildWorkflowAsync(new Workflow2(languages)); - var flowchart = (Flowchart)workflow.Root; - _transformer.Transpose(flowchart); - await _workflowRunner.RunAsync(workflow); - var lines = _capturingTextWriter.Lines.ToList(); - var expectedLines = new[] { "Start!", "C#", "Rust", "Go", "Done!" }; - - Assert.Equal(expectedLines, lines); - } - - [Fact(DisplayName = "Transforming a flowchart correctly transposes connected nodes")] - public async Task Test3() - { - var languages = new[] { "C#", "Rust", "Go" }; - var builder = _workflowBuilderFactory.CreateBuilder(); - var workflow = await builder.BuildWorkflowAsync(new Workflow3(languages)); - var flowchart = (Flowchart)workflow.Root; - _transformer.Transpose(flowchart); - await _workflowRunner.RunAsync(workflow); - var lines = _capturingTextWriter.Lines.ToList(); - var expectedLines = new[] { "Start!", "C#", "Rust", "Go", "Done!" }; - - Assert.Equal(expectedLines, lines); - } -} \ No newline at end of file