From b9bde79638a8e615d4ec2cc545c75b2e6219babb Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Fri, 13 Dec 2024 12:09:04 +0100 Subject: [PATCH] Refactor variable handling in storage driver logic Refactored `StorageDriverContext` to include `Variable` and updated its usage across relevant methods to ensure context accuracy. Enhanced `ObjectConverter` to support conditional deserialization of JSON objects. Adjusted `WorkflowInstanceStorageDriver` to utilize improved variable resolution with new conversion options. --- .../Elsa.Expressions/Helpers/ObjectConverter.cs | 6 +++--- .../Contexts/StorageDriverContext.cs | 4 +++- .../Services/VariablePersistenceManager.cs | 6 +++--- .../WorkflowInstanceStorageDriver.cs | 13 +++++++++++-- 4 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/modules/Elsa.Expressions/Helpers/ObjectConverter.cs b/src/modules/Elsa.Expressions/Helpers/ObjectConverter.cs index 33249a919..85238b016 100644 --- a/src/modules/Elsa.Expressions/Helpers/ObjectConverter.cs +++ b/src/modules/Elsa.Expressions/Helpers/ObjectConverter.cs @@ -19,7 +19,7 @@ namespace Elsa.Expressions.Helpers; /// /// Provides options to the conversion method. /// -public record ObjectConverterOptions(JsonSerializerOptions? SerializerOptions = default, IWellKnownTypeRegistry? WellKnownTypeRegistry = default); +public record ObjectConverterOptions(JsonSerializerOptions? SerializerOptions = null, IWellKnownTypeRegistry? WellKnownTypeRegistry = null, bool DeserializeJsonObjectToObject = false); /// /// A helper that attempts many strategies to try and convert the source value into the destination type. @@ -77,7 +77,7 @@ public static class ObjectConverter public static object? ConvertTo(this object? value, Type targetType, ObjectConverterOptions? converterOptions = null) { if (value == null) - return default!; + return null; var sourceType = value.GetType(); @@ -104,7 +104,7 @@ public static class ObjectConverter return underlyingTargetType switch { { } t when t == typeof(string) => jsonNode.ToString(), - { } t when t != typeof(object) => jsonNode.Deserialize(targetType, serializerOptions), + { } t when t != typeof(object) || converterOptions?.DeserializeJsonObjectToObject == true => jsonNode.Deserialize(targetType, serializerOptions), _ => jsonNode }; } diff --git a/src/modules/Elsa.Workflows.Core/Contexts/StorageDriverContext.cs b/src/modules/Elsa.Workflows.Core/Contexts/StorageDriverContext.cs index 77e32360e..49811f5dc 100644 --- a/src/modules/Elsa.Workflows.Core/Contexts/StorageDriverContext.cs +++ b/src/modules/Elsa.Workflows.Core/Contexts/StorageDriverContext.cs @@ -1,6 +1,8 @@ +using Elsa.Workflows.Memory; + namespace Elsa.Workflows; /// /// Provides context for storage drivers. /// -public record StorageDriverContext(IExecutionContext ExecutionContext, CancellationToken CancellationToken); \ No newline at end of file +public record StorageDriverContext(IExecutionContext ExecutionContext, Variable Variable, CancellationToken CancellationToken); \ No newline at end of file diff --git a/src/modules/Elsa.Workflows.Core/Services/VariablePersistenceManager.cs b/src/modules/Elsa.Workflows.Core/Services/VariablePersistenceManager.cs index 663e0057d..3b351eddf 100644 --- a/src/modules/Elsa.Workflows.Core/Services/VariablePersistenceManager.cs +++ b/src/modules/Elsa.Workflows.Core/Services/VariablePersistenceManager.cs @@ -22,7 +22,7 @@ public class VariablePersistenceManager(IStorageDriverManager storageDriverManag foreach (var variable in variables) { context.ExpressionExecutionContext.Memory.Declare(variable); - var storageDriverContext = new StorageDriverContext(context, cancellationToken); + var storageDriverContext = new StorageDriverContext(context, variable, cancellationToken); var register = context.ExpressionExecutionContext.Memory; var block = EnsureBlock(register, variable); var metadata = (VariableBlockMetadata)block.Metadata!; @@ -65,7 +65,6 @@ public class VariablePersistenceManager(IStorageDriverManager storageDriverManag foreach (var context in contexts) { var variables = GetLocalVariables(context).ToList(); - var storageDriverContext = new StorageDriverContext(context, cancellationToken); foreach (var variable in variables) { @@ -78,6 +77,7 @@ public class VariablePersistenceManager(IStorageDriverManager storageDriverManag var id = GetStateId(variable); var value = block.Value; + var storageDriverContext = new StorageDriverContext(context, variable, cancellationToken); if (value == null) await driver.DeleteAsync(id, storageDriverContext); @@ -93,7 +93,6 @@ public class VariablePersistenceManager(IStorageDriverManager storageDriverManag var register = context.ExpressionExecutionContext.Memory; var variableList = GetLocalVariables(context).ToList(); var cancellationToken = context.CancellationToken; - var storageDriverContext = new StorageDriverContext(context, cancellationToken); foreach (var variable in variableList) { @@ -107,6 +106,7 @@ public class VariablePersistenceManager(IStorageDriverManager storageDriverManag continue; var id = GetStateId(variable); + var storageDriverContext = new StorageDriverContext(context, variable, cancellationToken); await driver.DeleteAsync(id, storageDriverContext); register.Blocks.Remove(variable.Id); } diff --git a/src/modules/Elsa.Workflows.Core/VariableStorageDrivers/WorkflowInstanceStorageDriver.cs b/src/modules/Elsa.Workflows.Core/VariableStorageDrivers/WorkflowInstanceStorageDriver.cs index c85ee32f9..cf942dcce 100644 --- a/src/modules/Elsa.Workflows.Core/VariableStorageDrivers/WorkflowInstanceStorageDriver.cs +++ b/src/modules/Elsa.Workflows.Core/VariableStorageDrivers/WorkflowInstanceStorageDriver.cs @@ -1,6 +1,7 @@ using System.ComponentModel.DataAnnotations; using System.Text.Json; using System.Text.Json.Nodes; +using Elsa.Expressions.Helpers; using Elsa.Extensions; using JetBrains.Annotations; @@ -11,7 +12,7 @@ namespace Elsa.Workflows; /// [Display(Name = "Workflow Instance")] [UsedImplicitly] -public class WorkflowInstanceStorageDriver : IStorageDriver +public class WorkflowInstanceStorageDriver(IPayloadSerializer payloadSerializer) : IStorageDriver { /// /// The key used to store the variables in the workflow state. @@ -39,7 +40,15 @@ public class WorkflowInstanceStorageDriver : IStorageDriver { var dictionary = GetVariablesDictionary(context); var node = dictionary.GetValueOrDefault(id); - return new(node); + var variable = context.Variable; + var variableType = variable.GetVariableType(); + var options = new ObjectConverterOptions + { + DeserializeJsonObjectToObject = true, + SerializerOptions = payloadSerializer.GetOptions() + }; + var parsedValue = node.ConvertTo(variableType, options); + return new (parsedValue); } ///