**BREAKING API** Update Builder API to allow to connect to named activities as well as activities by type name
This replaces the `Then(string activityName)` method with `ThenNamed(string activityName)`. A new method is added to allow connecting to activities by type name: `ThenTypeNamed(string activityTypeName)`. The reason for this change and addition is to allow workflow builders to connect to activity types that do not have a corresponding type. For example, the Telnyx project has an activity type provider that *dynamically* provides activity types based on Telnyx webhook callback types.
This commit is contained in:
parent
5d8d05aec5
commit
6fef9874da
|
|
@ -2,6 +2,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using Elsa.Activities.ControlFlow;
|
||||
using Elsa.Activities.Telnyx.Webhooks.Payloads.Call;
|
||||
using Elsa.Attributes;
|
||||
using Elsa.Builders;
|
||||
using Elsa.Design;
|
||||
|
|
@ -85,7 +86,7 @@ namespace Elsa.Activities.Telnyx.Activities
|
|||
.WithFrom(() => From)
|
||||
.WithFromDisplayName(() => FromDisplayName)
|
||||
)
|
||||
.Then();
|
||||
.ThenTypeNamed(CallAnsweredPayload.ActivityTypeName);
|
||||
}
|
||||
|
||||
object IActivityPropertyDefaultValueProvider.GetDefaultValue(PropertyInfo property) => Duration.FromSeconds(20);
|
||||
|
|
|
|||
|
|
@ -2,10 +2,11 @@
|
|||
|
||||
namespace Elsa.Activities.Telnyx.Webhooks.Payloads.Call
|
||||
{
|
||||
[Payload(EventType, "TelnyxCallAnswered", "Call Answered", "Triggered when an incoming call is answered.")]
|
||||
[Payload(EventType, ActivityTypeName, "Call Answered", "Triggered when an incoming call is answered.")]
|
||||
public sealed record CallAnsweredPayload : CallPayload
|
||||
{
|
||||
public const string EventType = "call.answered";
|
||||
public const string ActivityTypeName = "CallAnswered";
|
||||
public string From { get; init; } = default!;
|
||||
public string To { get; init; } = default!;
|
||||
public string State { get; init; } = default!;
|
||||
|
|
|
|||
|
|
@ -2,10 +2,11 @@
|
|||
|
||||
namespace Elsa.Activities.Telnyx.Webhooks.Payloads.Call
|
||||
{
|
||||
[Payload(EventType, "TelnyxCallDtmfReceived", "Call DTMF Received", "Triggered when DTMF input is received.")]
|
||||
public sealed record CallDtmfReceived : CallPayload
|
||||
[Payload(EventType, ActivityTypeName, "Call DTMF Received", "Triggered when DTMF input is received.")]
|
||||
public sealed record CallDtmfReceivedPayload : CallPayload
|
||||
{
|
||||
public const string EventType = "call.dtmf.received";
|
||||
public const string ActivityTypeName = "CallDtmfReceived";
|
||||
public string Digit { get; set; }
|
||||
public string From { get; set; }
|
||||
public string To { get; set; }
|
||||
|
|
@ -2,10 +2,11 @@
|
|||
|
||||
namespace Elsa.Activities.Telnyx.Webhooks.Payloads.Call
|
||||
{
|
||||
[Payload(EventType, "TelnyxCallGatherEnded", "Call Gather Ended", "Triggered when an call gather has ended.")]
|
||||
public sealed record CallGatherEnded : CallPayload
|
||||
[Payload(EventType, ActivityTypeName, "Call Gather Ended", "Triggered when an call gather has ended.")]
|
||||
public sealed record CallGatherEndedPayload : CallPayload
|
||||
{
|
||||
public const string EventType = "call.gather.ended";
|
||||
public const string ActivityTypeName = "CallGatherEnded";
|
||||
public string Digits { get; set; }
|
||||
public string From { get; set; }
|
||||
public string To { get; set; }
|
||||
|
|
@ -3,10 +3,11 @@ using NodaTime;
|
|||
|
||||
namespace Elsa.Activities.Telnyx.Webhooks.Payloads.Call
|
||||
{
|
||||
[Payload(EventType, "TelnyxCallHangup", "Call Hangup", "Triggered when an incoming call was hangup.")]
|
||||
[Payload(EventType, ActivityTypeName, "Call Hangup", "Triggered when an incoming call was hangup.")]
|
||||
public sealed record CallHangupPayload : CallPayload
|
||||
{
|
||||
public const string EventType = "call.hangup";
|
||||
public const string ActivityTypeName = "CallHangup";
|
||||
public Instant StartTime { get; init; }
|
||||
public Instant EndTime { get; init; }
|
||||
public string SipHangupCause { get; init; } = default!;
|
||||
|
|
|
|||
|
|
@ -2,10 +2,11 @@
|
|||
|
||||
namespace Elsa.Activities.Telnyx.Webhooks.Payloads.Call
|
||||
{
|
||||
[Payload(EventType, "TelnyxCallInitiated", "Call Initiated", "Triggered when an incoming call is received.")]
|
||||
[Payload(EventType, ActivityTypeName, "Call Initiated", "Triggered when an incoming call is received.")]
|
||||
public sealed record CallInitiatedPayload : CallPayload
|
||||
{
|
||||
public const string EventType = "call.initiated";
|
||||
public const string ActivityTypeName = "CallInitiated";
|
||||
public string Direction { get; init; } = default!;
|
||||
public string State { get; init; } = default!;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +0,0 @@
|
|||
using Elsa.Activities.Telnyx.Webhooks.Attributes;
|
||||
|
||||
namespace Elsa.Activities.Telnyx.Webhooks.Payloads.Call
|
||||
{
|
||||
[Payload(EventType, "TelnyxCallPlaybackEnded", "Call Playback Ended", "Triggered when an audio playback has ended.")]
|
||||
public sealed record CallPlaybackEnded : CallPlayback
|
||||
{
|
||||
public const string EventType = "call.playback.ended";
|
||||
public string Status { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
using Elsa.Activities.Telnyx.Webhooks.Attributes;
|
||||
|
||||
namespace Elsa.Activities.Telnyx.Webhooks.Payloads.Call
|
||||
{
|
||||
[Payload(EventType, ActivityTypeName, "Call Playback Ended", "Triggered when an audio playback has ended.")]
|
||||
public sealed record CallPlaybackEndedPayload : CallPlayback
|
||||
{
|
||||
public const string EventType = "call.playback.ended";
|
||||
public const string ActivityTypeName = "CallPlaybackEnded";
|
||||
public string Status { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
using Elsa.Activities.Telnyx.Webhooks.Attributes;
|
||||
|
||||
namespace Elsa.Activities.Telnyx.Webhooks.Payloads.Call
|
||||
{
|
||||
[Payload(EventType, "TelnyxCallPlaybackStarted", "Call Playback Started", "Triggered when an audio playback has started.")]
|
||||
public sealed record CallPlaybackStarted : CallPlayback
|
||||
{
|
||||
public const string EventType = "call.playback.started";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
using Elsa.Activities.Telnyx.Webhooks.Attributes;
|
||||
|
||||
namespace Elsa.Activities.Telnyx.Webhooks.Payloads.Call
|
||||
{
|
||||
[Payload(EventType, ActivityTypeName, "Call Playback Started", "Triggered when an audio playback has started.")]
|
||||
public sealed record CallPlaybackStartedPayload : CallPlayback
|
||||
{
|
||||
public const string EventType = "call.playback.started";
|
||||
public const string ActivityTypeName = "CallPlaybackStarted";
|
||||
}
|
||||
}
|
||||
|
|
@ -10,6 +10,7 @@ namespace Elsa.Builders
|
|||
{
|
||||
ICompositeActivityBuilder WorkflowBuilder { get; set; }
|
||||
public Type ActivityType { get; }
|
||||
public string ActivityTypeName { get; }
|
||||
string ActivityId { get; set; }
|
||||
public string? Name { get; set; }
|
||||
public string? DisplayName { get; set; }
|
||||
|
|
@ -20,10 +21,10 @@ namespace Elsa.Builders
|
|||
bool SaveWorkflowContextEnabled { get; set; }
|
||||
bool PersistOutputEnabled { get; set; }
|
||||
string? Source { get; }
|
||||
IActivityBuilder Add<T>(Action<ISetupActivity<T>>? setup = default, [CallerLineNumber] int lineNumber = default, [CallerFilePath] string? sourceFile = default) where T : class, IActivity;
|
||||
IActivityBuilder Add<T>(string activityTypeName, Action<ISetupActivity<T>>? setup = default, [CallerLineNumber] int lineNumber = default, [CallerFilePath] string? sourceFile = default) where T : class, IActivity;
|
||||
IOutcomeBuilder When(string outcome);
|
||||
IActivityBuilder Then(IActivityBuilder targetActivity);
|
||||
IConnectionBuilder Then(string activityName);
|
||||
IConnectionBuilder ThenNamed(string activityName);
|
||||
IActivityBuilder WithId(string? value);
|
||||
IActivityBuilder WithName(string? value);
|
||||
IActivityBuilder WithDisplayName(string? value);
|
||||
|
|
|
|||
|
|
@ -6,7 +6,9 @@ namespace Elsa.Builders
|
|||
{
|
||||
public interface IBuilder
|
||||
{
|
||||
IActivityBuilder Then<T>(Action<ISetupActivity<T>>? setup, Action<IActivityBuilder>? branch = default, [CallerLineNumber] int lineNumber = default, [CallerFilePath] string? sourceFile = default) where T : class, IActivity;
|
||||
IActivityBuilder Then<T>(Action<IActivityBuilder>? branch = default, [CallerLineNumber] int lineNumber = default, [CallerFilePath] string? sourceFile = default) where T : class, IActivity;
|
||||
IActivityBuilder Then<T>(string activityTypeName, Action<ISetupActivity<T>>? setup, Action<IActivityBuilder>? branch = default, [CallerLineNumber] int lineNumber = default, [CallerFilePath] string? sourceFile = default)
|
||||
where T : class, IActivity;
|
||||
|
||||
IActivityBuilder Then<T>(string activityTypeName, Action<IActivityBuilder>? branch = default, [CallerLineNumber] int lineNumber = default, [CallerFilePath] string? sourceFile = default) where T : class, IActivity;
|
||||
}
|
||||
}
|
||||
|
|
@ -12,34 +12,37 @@ namespace Elsa.Builders
|
|||
IReadOnlyCollection<IActivityBuilder> Activities { get; }
|
||||
|
||||
IActivityBuilder New<T>(
|
||||
string activityTypeName,
|
||||
IDictionary<string, IActivityPropertyValueProvider>? propertyValueProviders = default,
|
||||
[CallerLineNumber] int lineNumber = default,
|
||||
[CallerFilePath] string? sourceFile = default)
|
||||
where T : class, IActivity;
|
||||
|
||||
IActivityBuilder New<T>(
|
||||
string activityTypeName,
|
||||
Action<ISetupActivity<T>>? setup,
|
||||
[CallerLineNumber] int lineNumber = default,
|
||||
[CallerFilePath] string? sourceFile = default) where T : class, IActivity;
|
||||
|
||||
IActivityBuilder StartWith<T>(
|
||||
string activityTypeName,
|
||||
Action<ISetupActivity<T>>? setup,
|
||||
Action<IActivityBuilder>? branch = default,
|
||||
[CallerLineNumber] int lineNumber = default,
|
||||
[CallerFilePath] string? sourceFile = default) where T : class, IActivity;
|
||||
|
||||
IActivityBuilder StartWith<T>(Action<IActivityBuilder>? branch = default, [CallerLineNumber] int lineNumber = default, [CallerFilePath] string? sourceFile = default) where T : class, IActivity;
|
||||
IActivityBuilder StartWith<T>(string activityTypeName, Action<IActivityBuilder>? branch = default, [CallerLineNumber] int lineNumber = default, [CallerFilePath] string? sourceFile = default) where T : class, IActivity;
|
||||
|
||||
IActivityBuilder Add<T>(
|
||||
string activityTypeName,
|
||||
Action<ISetupActivity<T>>? setup,
|
||||
Action<IActivityBuilder>? branch = default,
|
||||
string? activityType = default,
|
||||
[CallerLineNumber] int lineNumber = default,
|
||||
[CallerFilePath] string? sourceFile = default) where T : class, IActivity;
|
||||
|
||||
IActivityBuilder Add<T>(
|
||||
string activityTypeName,
|
||||
Action<IActivityBuilder>? branch = default,
|
||||
string? activityType = default,
|
||||
IDictionary<string, IActivityPropertyValueProvider>? propertyValueProviders = default,
|
||||
[CallerLineNumber] int lineNumber = default,
|
||||
[CallerFilePath] string? sourceFile = default)
|
||||
|
|
|
|||
|
|
@ -17,11 +17,11 @@ namespace Elsa.Builders
|
|||
|
||||
public static class SetupActivityExtensions
|
||||
{
|
||||
// public static ISetupActivity<T> Set<T, TProperty>(
|
||||
// this ISetupActivity<T> builder,
|
||||
// Expression<Func<T, TProperty?>> propertyAccessor,
|
||||
// Func<ActivityExecutionContext, ValueTask<TProperty?>> valueFactory) where T : IActivity =>
|
||||
// builder.Set(propertyAccessor, async context => await valueFactory(context));
|
||||
public static ISetupActivity<T> Set<T, TProperty>(
|
||||
this ISetupActivity<T> builder,
|
||||
Expression<Func<T, TProperty?>> propertyAccessor,
|
||||
Func<ActivityExecutionContext, ValueTask<TProperty?>> valueFactory) where T : IActivity =>
|
||||
builder.Set(propertyAccessor, async context => await valueFactory(context));
|
||||
|
||||
public static ISetupActivity<T> Set<T, TProperty>(
|
||||
this ISetupActivity<T> builder,
|
||||
|
|
|
|||
|
|
@ -6,20 +6,21 @@ using System.Runtime.CompilerServices;
|
|||
using Elsa.Services;
|
||||
using Elsa.Services.Models;
|
||||
|
||||
// ReSharper disable ExplicitCallerInfoArgument
|
||||
namespace Elsa.Builders
|
||||
{
|
||||
public class ActivityBuilder : IActivityBuilder
|
||||
{
|
||||
public ActivityBuilder(
|
||||
Type activityType,
|
||||
string? activityTypeName,
|
||||
string activityTypeName,
|
||||
ICompositeActivityBuilder workflowBuilder,
|
||||
IDictionary<string, IActivityPropertyValueProvider>? propertyValueProviders,
|
||||
int lineNumber,
|
||||
string? sourceFile)
|
||||
{
|
||||
ActivityType = activityType;
|
||||
ActivityTypeName = activityTypeName ?? activityType.Name;
|
||||
ActivityTypeName = activityTypeName;
|
||||
WorkflowBuilder = workflowBuilder;
|
||||
PropertyValueProviders = propertyValueProviders;
|
||||
LineNumber = lineNumber;
|
||||
|
|
@ -31,7 +32,7 @@ namespace Elsa.Builders
|
|||
}
|
||||
|
||||
public Type ActivityType { get; protected set; } = default!;
|
||||
public string ActivityTypeName { get; set; } = default!;
|
||||
public string ActivityTypeName { get; protected set; } = default!;
|
||||
public ICompositeActivityBuilder WorkflowBuilder { get; set; } = default!;
|
||||
public string ActivityId { get; set; } = default!;
|
||||
public string? Name { get; set; }
|
||||
|
|
@ -47,27 +48,27 @@ namespace Elsa.Builders
|
|||
public string? Source => SourceFile != null && LineNumber != default ? $"{Path.GetFileName(SourceFile)}:{LineNumber}" : default;
|
||||
|
||||
public IActivityBuilder Add<T>(
|
||||
string activityTypeName,
|
||||
Action<ISetupActivity<T>>? setup = default,
|
||||
string? activityType = default,
|
||||
[CallerLineNumber] int lineNumber = default,
|
||||
[CallerFilePath] string? sourceFile = default)
|
||||
where T : class, IActivity =>
|
||||
WorkflowBuilder.Add(setup, null, activityType, lineNumber, sourceFile);
|
||||
WorkflowBuilder.Add(activityTypeName, setup, null, lineNumber, sourceFile);
|
||||
|
||||
public IOutcomeBuilder When(string outcome) => new OutcomeBuilder(WorkflowBuilder, this, outcome);
|
||||
|
||||
public virtual IActivityBuilder Then<T>(
|
||||
string activityTypeName,
|
||||
Action<ISetupActivity<T>>? setup = null,
|
||||
Action<IActivityBuilder>? branch = null,
|
||||
string? activityType = default,
|
||||
[CallerLineNumber] int lineNumber = default,
|
||||
[CallerFilePath] string? sourceFile = default)
|
||||
where T : class, IActivity =>
|
||||
When(OutcomeNames.Done).Then(setup, branch, act, lineNumber, sourceFile);
|
||||
When(OutcomeNames.Done).Then(activityTypeName, setup, branch, lineNumber, sourceFile);
|
||||
|
||||
public virtual IActivityBuilder Then<T>(Action<IActivityBuilder>? branch = null, string? activityTypeName = default, [CallerLineNumber] int lineNumber = default, [CallerFilePath] string? sourceFile = default)
|
||||
public virtual IActivityBuilder Then<T>(string activityTypeName, Action<IActivityBuilder>? branch = null, [CallerLineNumber] int lineNumber = default, [CallerFilePath] string? sourceFile = default)
|
||||
where T : class, IActivity =>
|
||||
When(OutcomeNames.Done).Then<T>(branch, lineNumber, sourceFile);
|
||||
When(OutcomeNames.Done).Then<T>(activityTypeName, branch, lineNumber, sourceFile);
|
||||
|
||||
public virtual IActivityBuilder Then(IActivityBuilder targetActivity)
|
||||
{
|
||||
|
|
@ -75,7 +76,7 @@ namespace Elsa.Builders
|
|||
return this;
|
||||
}
|
||||
|
||||
public virtual IConnectionBuilder Then(string activityName) =>
|
||||
public virtual IConnectionBuilder ThenNamed(string activityName) =>
|
||||
WorkflowBuilder.Connect(
|
||||
() => this,
|
||||
() => WorkflowBuilder.Activities.First(x => x.Name == activityName));
|
||||
|
|
|
|||
|
|
@ -1,65 +1,18 @@
|
|||
using System;
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading.Tasks;
|
||||
using Elsa.Activities.Primitives;
|
||||
using Elsa.ActivityResults;
|
||||
using Elsa.Services.Models;
|
||||
using Elsa.Services;
|
||||
|
||||
// ReSharper disable ExplicitCallerInfoArgument
|
||||
namespace Elsa.Builders
|
||||
{
|
||||
public static class ActivityBuilderExtensions
|
||||
{
|
||||
public static IActivityBuilder Then(
|
||||
this IBuilder builder,
|
||||
Func<ActivityExecutionContext, ValueTask<IActivityExecutionResult>> activity,
|
||||
public static IActivityBuilder Add<T>(
|
||||
this IActivityBuilder activityBuilder,
|
||||
Action<ISetupActivity<T>>? setup = default,
|
||||
[CallerLineNumber] int lineNumber = default,
|
||||
[CallerFilePath] string? sourceFile = default) =>
|
||||
builder.Then<Inline>(inline => inline.Set(x => x.Function, RunInline(activity)), null, lineNumber, sourceFile);
|
||||
|
||||
public static IActivityBuilder
|
||||
Then(this IBuilder builder, Func<ActivityExecutionContext, ValueTask> activity, [CallerLineNumber] int lineNumber = default, [CallerFilePath] string? sourceFile = default) =>
|
||||
builder.Then<Inline>(inline => inline.Set(x => x.Function, RunInline(activity)), null, lineNumber, sourceFile);
|
||||
|
||||
public static IActivityBuilder Then(this IBuilder builder, Action<ActivityExecutionContext> activity, [CallerLineNumber] int lineNumber = default, [CallerFilePath] string? sourceFile = default) =>
|
||||
builder.Then<Inline>(inline => inline.Set(x => x.Function, RunInline(activity)), null, lineNumber, sourceFile);
|
||||
|
||||
public static IActivityBuilder Then(this IBuilder builder, Action activity) =>
|
||||
builder.Then<Inline>(inline => inline.Set(x => x.Function, RunInline(activity)));
|
||||
|
||||
private static Func<ActivityExecutionContext, ValueTask<IActivityExecutionResult>> RunInline(
|
||||
Func<ActivityExecutionContext, ValueTask<IActivityExecutionResult>> activity) =>
|
||||
async context => await activity(context);
|
||||
|
||||
private static Func<ActivityExecutionContext, ValueTask<IActivityExecutionResult>> RunInline(
|
||||
Func<ActivityExecutionContext, ValueTask> activity) =>
|
||||
async context =>
|
||||
{
|
||||
await activity(context);
|
||||
return new OutcomeResult();
|
||||
};
|
||||
|
||||
private static Func<ActivityExecutionContext, ValueTask<IActivityExecutionResult>> RunInline(
|
||||
Action<ActivityExecutionContext> activity) =>
|
||||
context =>
|
||||
{
|
||||
activity(context);
|
||||
return new ValueTask<IActivityExecutionResult>(new OutcomeResult());
|
||||
};
|
||||
|
||||
private static Func<ActivityExecutionContext, ValueTask<IActivityExecutionResult>> RunInline(
|
||||
Func<ActivityExecutionContext, Task> activity) =>
|
||||
async context =>
|
||||
{
|
||||
await activity(context);
|
||||
return new OutcomeResult();
|
||||
};
|
||||
|
||||
private static Func<ActivityExecutionContext, ValueTask<IActivityExecutionResult>> RunInline(Action activity) =>
|
||||
context =>
|
||||
{
|
||||
activity();
|
||||
return new ValueTask<IActivityExecutionResult>(new OutcomeResult());
|
||||
};
|
||||
[CallerFilePath] string? sourceFile = default)
|
||||
where T : class, IActivity =>
|
||||
activityBuilder.Add(typeof(T).Name, setup, lineNumber, sourceFile);
|
||||
}
|
||||
}
|
||||
42
src/core/Elsa.Core/Builders/BuilderExtensions.cs
Normal file
42
src/core/Elsa.Core/Builders/BuilderExtensions.cs
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Elsa.Services;
|
||||
|
||||
// ReSharper disable ExplicitCallerInfoArgument
|
||||
namespace Elsa.Builders
|
||||
{
|
||||
public static class BuilderExtensions
|
||||
{
|
||||
public static IActivityBuilder Then<T>(
|
||||
this IBuilder builder,
|
||||
Action<ISetupActivity<T>>? setup,
|
||||
Action<IActivityBuilder>? branch = default,
|
||||
[CallerLineNumber] int lineNumber = default,
|
||||
[CallerFilePath] string? sourceFile = default)
|
||||
where T : class, IActivity => builder.Then<T>(typeof(T).Name, setup, branch, lineNumber, sourceFile);
|
||||
|
||||
public static IActivityBuilder ThenTypeNamed(
|
||||
this IBuilder builder,
|
||||
string activityTypeName,
|
||||
Action<ISetupActivity<IActivity>>? setup,
|
||||
Action<IActivityBuilder>? branch = default,
|
||||
[CallerLineNumber] int lineNumber = default,
|
||||
[CallerFilePath] string? sourceFile = default)
|
||||
=> builder.Then(activityTypeName, setup, branch, lineNumber, sourceFile);
|
||||
|
||||
public static IActivityBuilder Then<T>(
|
||||
this IBuilder builder,
|
||||
Action<IActivityBuilder>? branch = default,
|
||||
[CallerLineNumber] int lineNumber = default,
|
||||
[CallerFilePath] string? sourceFile = default) where T : class, IActivity =>
|
||||
builder.Then<T>(typeof(T).Name, branch, lineNumber, sourceFile);
|
||||
|
||||
public static IActivityBuilder ThenTypeNamed(
|
||||
this IBuilder builder,
|
||||
string activityTypeName,
|
||||
Action<IActivityBuilder>? branch = default,
|
||||
[CallerLineNumber] int lineNumber = default,
|
||||
[CallerFilePath] string? sourceFile = default) =>
|
||||
builder.Then<IActivity>(activityTypeName, branch, lineNumber, sourceFile);
|
||||
}
|
||||
}
|
||||
|
|
@ -14,12 +14,11 @@ namespace Elsa.Builders
|
|||
public class CompositeActivityBuilder : ActivityBuilder, ICompositeActivityBuilder
|
||||
{
|
||||
private readonly Func<ICompositeActivityBuilder> _compositeActivityBuilderFactory;
|
||||
private readonly IGetsStartActivitiesForCompositeActivityBlueprint startingActivitiesProvider;
|
||||
private readonly IGetsStartActivitiesForCompositeActivityBlueprint _startingActivitiesProvider;
|
||||
|
||||
public CompositeActivityBuilder(IServiceProvider serviceProvider, IGetsStartActivitiesForCompositeActivityBlueprint startingActivitiesProvider)
|
||||
{
|
||||
this.startingActivitiesProvider = startingActivitiesProvider ?? throw new ArgumentNullException(nameof(startingActivitiesProvider));
|
||||
|
||||
_startingActivitiesProvider = startingActivitiesProvider ?? throw new ArgumentNullException(nameof(startingActivitiesProvider));
|
||||
ServiceProvider = serviceProvider;
|
||||
ActivityBuilders = new List<IActivityBuilder>();
|
||||
ConnectionBuilders = new List<IConnectionBuilder>();
|
||||
|
|
@ -40,7 +39,7 @@ namespace Elsa.Builders
|
|||
|
||||
public IActivityBuilder New(
|
||||
Type activityType,
|
||||
string? activityTypeName = default,
|
||||
string activityTypeName,
|
||||
IDictionary<string, IActivityPropertyValueProvider>? propertyValueProviders = default,
|
||||
[CallerLineNumber] int lineNumber = default,
|
||||
[CallerFilePath] string? sourceFile = default)
|
||||
|
|
@ -50,7 +49,7 @@ namespace Elsa.Builders
|
|||
}
|
||||
|
||||
public IActivityBuilder New<T>(
|
||||
string? activityTypeName = default,
|
||||
string activityTypeName,
|
||||
IDictionary<string, IActivityPropertyValueProvider>? propertyValueProviders = default,
|
||||
[CallerLineNumber] int lineNumber = default,
|
||||
[CallerFilePath] string? sourceFile = default)
|
||||
|
|
@ -58,8 +57,8 @@ namespace Elsa.Builders
|
|||
New(typeof(T), activityTypeName, propertyValueProviders, lineNumber, sourceFile);
|
||||
|
||||
public IActivityBuilder New<T>(
|
||||
string activityTypeName,
|
||||
Action<ISetupActivity<T>>? setup = default,
|
||||
string? activityTypeName = default,
|
||||
[CallerLineNumber] int lineNumber = default,
|
||||
[CallerFilePath] string? sourceFile = default) where T : class, IActivity
|
||||
{
|
||||
|
|
@ -74,62 +73,58 @@ namespace Elsa.Builders
|
|||
}
|
||||
|
||||
public IActivityBuilder StartWith<T>(
|
||||
string activityTypeName,
|
||||
Action<ISetupActivity<T>>? setup = default,
|
||||
Action<IActivityBuilder>? branch = default,
|
||||
string? activityTypeName = default,
|
||||
[CallerLineNumber] int lineNumber = default,
|
||||
[CallerFilePath] string? sourceFile = default) where T : class, IActivity
|
||||
{
|
||||
var activityBuilder = New(setup, activityTypeName, lineNumber, sourceFile);
|
||||
var activityBuilder = New(activityTypeName, setup, lineNumber, sourceFile);
|
||||
return Add(activityBuilder, branch);
|
||||
}
|
||||
|
||||
public IActivityBuilder StartWith<T>(Action<IActivityBuilder>? branch = default, string? activityTypeName = default, [CallerLineNumber] int lineNumber = default, [CallerFilePath] string? sourceFile = default)
|
||||
public IActivityBuilder StartWith<T>(string activityTypeName, Action<IActivityBuilder>? branch = default, [CallerLineNumber] int lineNumber = default, [CallerFilePath] string? sourceFile = default)
|
||||
where T : class, IActivity =>
|
||||
Add<T>(branch, activityTypeName, null, lineNumber, sourceFile);
|
||||
Add<T>(activityTypeName, branch, null, lineNumber, sourceFile);
|
||||
|
||||
public IActivityBuilder Add<T>(
|
||||
string activityTypeName,
|
||||
Action<ISetupActivity<T>>? setup = default,
|
||||
Action<IActivityBuilder>? branch = default,
|
||||
string? activityType = default,
|
||||
[CallerLineNumber] int lineNumber = default,
|
||||
[CallerFilePath] string? sourceFile = default) where T : class, IActivity
|
||||
{
|
||||
var activityBuilder = New(setup, activityType, lineNumber, sourceFile);
|
||||
var activityBuilder = New(activityTypeName, setup, lineNumber, sourceFile);
|
||||
return Add(activityBuilder, branch);
|
||||
}
|
||||
|
||||
public IActivityBuilder Add<T>(
|
||||
string activityTypeName,
|
||||
Action<IActivityBuilder>? branch = default,
|
||||
string? activityType = default,
|
||||
IDictionary<string, IActivityPropertyValueProvider>? propertyValueProviders = default,
|
||||
[CallerLineNumber] int lineNumber = default,
|
||||
[CallerFilePath] string? sourceFile = default)
|
||||
where T : class, IActivity
|
||||
{
|
||||
var activityBuilder = new ActivityBuilder(typeof(T), activityType, this, propertyValueProviders, lineNumber, sourceFile);
|
||||
var activityBuilder = new ActivityBuilder( typeof(T), activityTypeName, this, propertyValueProviders, lineNumber, sourceFile);
|
||||
return Add(activityBuilder, branch);
|
||||
}
|
||||
|
||||
public IActivityBuilder Add(IActivityBuilder activityBuilder, Action<IActivityBuilder>? branch = default)
|
||||
public IActivityBuilder Add(
|
||||
IActivityBuilder activityBuilder,
|
||||
Action<IActivityBuilder>? branch = default)
|
||||
{
|
||||
branch?.Invoke(activityBuilder);
|
||||
ActivityBuilders.Add(activityBuilder);
|
||||
return activityBuilder;
|
||||
}
|
||||
|
||||
public override IActivityBuilder Then<T>(
|
||||
Action<ISetupActivity<T>>? setup = null,
|
||||
Action<IActivityBuilder>? branch = null,
|
||||
string? activityTypeName = default,
|
||||
[CallerLineNumber] int lineNumber = default,
|
||||
[CallerFilePath] string? sourceFile = default) =>
|
||||
StartWith(setup, branch, activityTypeName, lineNumber, sourceFile);
|
||||
public override IActivityBuilder Then<T>(string activityTypeName, Action<ISetupActivity<T>>? setup = null, Action<IActivityBuilder>? branch = null, [CallerLineNumber] int lineNumber = default, [CallerFilePath] string? sourceFile = default) =>
|
||||
StartWith(activityTypeName,setup, branch, lineNumber, sourceFile);
|
||||
|
||||
public override IActivityBuilder Then(IActivityBuilder targetActivity) => Add(targetActivity);
|
||||
|
||||
public override IActivityBuilder Then<T>(Action<IActivityBuilder>? branch = null, string? activityTypeName = default, [CallerLineNumber] int lineNumber = default, [CallerFilePath] string? sourceFile = default)
|
||||
where T : class, IActivity => StartWith<T>(branch, activityTypeName, lineNumber, sourceFile);
|
||||
public override IActivityBuilder Then<T>(string activityTypeName, Action<IActivityBuilder>? branch = null, [CallerLineNumber] int lineNumber = default, [CallerFilePath] string? sourceFile = default) => StartWith<T>(activityTypeName, branch, lineNumber, sourceFile);
|
||||
|
||||
public IConnectionBuilder Connect(
|
||||
IActivityBuilder source,
|
||||
|
|
@ -215,18 +210,18 @@ namespace Elsa.Builders
|
|||
compositeActivityBlueprint.ActivityPropertyProviders = compositeActivityBlueprint.ActivityPropertyProviders;
|
||||
|
||||
// Connect the composite activity to its starting activities.
|
||||
var startActivities = startingActivitiesProvider.GetStartActivities(compositeActivityBlueprint).ToList();
|
||||
var startActivities = _startingActivitiesProvider.GetStartActivities(compositeActivityBlueprint).ToList();
|
||||
connections.AddRange(startActivities.Select(x => new Connection(compositeActivityBlueprint, x, CompositeActivity.Enter)));
|
||||
}
|
||||
}
|
||||
|
||||
private IActivityBlueprint BuildActivityBlueprint(IActivityBuilder builder, ICompositeActivityBlueprint parent)
|
||||
private static IActivityBlueprint BuildActivityBlueprint(IActivityBuilder builder, ICompositeActivityBlueprint parent)
|
||||
{
|
||||
var isComposite = typeof(CompositeActivity).IsAssignableFrom(builder.ActivityType);
|
||||
return isComposite
|
||||
? new CompositeActivityBlueprint(builder.ActivityId, parent, builder.Name, builder.DisplayName, builder.Description, builder.ActivityType.Name, builder.PersistWorkflowEnabled, builder.LoadWorkflowContextEnabled,
|
||||
? new CompositeActivityBlueprint(builder.ActivityId, parent, builder.Name, builder.DisplayName, builder.Description, builder.ActivityTypeName, builder.PersistWorkflowEnabled, builder.LoadWorkflowContextEnabled,
|
||||
builder.SaveWorkflowContextEnabled, builder.PersistOutputEnabled, builder.Source)
|
||||
: new ActivityBlueprint(builder.ActivityId, parent, builder.Name, builder.DisplayName, builder.Description, builder.ActivityType.Name, builder.PersistWorkflowEnabled, builder.LoadWorkflowContextEnabled,
|
||||
: new ActivityBlueprint(builder.ActivityId, parent, builder.Name, builder.DisplayName, builder.Description, builder.ActivityTypeName, builder.PersistWorkflowEnabled, builder.LoadWorkflowContextEnabled,
|
||||
builder.SaveWorkflowContextEnabled, builder.PersistOutputEnabled, builder.Source);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,72 +1,52 @@
|
|||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading.Tasks;
|
||||
using Elsa.Activities.Primitives;
|
||||
using Elsa.ActivityResults;
|
||||
using Elsa.Services.Models;
|
||||
using Elsa.Services;
|
||||
|
||||
// ReSharper disable ExplicitCallerInfoArgument
|
||||
namespace Elsa.Builders
|
||||
{
|
||||
public static class CompositeActivityBuilderExtensions
|
||||
{
|
||||
public static IActivityBuilder StartWith(this ICompositeActivityBuilder builder, Action action) => builder.StartWith<Inline>(inline => inline.Set(x => x.Function, RunInline(action)));
|
||||
|
||||
public static IActivityBuilder
|
||||
StartWith(this ICompositeActivityBuilder builder, Action<ActivityExecutionContext> action, [CallerLineNumber] int lineNumber = default, [CallerFilePath] string? sourceFile = default) =>
|
||||
builder.StartWith<Inline>(inline => inline.Set(x => x.Function, RunInline(action)), null, lineNumber, sourceFile);
|
||||
|
||||
public static IActivityBuilder StartWith(
|
||||
this ICompositeActivityBuilder builder,
|
||||
Func<ActivityExecutionContext, ValueTask> action,
|
||||
public static IActivityBuilder New<T>(
|
||||
this ICompositeActivityBuilder compositeActivityBuilder,
|
||||
IDictionary<string, IActivityPropertyValueProvider>? propertyValueProviders = default,
|
||||
[CallerLineNumber] int lineNumber = default,
|
||||
[CallerFilePath] string? sourceFile = default) =>
|
||||
builder.StartWith<Inline>(inline => inline.Set(x => x.Function, RunInline(action)), null, lineNumber, sourceFile);
|
||||
[CallerFilePath] string? sourceFile = default)
|
||||
where T : class, IActivity => compositeActivityBuilder.New<T>(typeof(T).Name, propertyValueProviders, lineNumber, sourceFile);
|
||||
|
||||
public static IActivityBuilder StartWith(
|
||||
this ICompositeActivityBuilder builder,
|
||||
Func<ActivityExecutionContext, ValueTask<IActivityExecutionResult>> action,
|
||||
public static IActivityBuilder New<T>(
|
||||
this ICompositeActivityBuilder compositeActivityBuilder,
|
||||
Action<ISetupActivity<T>>? setup,
|
||||
[CallerLineNumber] int lineNumber = default,
|
||||
[CallerFilePath] string? sourceFile = default) =>
|
||||
builder.StartWith<Inline>(inline => inline.Set(x => x.Function, RunInline(action)), null, lineNumber, sourceFile);
|
||||
[CallerFilePath] string? sourceFile = default) where T : class, IActivity => compositeActivityBuilder.New<T>(typeof(T).Name, setup, lineNumber, sourceFile);
|
||||
|
||||
public static IActivityBuilder SetVariable(this ICompositeActivityBuilder builder, string variableName, object? value, [CallerLineNumber] int lineNumber = default, [CallerFilePath] string? sourceFile = default) =>
|
||||
builder.StartWith<SetVariable>(
|
||||
activity =>
|
||||
{
|
||||
activity.Set(x => x.VariableName, _ => variableName);
|
||||
activity.Set(x => x.Value, _ => value);
|
||||
}, null, lineNumber, sourceFile);
|
||||
|
||||
public static IActivityBuilder SetVariable(
|
||||
this ICompositeActivityBuilder builder,
|
||||
string variableName,
|
||||
Func<object?> value,
|
||||
public static IActivityBuilder StartWith<T>(
|
||||
this ICompositeActivityBuilder compositeActivityBuilder,
|
||||
Action<ISetupActivity<T>>? setup,
|
||||
Action<IActivityBuilder>? branch = default,
|
||||
[CallerLineNumber] int lineNumber = default,
|
||||
[CallerFilePath] string? sourceFile = default) =>
|
||||
builder.SetVariable(variableName, value(), lineNumber, sourceFile);
|
||||
[CallerFilePath] string? sourceFile = default) where T : class, IActivity => compositeActivityBuilder.StartWith(typeof(T).Name, setup, branch, lineNumber, sourceFile);
|
||||
|
||||
private static Func<ActivityExecutionContext, ValueTask<IActivityExecutionResult>> RunInline(Action action) =>
|
||||
_ =>
|
||||
{
|
||||
action();
|
||||
return new ValueTask<IActivityExecutionResult>(new DoneResult());
|
||||
};
|
||||
public static IActivityBuilder StartWith<T>(
|
||||
this ICompositeActivityBuilder compositeActivityBuilder,
|
||||
Action<IActivityBuilder>? branch = default,
|
||||
[CallerLineNumber] int lineNumber = default,
|
||||
[CallerFilePath] string? sourceFile = default) where T : class, IActivity => compositeActivityBuilder.StartWith<T>(typeof(T).Name, branch, lineNumber, sourceFile);
|
||||
|
||||
private static Func<ActivityExecutionContext, ValueTask<IActivityExecutionResult>> RunInline(Action<ActivityExecutionContext> action) =>
|
||||
context =>
|
||||
{
|
||||
action(context);
|
||||
return new ValueTask<IActivityExecutionResult>(new DoneResult());
|
||||
};
|
||||
public static IActivityBuilder Add<T>(
|
||||
this ICompositeActivityBuilder compositeActivityBuilder,
|
||||
Action<ISetupActivity<T>>? setup,
|
||||
Action<IActivityBuilder>? branch = default,
|
||||
[CallerLineNumber] int lineNumber = default,
|
||||
[CallerFilePath] string? sourceFile = default) where T : class, IActivity => compositeActivityBuilder.Add(typeof(T).Name, setup, branch, lineNumber, sourceFile);
|
||||
|
||||
private static Func<ActivityExecutionContext, ValueTask<IActivityExecutionResult>> RunInline(Func<ActivityExecutionContext, ValueTask> action) =>
|
||||
async context =>
|
||||
{
|
||||
await action(context);
|
||||
return new DoneResult();
|
||||
};
|
||||
|
||||
private static Func<ActivityExecutionContext, ValueTask<IActivityExecutionResult>> RunInline(Func<ActivityExecutionContext, ValueTask<IActivityExecutionResult>> action) => async context => await action(context);
|
||||
public static IActivityBuilder Add<T>(
|
||||
this ICompositeActivityBuilder compositeActivityBuilder,
|
||||
Action<IActivityBuilder>? branch = default,
|
||||
IDictionary<string, IActivityPropertyValueProvider>? propertyValueProviders = default,
|
||||
[CallerLineNumber] int lineNumber = default,
|
||||
[CallerFilePath] string? sourceFile = default)
|
||||
where T : class, IActivity => compositeActivityBuilder.Add<T>(typeof(T).Name, branch, propertyValueProviders, lineNumber, sourceFile);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading.Tasks;
|
||||
using Elsa.Activities.Primitives;
|
||||
using Elsa.ActivityResults;
|
||||
using Elsa.Services.Models;
|
||||
|
||||
// ReSharper disable ExplicitCallerInfoArgument
|
||||
namespace Elsa.Builders
|
||||
{
|
||||
public static class InlineActivityBuilderExtensions
|
||||
{
|
||||
public static IActivityBuilder Then(
|
||||
this IBuilder builder,
|
||||
Func<ActivityExecutionContext, ValueTask<IActivityExecutionResult>> activity,
|
||||
[CallerLineNumber] int lineNumber = default,
|
||||
[CallerFilePath] string? sourceFile = default) =>
|
||||
builder.Then<Inline>(inline => inline.Set(x => x.Function, RunInline(activity)), null, lineNumber, sourceFile);
|
||||
|
||||
public static IActivityBuilder
|
||||
Then(this IBuilder builder, Func<ActivityExecutionContext, ValueTask> activity, [CallerLineNumber] int lineNumber = default, [CallerFilePath] string? sourceFile = default) =>
|
||||
builder.Then<Inline>(inline => inline.Set(x => x.Function, RunInline(activity)), null, lineNumber, sourceFile);
|
||||
|
||||
public static IActivityBuilder Then(this IBuilder builder, Action<ActivityExecutionContext> activity, [CallerLineNumber] int lineNumber = default, [CallerFilePath] string? sourceFile = default) =>
|
||||
builder.Then<Inline>(inline => inline.Set(x => x.Function, RunInline(activity)), null, lineNumber, sourceFile);
|
||||
|
||||
public static IActivityBuilder Then(this IBuilder builder, Action activity) =>
|
||||
builder.Then<Inline>(inline => inline.Set(x => x.Function, RunInline(activity)));
|
||||
|
||||
private static Func<ActivityExecutionContext, ValueTask<IActivityExecutionResult>> RunInline(
|
||||
Func<ActivityExecutionContext, ValueTask<IActivityExecutionResult>> activity) =>
|
||||
async context => await activity(context);
|
||||
|
||||
private static Func<ActivityExecutionContext, ValueTask<IActivityExecutionResult>> RunInline(
|
||||
Func<ActivityExecutionContext, ValueTask> activity) =>
|
||||
async context =>
|
||||
{
|
||||
await activity(context);
|
||||
return new OutcomeResult();
|
||||
};
|
||||
|
||||
private static Func<ActivityExecutionContext, ValueTask<IActivityExecutionResult>> RunInline(
|
||||
Action<ActivityExecutionContext> activity) =>
|
||||
context =>
|
||||
{
|
||||
activity(context);
|
||||
return new ValueTask<IActivityExecutionResult>(new OutcomeResult());
|
||||
};
|
||||
|
||||
private static Func<ActivityExecutionContext, ValueTask<IActivityExecutionResult>> RunInline(
|
||||
Func<ActivityExecutionContext, Task> activity) =>
|
||||
async context =>
|
||||
{
|
||||
await activity(context);
|
||||
return new OutcomeResult();
|
||||
};
|
||||
|
||||
private static Func<ActivityExecutionContext, ValueTask<IActivityExecutionResult>> RunInline(Action activity) =>
|
||||
context =>
|
||||
{
|
||||
activity();
|
||||
return new ValueTask<IActivityExecutionResult>(new OutcomeResult());
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading.Tasks;
|
||||
using Elsa.Activities.Primitives;
|
||||
using Elsa.ActivityResults;
|
||||
using Elsa.Services.Models;
|
||||
|
||||
// ReSharper disable ExplicitCallerInfoArgument
|
||||
namespace Elsa.Builders
|
||||
{
|
||||
public static class InlineCompositeActivityBuilderExtensions
|
||||
{
|
||||
public static IActivityBuilder StartWith(this ICompositeActivityBuilder builder, Action action) => builder.StartWith<Inline>(inline => inline.Set(x => x.Function, RunInline(action)));
|
||||
|
||||
public static IActivityBuilder
|
||||
StartWith(this ICompositeActivityBuilder builder, Action<ActivityExecutionContext> action, [CallerLineNumber] int lineNumber = default, [CallerFilePath] string? sourceFile = default) =>
|
||||
builder.StartWith<Inline>(inline => inline.Set(x => x.Function, RunInline(action)), null, lineNumber, sourceFile);
|
||||
|
||||
public static IActivityBuilder StartWith(
|
||||
this ICompositeActivityBuilder builder,
|
||||
Func<ActivityExecutionContext, ValueTask> action,
|
||||
[CallerLineNumber] int lineNumber = default,
|
||||
[CallerFilePath] string? sourceFile = default) =>
|
||||
builder.StartWith<Inline>(inline => inline.Set(x => x.Function, RunInline(action)), null, lineNumber, sourceFile);
|
||||
|
||||
public static IActivityBuilder StartWith(
|
||||
this ICompositeActivityBuilder builder,
|
||||
Func<ActivityExecutionContext, ValueTask<IActivityExecutionResult>> action,
|
||||
[CallerLineNumber] int lineNumber = default,
|
||||
[CallerFilePath] string? sourceFile = default) =>
|
||||
builder.StartWith<Inline>(inline => inline.Set(x => x.Function, RunInline(action)), null, lineNumber, sourceFile);
|
||||
|
||||
private static Func<ActivityExecutionContext, ValueTask<IActivityExecutionResult>> RunInline(Action action) =>
|
||||
_ =>
|
||||
{
|
||||
action();
|
||||
return new ValueTask<IActivityExecutionResult>(new DoneResult());
|
||||
};
|
||||
|
||||
private static Func<ActivityExecutionContext, ValueTask<IActivityExecutionResult>> RunInline(Action<ActivityExecutionContext> action) =>
|
||||
context =>
|
||||
{
|
||||
action(context);
|
||||
return new ValueTask<IActivityExecutionResult>(new DoneResult());
|
||||
};
|
||||
|
||||
private static Func<ActivityExecutionContext, ValueTask<IActivityExecutionResult>> RunInline(Func<ActivityExecutionContext, ValueTask> action) =>
|
||||
async context =>
|
||||
{
|
||||
await action(context);
|
||||
return new DoneResult();
|
||||
};
|
||||
|
||||
private static Func<ActivityExecutionContext, ValueTask<IActivityExecutionResult>> RunInline(Func<ActivityExecutionContext, ValueTask<IActivityExecutionResult>> action) => async context => await action(context);
|
||||
}
|
||||
}
|
||||
|
|
@ -21,21 +21,21 @@ namespace Elsa.Builders
|
|||
public string Outcome { get; }
|
||||
|
||||
public IActivityBuilder Then<T>(
|
||||
string activityTypeName,
|
||||
Action<ISetupActivity<T>>? setup = default,
|
||||
Action<IActivityBuilder>? branch = default,
|
||||
string? activityType = default,
|
||||
[CallerLineNumber] int lineNumber = default,
|
||||
[CallerFilePath] string? sourceFile = default) where T : class, IActivity
|
||||
{
|
||||
var activityBuilder = WorkflowBuilder.Add(setup, default, activityType, lineNumber, sourceFile);
|
||||
var activityBuilder = WorkflowBuilder.Add(activityTypeName, setup, null, lineNumber, sourceFile);
|
||||
Then(activityBuilder, branch);
|
||||
return activityBuilder;
|
||||
}
|
||||
|
||||
public IActivityBuilder Then<T>(Action<IActivityBuilder>? branch = default, [CallerLineNumber] int lineNumber = default, [CallerFilePath] string? sourceFile = default)
|
||||
public IActivityBuilder Then<T>(string activityTypeName, Action<IActivityBuilder>? branch = default, [CallerLineNumber] int lineNumber = default, [CallerFilePath] string? sourceFile = default)
|
||||
where T : class, IActivity
|
||||
{
|
||||
var activityBuilder = WorkflowBuilder.Add<T>(branch, null, lineNumber, sourceFile);
|
||||
var activityBuilder = WorkflowBuilder.Add<T>(activityTypeName, branch, null, lineNumber, sourceFile);
|
||||
Then(activityBuilder);
|
||||
return activityBuilder;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Elsa.Activities.Primitives;
|
||||
|
||||
// ReSharper disable ExplicitCallerInfoArgument
|
||||
namespace Elsa.Builders
|
||||
{
|
||||
public static class VariableCompositeActivityBuilderExtensions
|
||||
{
|
||||
public static IActivityBuilder SetVariable(this ICompositeActivityBuilder builder, string variableName, object? value, [CallerLineNumber] int lineNumber = default, [CallerFilePath] string? sourceFile = default) =>
|
||||
builder.StartWith<SetVariable>(
|
||||
activity =>
|
||||
{
|
||||
activity.Set(x => x.VariableName, _ => variableName);
|
||||
activity.Set(x => x.Value, _ => value);
|
||||
}, null, lineNumber, sourceFile);
|
||||
|
||||
public static IActivityBuilder SetVariable(
|
||||
this ICompositeActivityBuilder builder,
|
||||
string variableName,
|
||||
Func<object?> value,
|
||||
[CallerLineNumber] int lineNumber = default,
|
||||
[CallerFilePath] string? sourceFile = default) =>
|
||||
builder.SetVariable(variableName, value(), lineNumber, sourceFile);
|
||||
}
|
||||
}
|
||||
|
|
@ -17,6 +17,7 @@ namespace Elsa.Builders
|
|||
CustomAttributes = new Variables();
|
||||
ActivityId = idGenerator.Generate();
|
||||
ActivityType = typeof(Workflow);
|
||||
ActivityTypeName = nameof(Workflow);
|
||||
WorkflowBuilder = this;
|
||||
PropertyValueProviders = new Dictionary<string, IActivityPropertyValueProvider>();
|
||||
PersistenceBehavior = WorkflowPersistenceBehavior.WorkflowBurst;
|
||||
|
|
|
|||
|
|
@ -35,13 +35,13 @@ namespace Elsa.Samples.ForkJoinTimerAndSignalHttp.Workflows
|
|||
.When("Timer")
|
||||
.Timer(_timeOut)
|
||||
.SetVariable("CompletedVia", "Timer")
|
||||
.Then("Join");
|
||||
.ThenNamed("Join");
|
||||
|
||||
fork
|
||||
.When("Signal")
|
||||
.SignalReceived("hurry")
|
||||
.SetVariable("CompletedVia", "Signal")
|
||||
.Then("Join");
|
||||
.ThenNamed("Join");
|
||||
})
|
||||
.Add<Join>(x => x.WithMode(Join.JoinMode.WaitAny)).WithName("Join")
|
||||
.WriteLine(context => $"Demo {GetCorrelationId(context)} completed successfully via {context.GetVariable<string>("CompletedVia")}!");
|
||||
|
|
|
|||
|
|
@ -17,17 +17,17 @@ namespace Elsa.Samples.UserTaskConsole
|
|||
userTask
|
||||
.When("Accept")
|
||||
.WriteLine("Great! Your work has been accepted.")
|
||||
.Then("Exit");
|
||||
.ThenNamed("Exit");
|
||||
|
||||
userTask
|
||||
.When("Reject")
|
||||
.WriteLine("Sorry! Your work has been rejected.")
|
||||
.Then("Exit");
|
||||
.ThenNamed("Exit");
|
||||
|
||||
userTask
|
||||
.When("Needs Work")
|
||||
.WriteLine("So close! Your work needs a little bit more work.")
|
||||
.Then("Exit");
|
||||
.ThenNamed("Exit");
|
||||
}
|
||||
)
|
||||
.WriteLine("Workflow finished.").WithName("Exit");
|
||||
|
|
|
|||
|
|
@ -19,20 +19,20 @@ namespace Elsa.Samples.Temporal.Activities
|
|||
.While(true, @while => @while
|
||||
.Timer(Duration.FromSeconds(1))
|
||||
.WriteLine("Timer A went off"))
|
||||
.Then("Join1");
|
||||
.ThenNamed("Join1");
|
||||
|
||||
fork
|
||||
.When("B")
|
||||
.While(true, @while => @while
|
||||
.Timer(Duration.FromSeconds(5))
|
||||
.WriteLine("Timer B went off"))
|
||||
.Then("Join1");
|
||||
.ThenNamed("Join1");
|
||||
|
||||
fork
|
||||
.When("C")
|
||||
.Timer(Duration.FromSeconds(6))
|
||||
.WriteLine("Timer C went off")
|
||||
.Then("Join1");
|
||||
.ThenNamed("Join1");
|
||||
})
|
||||
.Add<Join>(join => join.WithMode(Join.JoinMode.WaitAny)).WithName("Join1")
|
||||
.WriteLine("Container 1 Joined!")
|
||||
|
|
|
|||
|
|
@ -18,14 +18,14 @@ namespace Elsa.Samples.Temporal.Activities
|
|||
.When("D")
|
||||
.Timer(Duration.FromSeconds(20))
|
||||
.WriteLine("Timer D went off. Exiting fork")
|
||||
.Then("Join2");
|
||||
.ThenNamed("Join2");
|
||||
|
||||
fork
|
||||
.When("E")
|
||||
.While(true, iterate => iterate
|
||||
.Timer(Duration.FromSeconds(5))
|
||||
.WriteLine("Timer E went off. Looping."))
|
||||
.Then("Join2");
|
||||
.ThenNamed("Join2");
|
||||
})
|
||||
.Add<Join>(join => join.WithMode(Join.JoinMode.WaitAny)).WithName("Join2")
|
||||
.WriteLine("Container 2 Joined!")
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ namespace Elsa.Samples.Temporal.Workflows
|
|||
.When("A")
|
||||
.Timer(Duration.FromSeconds(5)).WithId("timer-a")
|
||||
.WriteLine("Timer A went off. Exiting fork").WithId("write-line-a")
|
||||
.Then("Join2");
|
||||
.ThenNamed("Join2");
|
||||
|
||||
fork
|
||||
.When("B")
|
||||
|
|
@ -29,7 +29,7 @@ namespace Elsa.Samples.Temporal.Workflows
|
|||
.Timer(Duration.FromSeconds(1)).WithId("timer-b")
|
||||
.WriteLine("Timer B went off. Looping.").WithId("write-line-b"))
|
||||
).WithId("while-true")
|
||||
.Then("Join2");
|
||||
.ThenNamed("Join2");
|
||||
})
|
||||
.Add<Join>(join => join.WithMode(Join.JoinMode.WaitAny)).WithName("Join2")
|
||||
).WithId("for-2"))
|
||||
|
|
|
|||
|
|
@ -20,9 +20,9 @@ namespace Elsa.Core.IntegrationTests.Workflows
|
|||
activity => activity.Set(x => x.Branches, new HashSet<string>(new[] { "Branch 1", "Branch 2", "Branch 3" })),
|
||||
fork =>
|
||||
{
|
||||
fork.When("Branch 1").SignalReceived("Signal1").WriteLine("Branch 1 executed").WithName("WriteLine1").Then("Join");
|
||||
fork.When("Branch 2").SignalReceived("Signal2").WriteLine("Branch 2 executed").WithName("WriteLine2").Then("Join");
|
||||
fork.When("Branch 3").SignalReceived("Signal3").WriteLine("Branch 3 executed").WithName("WriteLine3").Then("Join");
|
||||
fork.When("Branch 1").SignalReceived("Signal1").WriteLine("Branch 1 executed").WithName("WriteLine1").ThenNamed("Join");
|
||||
fork.When("Branch 2").SignalReceived("Signal2").WriteLine("Branch 2 executed").WithName("WriteLine2").ThenNamed("Join");
|
||||
fork.When("Branch 3").SignalReceived("Signal3").WriteLine("Branch 3 executed").WithName("WriteLine3").ThenNamed("Join");
|
||||
})
|
||||
.Add<Join>(join => join.Set(x => x.Mode, _joinMode)).WithName("Join")
|
||||
.WriteLine("Finished").WithName("Finished");
|
||||
|
|
|
|||
Loading…
Reference in a new issue