Refactor use of readonly dictionary to dictionary

This commit is contained in:
Sipke Schoorstra 2022-04-07 13:06:16 +02:00
parent 7f3d989911
commit 0c9674fc6d
20 changed files with 43 additions and 38 deletions

View file

@ -5,8 +5,8 @@ namespace Elsa.Contracts;
public interface IWorkflowRunner
{
Task<ExecuteWorkflowResult> RunAsync(Workflow workflow, IReadOnlyDictionary<string, object>? input = default, CancellationToken cancellationToken = default);
Task<ExecuteWorkflowResult> RunAsync(Workflow workflow, WorkflowState workflowState, IReadOnlyDictionary<string, object>? input = default, CancellationToken cancellationToken = default);
Task<ExecuteWorkflowResult> RunAsync(Workflow workflow, WorkflowState workflowState, Bookmark? bookmark, IReadOnlyDictionary<string, object>? input = default, CancellationToken cancellationToken = default);
Task<ExecuteWorkflowResult> RunAsync(Workflow workflow, IDictionary<string, object>? input = default, CancellationToken cancellationToken = default);
Task<ExecuteWorkflowResult> RunAsync(Workflow workflow, WorkflowState workflowState, IDictionary<string, object>? input = default, CancellationToken cancellationToken = default);
Task<ExecuteWorkflowResult> RunAsync(Workflow workflow, WorkflowState workflowState, Bookmark? bookmark, IDictionary<string, object>? input = default, CancellationToken cancellationToken = default);
Task<ExecuteWorkflowResult> RunAsync(WorkflowExecutionContext workflowExecutionContext);
}

View file

@ -4,8 +4,6 @@ namespace Elsa;
public static class DictionaryExtensions
{
public static bool TryGetValue<TKey, T>(this IReadOnlyDictionary<TKey, object> dictionary, TKey key, out T? value) => TryGetValue((IDictionary<TKey, object?>)dictionary, key, out value);
public static bool TryGetValue<T>(this IDictionary<string, object?> dictionary, string key, out T? value) => dictionary.TryGetValue<string, T>(key, out value);
public static bool TryGetValue<TKey, T>(this IDictionary<TKey, object?> dictionary, TKey key, out T? value)
@ -21,7 +19,7 @@ public static class DictionaryExtensions
}
public static T? GetValue<TKey, T>(this IDictionary<TKey, object?> dictionary, TKey key) => ConvertValue<T>(dictionary[key]);
public static T? GetValue<T>(this IReadOnlyDictionary<string, object> dictionary, string key) => ConvertValue<T>(dictionary[key]);
public static T? GetValue<T>(this IDictionary<string, object> dictionary, string key) => ConvertValue<T>(dictionary[key]);
public static T? GetOrAdd<TKey, T>(this IDictionary<TKey, object?> dictionary, TKey key, Func<T> valueFactory) where T : notnull
{

View file

@ -4,7 +4,14 @@ namespace Elsa;
public static class ObjectExtensions
{
/// <summary>
/// Converts an object into a dictionary.
/// </summary>
public static IDictionary<string, object> ToDictionary(this object source, BindingFlags bindingAttr = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance) => source.ToDictionaryInternal(bindingAttr);
/// <summary>
/// Converts an object into a dictionary.
/// </summary>
public static IReadOnlyDictionary<string, object> ToReadOnlyDictionary(this object source, BindingFlags bindingAttr = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance) => source.ToDictionaryInternal(bindingAttr);
private static Dictionary<string, object> ToDictionaryInternal(this object source, BindingFlags bindingAttr = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance) =>

View file

@ -60,7 +60,7 @@ public class ActivityExecutionContext
/// <summary>
/// A dictionary of received inputs.
/// </summary>
public IReadOnlyDictionary<string, object> Input => WorkflowExecutionContext.Input;
public IDictionary<string, object> Input => WorkflowExecutionContext.Input;
/// <summary>
/// Journal data will be added to the workflow execution log for the "Executed" event.

View file

@ -9,7 +9,7 @@ public class ExpressionExecutionContext
public ExpressionExecutionContext(IServiceProvider serviceProvider,
Register register,
Workflow workflow,
IReadOnlyDictionary<string, object> input,
IDictionary<string, object> input,
IDictionary<object, object?> transientProperties,
ExpressionExecutionContext? parentContext,
CancellationToken cancellationToken)
@ -25,7 +25,7 @@ public class ExpressionExecutionContext
public Register Register { get; }
public Workflow Workflow { get; }
public IReadOnlyDictionary<string, object> Input { get; }
public IDictionary<string, object> Input { get; }
public IDictionary<object, object?> TransientProperties { get; }
public ExpressionExecutionContext? ParentContext { get; set; }
public CancellationToken CancellationToken { get; }
@ -35,7 +35,7 @@ public class ExpressionExecutionContext
public T Get<T>(RegisterLocationReference locationReference) => (T)Get(locationReference);
public T? Get<T>(Input<T>? input) => input != null ? (T?)GetLocation(input.LocationReference).Value : default;
public T? Get<T>(Output output) => (T?)GetLocation(output.LocationReference).Value;
public object? Get(Output? output) => output != null ? GetLocation(output.LocationReference).Value : default;
public object? Get(Output output) => GetLocation(output.LocationReference).Value;
public T? GetVariable<T>(string name) => (T?)GetVariable(name);
public T? GetVariable<T>() => (T?)GetVariable(typeof(T).Name);
public object? GetVariable(string name) => new Variable(name).Get(this);

View file

@ -20,7 +20,7 @@ public class WorkflowExecutionContext
ActivityNode graph,
IActivityScheduler scheduler,
Bookmark? bookmark,
IReadOnlyDictionary<string, object>? input,
IDictionary<string, object>? input,
ExecuteActivityDelegate? executeDelegate,
CancellationToken cancellationToken)
{
@ -48,7 +48,7 @@ public class WorkflowExecutionContext
public IDictionary<IActivity, ActivityNode> NodeActivityLookup { get; }
public IActivityScheduler Scheduler { get; }
public Bookmark? Bookmark { get; }
public IReadOnlyDictionary<string, object> Input { get; }
public IDictionary<string, object> Input { get; }
/// <summary>
/// A dictionary that can be used by application code and activities to store information. Values need to be serializable, since this dictionary will be persisted alongside the workflow instance.

View file

@ -30,7 +30,7 @@ public class WorkflowRunner : IWorkflowRunner
_schedulerFactory = schedulerFactory;
}
public async Task<ExecuteWorkflowResult> RunAsync(Workflow workflow, IReadOnlyDictionary<string, object>? input, CancellationToken cancellationToken = default)
public async Task<ExecuteWorkflowResult> RunAsync(Workflow workflow, IDictionary<string, object>? input, CancellationToken cancellationToken = default)
{
// Create a child scope.
using var scope = _serviceScopeFactory.CreateScope();
@ -44,7 +44,7 @@ public class WorkflowRunner : IWorkflowRunner
return await RunAsync(workflowExecutionContext);
}
public async Task<ExecuteWorkflowResult> RunAsync(Workflow workflow, WorkflowState workflowState, IReadOnlyDictionary<string, object>? input, CancellationToken cancellationToken = default)
public async Task<ExecuteWorkflowResult> RunAsync(Workflow workflow, WorkflowState workflowState, IDictionary<string, object>? input, CancellationToken cancellationToken = default)
{
// Create a child scope.
using var scope = _serviceScopeFactory.CreateScope();
@ -58,7 +58,7 @@ public class WorkflowRunner : IWorkflowRunner
return await RunAsync(workflowExecutionContext);
}
public async Task<ExecuteWorkflowResult> RunAsync(Workflow workflow, WorkflowState workflowState, Bookmark? bookmark, IReadOnlyDictionary<string, object>? input, CancellationToken cancellationToken = default)
public async Task<ExecuteWorkflowResult> RunAsync(Workflow workflow, WorkflowState workflowState, Bookmark? bookmark, IDictionary<string, object>? input, CancellationToken cancellationToken = default)
{
// Create a child scope.
using var scope = _serviceScopeFactory.CreateScope();
@ -89,7 +89,7 @@ public class WorkflowRunner : IWorkflowRunner
Workflow workflow,
WorkflowState? workflowState,
Bookmark? bookmark,
IReadOnlyDictionary<string, object>? input,
IDictionary<string, object>? input,
ExecuteActivityDelegate? executeActivityDelegate,
CancellationToken cancellationToken)
{

View file

@ -27,7 +27,7 @@ public class DispatchWorkflow : Activity
}
var workflowService = context.GetRequiredService<IWorkflowService>();
var input = context.Get(Input)?.ToReadOnlyDictionary();
var input = context.Get(Input);
await workflowService.DispatchWorkflowAsync(workflowDefinitionId, VersionOptions.Published, input, context.CancellationToken);
}
}

View file

@ -95,7 +95,7 @@ public class WorkflowOperatorActor : IActor
return response;
}
private async Task<ExecuteWorkflowResult> ExecuteAsync(Workflow workflow, WorkflowState workflowState, Bookmark? bookmarkMessage, IReadOnlyDictionary<string, object?>? input, CancellationToken cancellationToken)
private async Task<ExecuteWorkflowResult> ExecuteAsync(Workflow workflow, WorkflowState workflowState, Bookmark? bookmarkMessage, IDictionary<string, object>? input, CancellationToken cancellationToken)
{
if (bookmarkMessage == null)
return await _workflowRunner.RunAsync(workflow, workflowState, input, cancellationToken);

View file

@ -7,9 +7,9 @@ namespace Elsa.Runtime.ProtoActor.Extensions;
public static class ProtoInputExtensions
{
public static IReadOnlyDictionary<string, object?> Deserialize(this Input input) => input.Data.ToDictionary(x => x.Key, x => JsonSerializer.Deserialize<object>(x.Value.Text));
public static IDictionary<string, object?> Deserialize(this Input input) => input.Data.ToDictionary(x => x.Key, x => JsonSerializer.Deserialize<object>(x.Value.Text));
public static Input Serialize(this IReadOnlyDictionary<string, object?> input)
public static Input Serialize(this IDictionary<string, object?> input)
{
var result = new Input();
var data = result.Data;

View file

@ -8,10 +8,10 @@ namespace Elsa.Runtime.Contracts;
/// </summary>
public interface IWorkflowService
{
Task<ExecuteWorkflowResult> ExecuteWorkflowAsync(string definitionId, VersionOptions versionOptions, IReadOnlyDictionary<string, object>? input = default, CancellationToken cancellationToken = default);
Task<ExecuteWorkflowResult> ExecuteWorkflowAsync(string instanceId, Bookmark bookmark, IReadOnlyDictionary<string, object>? input = default, CancellationToken cancellationToken = default);
Task<DispatchWorkflowResult> DispatchWorkflowAsync(string definitionId, VersionOptions versionOptions, IReadOnlyDictionary<string, object>? input = default, CancellationToken cancellationToken = default);
Task<DispatchWorkflowResult> DispatchWorkflowAsync(string instanceId, Bookmark bookmark, IReadOnlyDictionary<string, object>? input = default, CancellationToken cancellationToken = default);
Task<ExecuteWorkflowResult> ExecuteWorkflowAsync(string definitionId, VersionOptions versionOptions, IDictionary<string, object>? input = default, CancellationToken cancellationToken = default);
Task<ExecuteWorkflowResult> ExecuteWorkflowAsync(string instanceId, Bookmark bookmark, IDictionary<string, object>? input = default, CancellationToken cancellationToken = default);
Task<DispatchWorkflowResult> DispatchWorkflowAsync(string definitionId, VersionOptions versionOptions, IDictionary<string, object>? input = default, CancellationToken cancellationToken = default);
Task<DispatchWorkflowResult> DispatchWorkflowAsync(string instanceId, Bookmark bookmark, IDictionary<string, object>? input = default, CancellationToken cancellationToken = default);
Task<IEnumerable<ExecuteWorkflowInstructionResult>> ExecuteStimulusAsync(IStimulus stimulus, CancellationToken cancellationToken);
Task<IEnumerable<DispatchWorkflowInstructionResult>> DispatchStimulusAsync(IStimulus stimulus, CancellationToken cancellationToken);

View file

@ -10,7 +10,7 @@ using Microsoft.Extensions.Logging;
namespace Elsa.Runtime.Interpreters;
public record ResumeWorkflowInstruction(WorkflowBookmark WorkflowBookmark, IReadOnlyDictionary<string, object>? Input) : IWorkflowInstruction;
public record ResumeWorkflowInstruction(WorkflowBookmark WorkflowBookmark, IDictionary<string, object>? Input) : IWorkflowInstruction;
public class ResumeWorkflowInstructionInterpreter : WorkflowInstructionInterpreter<ResumeWorkflowInstruction>
{

View file

@ -8,7 +8,7 @@ using Microsoft.Extensions.Logging;
namespace Elsa.Runtime.Interpreters;
public record TriggerWorkflowInstruction(WorkflowTrigger WorkflowTrigger, IReadOnlyDictionary<string, object>? Input) : IWorkflowInstruction;
public record TriggerWorkflowInstruction(WorkflowTrigger WorkflowTrigger, IDictionary<string, object>? Input) : IWorkflowInstruction;
public class TriggerWorkflowInstructionInterpreter : WorkflowInstructionInterpreter<TriggerWorkflowInstruction>
{

View file

@ -2,4 +2,4 @@ using Elsa.Persistence.Models;
namespace Elsa.Runtime.Models;
public record DispatchWorkflowDefinitionRequest(string DefinitionId, VersionOptions VersionOptions, IReadOnlyDictionary<string, object>? Input = default);
public record DispatchWorkflowDefinitionRequest(string DefinitionId, VersionOptions VersionOptions, IDictionary<string, object>? Input = default);

View file

@ -2,4 +2,4 @@ using Elsa.Models;
namespace Elsa.Runtime.Models;
public record DispatchWorkflowInstanceRequest(string InstanceId, Bookmark? Bookmark = default, IReadOnlyDictionary<string, object>? Input = default);
public record DispatchWorkflowInstanceRequest(string InstanceId, Bookmark? Bookmark = default, IDictionary<string, object>? Input = default);

View file

@ -2,4 +2,4 @@ using Elsa.Persistence.Models;
namespace Elsa.Runtime.Models;
public record ExecuteWorkflowDefinitionRequest(string DefinitionId, VersionOptions VersionOptions, IReadOnlyDictionary<string, object>? Input = default);
public record ExecuteWorkflowDefinitionRequest(string DefinitionId, VersionOptions VersionOptions, IDictionary<string, object>? Input = default);

View file

@ -2,4 +2,4 @@ using Elsa.Models;
namespace Elsa.Runtime.Models;
public record ExecuteWorkflowInstanceRequest(string InstanceId, Bookmark? Bookmark = default, IReadOnlyDictionary<string, object>? Input = default);
public record ExecuteWorkflowInstanceRequest(string InstanceId, Bookmark? Bookmark = default, IDictionary<string, object>? Input = default);

View file

@ -4,7 +4,7 @@ namespace Elsa.Runtime.Models;
public static class Stimulus
{
public static StandardStimulus Standard(string activityTypeName, string? hash = default, IReadOnlyDictionary<string, object>? input = default) => new(activityTypeName, hash, input);
public static StandardStimulus Standard(string activityTypeName, string? hash, object input) => new(activityTypeName, hash, input.ToReadOnlyDictionary());
public static StandardStimulus Standard(string activityTypeName, object input) => new(activityTypeName, default, input.ToReadOnlyDictionary());
public static StandardStimulus Standard(string activityTypeName, string? hash = default, IDictionary<string, object>? input = default) => new(activityTypeName, hash, input);
public static StandardStimulus Standard(string activityTypeName, string? hash, object input) => new(activityTypeName, hash, input.ToDictionary());
public static StandardStimulus Standard(string activityTypeName, object input) => new(activityTypeName, default, input.ToDictionary());
}

View file

@ -18,25 +18,25 @@ public class WorkflowService : IWorkflowService
_stimulusInterpreter = stimulusInterpreter;
}
public async Task<ExecuteWorkflowResult> ExecuteWorkflowAsync(string definitionId, VersionOptions versionOptions, IReadOnlyDictionary<string, object>? input = default, CancellationToken cancellationToken = default)
public async Task<ExecuteWorkflowResult> ExecuteWorkflowAsync(string definitionId, VersionOptions versionOptions, IDictionary<string, object>? input = default, CancellationToken cancellationToken = default)
{
var executeRequest = new ExecuteWorkflowDefinitionRequest(definitionId, versionOptions, input);
return await _workflowInvoker.ExecuteAsync(executeRequest, cancellationToken);
}
public async Task<ExecuteWorkflowResult> ExecuteWorkflowAsync(string instanceId, Bookmark bookmark, IReadOnlyDictionary<string, object>? input = default, CancellationToken cancellationToken = default)
public async Task<ExecuteWorkflowResult> ExecuteWorkflowAsync(string instanceId, Bookmark bookmark, IDictionary<string, object>? input = default, CancellationToken cancellationToken = default)
{
var request = new ExecuteWorkflowInstanceRequest(instanceId, bookmark, input);
return await _workflowInvoker.ExecuteAsync(request, cancellationToken);
}
public async Task<DispatchWorkflowResult> DispatchWorkflowAsync(string definitionId, VersionOptions versionOptions, IReadOnlyDictionary<string, object>? input = default, CancellationToken cancellationToken = default)
public async Task<DispatchWorkflowResult> DispatchWorkflowAsync(string definitionId, VersionOptions versionOptions, IDictionary<string, object>? input = default, CancellationToken cancellationToken = default)
{
var executeRequest = new DispatchWorkflowDefinitionRequest(definitionId, versionOptions, input);
return await _workflowInvoker.DispatchAsync(executeRequest, cancellationToken);
}
public async Task<DispatchWorkflowResult> DispatchWorkflowAsync(string instanceId, Bookmark bookmark, IReadOnlyDictionary<string, object>? input = default, CancellationToken cancellationToken = default)
public async Task<DispatchWorkflowResult> DispatchWorkflowAsync(string instanceId, Bookmark bookmark, IDictionary<string, object>? input = default, CancellationToken cancellationToken = default)
{
var request = new DispatchWorkflowInstanceRequest(instanceId, bookmark, input);
return await _workflowInvoker.DispatchAsync(request, cancellationToken);

View file

@ -5,4 +5,4 @@ namespace Elsa.Runtime.Stimuli;
/// <summary>
/// Represents a simple stimulus that targets a specific activity type and optionally a corresponding hash to use as a bookmark lookup.
/// </summary>
public record StandardStimulus(string ActivityTypeName, string? Hash = default, IReadOnlyDictionary<string, object>? Input = default) : IStimulus;
public record StandardStimulus(string ActivityTypeName, string? Hash = default, IDictionary<string, object>? Input = default) : IStimulus;