< Summary

Information
Class: Elsa.Workflows.Activity
Assembly: Elsa.Workflows.Core
File(s): /home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Workflows.Core/Abstractions/Activity.cs
Line coverage
84%
Covered lines: 48
Uncovered lines: 9
Coverable lines: 57
Total lines: 209
Line coverage: 84.2%
Branch coverage
100%
Covered branches: 6
Total branches: 6
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

File(s)

/home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Workflows.Core/Abstractions/Activity.cs

#LineLine coverage
 1using System.Diagnostics;
 2using System.Text.Json.Serialization;
 3using Elsa.Extensions;
 4using Elsa.Workflows.Behaviors;
 5using Elsa.Workflows.Helpers;
 6using Elsa.Workflows.Models;
 7using Elsa.Workflows.Serialization.Converters;
 8using JetBrains.Annotations;
 9
 10namespace Elsa.Workflows;
 11
 12/// <summary>
 13/// Base class for custom activities.
 14/// </summary>
 15[DebuggerDisplay("{Type} - {Id}")]
 16[UsedImplicitly(ImplicitUseTargetFlags.WithInheritors | ImplicitUseTargetFlags.Members)]
 17public abstract class Activity : IActivity, ISignalHandler
 18{
 1297219    private readonly ICollection<SignalHandlerRegistration> _signalReceivedHandlers = new List<SignalHandlerRegistration
 20
 21    /// <summary>
 22    /// Constructor.
 23    /// </summary>
 1297224    protected Activity(string? source = null, int? line = null)
 25    {
 1297226        this.SetSource(source, line);
 1297227        Type = ActivityTypeNameHelper.GenerateTypeName(GetType());
 1297228        Version = 1;
 1297229        Behaviors.Add<ScheduledChildCallbackBehavior>(this);
 1297230    }
 31
 32    /// <inheritdoc />
 033    protected Activity(string activityType, int version = 1, string? source = null, int? line = null) : this(source, lin
 34    {
 035        Type = activityType;
 036        Version = version;
 037    }
 38
 39    /// <inheritdoc />
 17015140    public string Id { get; set; } = null!;
 41
 42    /// <inheritdoc />
 2395743    public string NodeId { get; set; } = null!;
 44
 45    /// <inheritdoc />
 1452946    public string? Name { get; set; }
 47
 48    /// <inheritdoc />
 7255549    public string Type { get; set; }
 50
 51    /// <inheritdoc />
 5635752    public int Version { get; set; }
 53
 54    /// <summary>
 55    /// A flag indicating whether this activity can be used for starting a workflow.
 56    /// Usually used for triggers, but also used to disambiguate between two or more starting activities and no starting
 57    /// </summary>
 58    [JsonIgnore]
 59    public bool CanStartWorkflow
 60    {
 661        get => this.GetCanStartWorkflow();
 6862        set => this.SetCanStartWorkflow(value);
 63    }
 64
 65    /// <summary>
 66    /// A flag indicating if this activity should execute synchronously or asynchronously.
 67    /// By default, activities with an <see cref="ActivityKind"/> of <see cref="Action"/>, <see cref="Task"/> or <see cr
 68    /// will execute synchronously, while activities of the <see cref="ActivityKind.Job"/> kind will execute asynchronou
 69    /// </summary>
 70    [JsonIgnore]
 71    public bool? RunAsynchronously
 72    {
 673        get => this.GetRunAsynchronously();
 106174        set => this.SetRunAsynchronously(value);
 75    }
 76
 77    [JsonIgnore]
 78    public string? CommitStrategy
 79    {
 680        get => this.GetCommitStrategy();
 081        set => this.SetCommitStrategy(value);
 82    }
 83
 84    /// <inheritdoc />
 85    [JsonConverter(typeof(PolymorphicObjectConverterFactory))]
 6630886    public IDictionary<string, object> CustomProperties { get; set; } = new Dictionary<string, object>();
 87
 88    /// <inheritdoc />
 89    [JsonIgnore]
 1308690    public IDictionary<string, object> SyntheticProperties { get; set; } = new Dictionary<string, object>();
 91
 92    /// <inheritdoc />
 93    [JsonConverter(typeof(PolymorphicObjectConverterFactory))]
 1743994    public IDictionary<string, object> Metadata { get; set; } = new Dictionary<string, object>();
 95
 96    /// <summary>
 97    /// A collection of reusable behaviors to add to this activity.
 98    /// </summary>
 99    [JsonIgnore]
 44132100    public ICollection<IBehavior> Behaviors { get; } = new List<IBehavior>();
 101
 102    /// <summary>
 103    /// Override this method to return a value indicating whether the activity can execute.
 104    /// </summary>
 105    protected virtual ValueTask<bool> CanExecuteAsync(ActivityExecutionContext context)
 106    {
 3019107        var result = CanExecute(context);
 3019108        return new(result);
 109    }
 110
 111    /// <summary>
 112    /// Override this method to return a value indicating whether the activity can execute.
 113    /// </summary>
 114    protected virtual bool CanExecute(ActivityExecutionContext context)
 115    {
 2997116        return true;
 117    }
 118
 119    /// <summary>
 120    /// Override this method to implement activity-specific logic.
 121    /// </summary>
 122    protected virtual ValueTask ExecuteAsync(ActivityExecutionContext context)
 123    {
 698124        Execute(context);
 671125        return ValueTask.CompletedTask;
 126    }
 127
 128    /// <summary>
 129    /// Override this method to implement activity-specific logic.
 130    /// </summary>
 131    protected virtual void Execute(ActivityExecutionContext context)
 132    {
 18133    }
 134
 135    /// <summary>
 136    /// Override this method to handle any signals sent from downstream activities.
 137    /// </summary>
 138    protected virtual ValueTask OnSignalReceivedAsync(object signal, SignalContext context)
 139    {
 12182140        OnSignalReceived(signal, context);
 12182141        return ValueTask.CompletedTask;
 142    }
 143
 144    /// <summary>
 145    /// Override this method to handle any signals sent from downstream activities.
 146    /// </summary>
 147    protected virtual void OnSignalReceived(object signal, SignalContext context)
 148    {
 12182149    }
 150
 151    /// <summary>
 152    /// Register a signal handler delegate.
 153    /// </summary>
 10774154    protected void OnSignalReceived(Type signalType, Func<object, SignalContext, ValueTask> handler) => _signalReceivedH
 155
 156    /// <summary>
 157    /// Register a signal handler delegate.
 158    /// </summary>
 10776159    protected void OnSignalReceived<T>(Func<T, SignalContext, ValueTask> handler) => OnSignalReceived(typeof(T), (signal
 160
 161    /// <summary>
 162    /// Register a signal handler delegate.
 163    /// </summary>
 164    protected void OnSignalReceived<T>(Action<T, SignalContext> handler)
 165    {
 4035166        OnSignalReceived<T>((signal, context) =>
 4035167        {
 0168            handler(signal, context);
 0169            return ValueTask.CompletedTask;
 4035170        });
 4035171    }
 172
 173    /// <summary>
 174    /// Notify the workflow that this activity completed.
 175    /// </summary>
 176    protected async ValueTask CompleteAsync(ActivityExecutionContext context)
 177    {
 0178        await context.CompleteActivityAsync();
 0179    }
 180
 181    async ValueTask<bool> IActivity.CanExecuteAsync(ActivityExecutionContext context)
 182    {
 3019183        return await CanExecuteAsync(context);
 3019184    }
 185
 186    async ValueTask IActivity.ExecuteAsync(ActivityExecutionContext context)
 187    {
 3366188        await ExecuteAsync(context);
 189
 190        // Invoke behaviors.
 18849191        foreach (var behavior in Behaviors) await behavior.ExecuteAsync(context);
 3333192    }
 193
 194    async ValueTask ISignalHandler.ReceiveSignalAsync(object signal, SignalContext context)
 195    {
 196        // Give derived activity a chance to do something with the signal.
 12182197        await OnSignalReceivedAsync(signal, context);
 198
 199        // Invoke registered signal delegates for this particular type of signal.
 12182200        var signalType = signal.GetType();
 30276201        var handlers = _signalReceivedHandlers.Where(x => x.SignalType == signalType);
 202
 24368203        foreach (var registration in handlers)
 2204            await registration.Handler(signal, context);
 205
 206        // Invoke behaviors.
 63187207        foreach (var behavior in Behaviors) await behavior.ReceiveSignalAsync(signal, context);
 12182208    }
 209}