< Summary

Information
Class: Elsa.Workflows.WorkflowInstanceStorageDriver
Assembly: Elsa.Workflows.Core
File(s): /home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Workflows.Core/VariableStorageDrivers/WorkflowInstanceStorageDriver.cs
Line coverage
96%
Covered lines: 48
Uncovered lines: 2
Coverable lines: 50
Total lines: 106
Line coverage: 96%
Branch coverage
72%
Covered branches: 13
Total branches: 18
Branch coverage: 72.2%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
get_Priority()100%210%
get_Tags()100%210%
WriteAsync(...)50%44100%
ReadAsync(...)87.5%88100%
DeleteAsync(...)100%11100%
GetSerializerOptions()100%11100%
GetSerializationType(...)66.66%66100%
GetVariablesDictionary(...)100%11100%
SetVariablesDictionary(...)100%11100%
UpdateVariablesDictionary(...)100%11100%

File(s)

/home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Workflows.Core/VariableStorageDrivers/WorkflowInstanceStorageDriver.cs

#LineLine coverage
 1using System.ComponentModel.DataAnnotations;
 2using System.Text.Json;
 3using System.Text.Json.Nodes;
 4using Elsa.Expressions.Helpers;
 5using Elsa.Extensions;
 6using JetBrains.Annotations;
 7using Microsoft.Extensions.Logging;
 8
 9namespace Elsa.Workflows;
 10
 11/// <summary>
 12/// A storage driver that stores objects in the workflow state itself.
 13/// </summary>
 14[Display(Name = "Workflow Instance")]
 15[UsedImplicitly]
 50716public class WorkflowInstanceStorageDriver(IPayloadSerializer payloadSerializer, ILogger<WorkflowInstanceStorageDriver> 
 17{
 18    /// <summary>
 19    /// The key used to store the variables in the workflow state.
 20    /// </summary>
 21    public const string VariablesDictionaryStateKey = "Variables";
 22
 23    /// <inheritdoc />
 024    public double Priority => 5;
 25    /// <inheritdoc />
 026    public IEnumerable<string> Tags => [];
 27
 28    /// <inheritdoc />
 29    public ValueTask WriteAsync(string id, object value, StorageDriverContext context)
 30    {
 20131        UpdateVariablesDictionary(context, dictionary =>
 20132        {
 20133            try
 20134            {
 20135                var node = JsonSerializer.SerializeToNode(value, GetSerializationType(value, context), GetSerializerOpti
 19936                dictionary[id] = node!;
 19937            }
 238            catch (Exception ex) when (ex is JsonException or NotSupportedException or ObjectDisposedException)
 20139            {
 240                logger.LogWarning(ex, "Failed to serialize variable '{VariableId}' of type '{VariableType}' for workflow
 241                    id, value?.GetType().FullName ?? "null");
 242            }
 40243        });
 20144        return ValueTask.CompletedTask;
 45    }
 46
 47    /// <inheritdoc />
 48    public ValueTask<object?> ReadAsync(string id, StorageDriverContext context)
 49    {
 2650        var dictionary = GetVariablesDictionary(context);
 2651        var node = dictionary.GetValueOrDefault(id);
 2652        var variable = context.Variable;
 2653        var variableType = variable.GetVariableType();
 2654        var serializerOptions = GetSerializerOptions();
 55
 2656        if (variableType == typeof(object))
 757            return new(node?.Deserialize(typeof(object), serializerOptions));
 58
 1959        var options = new ObjectConverterOptions
 1960        {
 1961            DeserializeJsonObjectToObject = true,
 1962            SerializerOptions = serializerOptions
 1963        };
 1964        var result = node.TryConvertTo(variableType, options);
 1965        if (result.IsSuccess)
 1766            return new(result.Value);
 67
 268        logger.LogWarning(result.Exception, "Failed to convert stored variable '{VariableId}' to type '{VariableType}'. 
 269            id, variableType.FullName);
 70
 271        if (ObjectConverter.StrictMode)
 172            result.ThrowIfFailure();
 73
 174        return new((object?)null);
 75    }
 76
 77    /// <inheritdoc />
 78    public ValueTask DeleteAsync(string id, StorageDriverContext context)
 79    {
 24680        UpdateVariablesDictionary(context, dictionary => dictionary.Remove(id));
 12381        return ValueTask.CompletedTask;
 82    }
 83
 22784    private JsonSerializerOptions GetSerializerOptions() => payloadSerializer.GetOptions().Clone();
 85
 86    private static Type GetSerializationType(object? value, StorageDriverContext context)
 87    {
 20188        var declaredType = context.Variable.GetVariableType();
 20189        if (declaredType == typeof(object))
 8090            return typeof(object);
 91
 12192        return value?.GetType() ?? declaredType;
 93    }
 94
 46895    private VariablesDictionary GetVariablesDictionary(StorageDriverContext context) => context.ExecutionContext.Propert
 32496    private void SetVariablesDictionary(StorageDriverContext context, VariablesDictionary dictionary) => context.Executi
 97
 98    private void UpdateVariablesDictionary(StorageDriverContext context, Action<VariablesDictionary> update)
 99    {
 324100        var dictionary = GetVariablesDictionary(context);
 324101        update(dictionary);
 324102        SetVariablesDictionary(context, dictionary);
 324103    }
 104}
 105
 106public class VariablesDictionary : Dictionary<string, JsonNode>;