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.
This commit is contained in:
Sipke Schoorstra 2024-12-13 12:09:04 +01:00
parent cc75bb65ea
commit b9bde79638
4 changed files with 20 additions and 9 deletions

View file

@ -19,7 +19,7 @@ namespace Elsa.Expressions.Helpers;
/// <summary>
/// Provides options to the conversion method.
/// </summary>
public record ObjectConverterOptions(JsonSerializerOptions? SerializerOptions = default, IWellKnownTypeRegistry? WellKnownTypeRegistry = default);
public record ObjectConverterOptions(JsonSerializerOptions? SerializerOptions = null, IWellKnownTypeRegistry? WellKnownTypeRegistry = null, bool DeserializeJsonObjectToObject = false);
/// <summary>
/// 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
};
}

View file

@ -1,6 +1,8 @@
using Elsa.Workflows.Memory;
namespace Elsa.Workflows;
/// <summary>
/// Provides context for storage drivers.
/// </summary>
public record StorageDriverContext(IExecutionContext ExecutionContext, CancellationToken CancellationToken);
public record StorageDriverContext(IExecutionContext ExecutionContext, Variable Variable, CancellationToken CancellationToken);

View file

@ -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);
}

View file

@ -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;
/// </summary>
[Display(Name = "Workflow Instance")]
[UsedImplicitly]
public class WorkflowInstanceStorageDriver : IStorageDriver
public class WorkflowInstanceStorageDriver(IPayloadSerializer payloadSerializer) : IStorageDriver
{
/// <summary>
/// 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);
}
/// <inheritdoc />