Incremental work on blueprints
This commit is contained in:
parent
d9d567a489
commit
ef0f3a0907
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Elsa.Models;
|
||||
using Elsa.Services;
|
||||
using Elsa.Services.Models;
|
||||
|
||||
|
|
@ -12,7 +13,7 @@ namespace Elsa.ActivityResults
|
|||
{
|
||||
var outcomeList = outcomes?.ToList() ?? new List<string>(1);
|
||||
|
||||
if (!outcomeList.Any())
|
||||
if (!outcomeList.Any())
|
||||
outcomeList.Add(OutcomeNames.Done);
|
||||
|
||||
Outcomes = outcomeList;
|
||||
|
|
@ -24,24 +25,34 @@ namespace Elsa.ActivityResults
|
|||
|
||||
protected override void Execute(ActivityExecutionContext activityExecutionContext)
|
||||
{
|
||||
if(Output != null)
|
||||
if (Output != null)
|
||||
activityExecutionContext.Output = Output;
|
||||
|
||||
|
||||
activityExecutionContext.Outcomes = Outcomes.ToList();
|
||||
|
||||
var workflowExecutionContext = activityExecutionContext.WorkflowExecutionContext;
|
||||
var nextActivities = GetNextActivities(workflowExecutionContext, activityExecutionContext.ActivityDefinition, Outcomes).ToList();
|
||||
|
||||
var nextActivities = GetNextActivities(
|
||||
workflowExecutionContext,
|
||||
activityExecutionContext.ActivityDefinition,
|
||||
Outcomes).ToList();
|
||||
|
||||
workflowExecutionContext.ScheduleActivities(nextActivities, Output);
|
||||
}
|
||||
|
||||
private IEnumerable<IActivity> GetNextActivities(WorkflowExecutionContext workflowContext, IActivity source, IEnumerable<string> outcomes)
|
||||
|
||||
private IEnumerable<ActivityDefinition> GetNextActivities(
|
||||
WorkflowExecutionContext workflowContext,
|
||||
ActivityDefinition source,
|
||||
IEnumerable<string> outcomes)
|
||||
{
|
||||
var query =
|
||||
from connection in workflowContext.Connections
|
||||
from connection in workflowContext.WorkflowDefinition.Connections
|
||||
from outcome in outcomes
|
||||
where connection.Source.Activity == source && (connection.Source.Outcome ?? OutcomeNames.Done).Equals(outcome, StringComparison.OrdinalIgnoreCase)
|
||||
select connection.Target.Activity;
|
||||
let connectionOutcome = connection.Outcome ?? OutcomeNames.Done
|
||||
let isConnectionOutcome = connectionOutcome.Equals(outcome, StringComparison.OrdinalIgnoreCase)
|
||||
where connection.SourceActivityId == source.Id && isConnectionOutcome
|
||||
from activityDefinition in workflowContext.WorkflowDefinition.Activities
|
||||
where activityDefinition.Id == connection.TargetActivityId
|
||||
select activityDefinition;
|
||||
|
||||
return query.Distinct();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Elsa.Models;
|
||||
using Elsa.Services;
|
||||
using Elsa.Services.Models;
|
||||
using ScheduledActivity = Elsa.Services.Models.ScheduledActivity;
|
||||
|
|
@ -8,7 +9,7 @@ namespace Elsa.ActivityResults
|
|||
{
|
||||
public class ScheduleActivitiesResult : ActivityExecutionResult
|
||||
{
|
||||
public ScheduleActivitiesResult(IEnumerable<IActivity> activities, object? input = default) =>
|
||||
public ScheduleActivitiesResult(IEnumerable<ActivityDefinition> activities, object? input = default) =>
|
||||
Activities = activities.Select(x => new ScheduledActivity(x, input));
|
||||
|
||||
public ScheduleActivitiesResult(IEnumerable<ScheduledActivity> activities) => Activities = activities;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
using Elsa.Models;
|
||||
using Elsa.Services.Models;
|
||||
|
||||
namespace Elsa.ActivityResults
|
||||
|
|
@ -6,7 +7,9 @@ namespace Elsa.ActivityResults
|
|||
{
|
||||
protected override void Execute(ActivityExecutionContext activityExecutionContext)
|
||||
{
|
||||
activityExecutionContext.WorkflowExecutionContext.BlockingActivities.Add(activityExecutionContext.ActivityDefinition);
|
||||
var activityDefinition = activityExecutionContext.ActivityDefinition;
|
||||
var blockingActivity = new BlockingActivity(activityDefinition.Id, activityDefinition.Type);
|
||||
activityExecutionContext.WorkflowExecutionContext.BlockingActivities.Add(blockingActivity);
|
||||
activityExecutionContext.WorkflowExecutionContext.Suspend();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,6 @@ namespace Elsa.Builders
|
|||
Func<IActivityBuilder> Source { get; }
|
||||
Func<IActivityBuilder> Target{ get; }
|
||||
string Outcome { get; }
|
||||
Connection BuildConnection();
|
||||
//Connection BuildConnection();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Elsa.Models;
|
||||
using Elsa.Services;
|
||||
using Elsa.Services.Models;
|
||||
|
||||
|
|
@ -18,23 +19,35 @@ namespace Elsa
|
|||
//
|
||||
// return query;
|
||||
// }
|
||||
|
||||
public static IEnumerable<Connection> GetInboundConnections(this WorkflowExecutionContext workflowExecutionContext, IActivity activity) => workflowExecutionContext.Connections.Where(x => x.Target.Activity == activity);
|
||||
public static IEnumerable<Connection> GetOutboundConnections(this WorkflowExecutionContext workflowExecutionContext, IActivity activity) => workflowExecutionContext.Connections.Where(x => x.Source.Activity == activity);
|
||||
public static IEnumerable<string> GetInboundActivityPath(this WorkflowExecutionContext workflowExecutionContext, IActivity activity) => workflowExecutionContext.GetInboundActivityPathInternal(activity, activity).Distinct();
|
||||
|
||||
private static IEnumerable<string> GetInboundActivityPathInternal(this WorkflowExecutionContext workflowExecutionContext, IActivity activity, IActivity startingPointActivity)
|
||||
public static IEnumerable<ConnectionDefinition>
|
||||
GetInboundConnections(this WorkflowExecutionContext workflowExecutionContext, string activityId) =>
|
||||
workflowExecutionContext.WorkflowDefinition.Connections.Where(x => x.TargetActivityId == activityId);
|
||||
|
||||
public static IEnumerable<ConnectionDefinition> GetOutboundConnections(
|
||||
this WorkflowExecutionContext workflowExecutionContext,
|
||||
string activityId) =>
|
||||
workflowExecutionContext.WorkflowDefinition.Connections.Where(x => x.SourceActivityId == activityId);
|
||||
|
||||
public static IEnumerable<string> GetInboundActivityPath(this WorkflowExecutionContext workflowExecutionContext,
|
||||
string activityId) =>
|
||||
workflowExecutionContext.GetInboundActivityPathInternal(activityId, activityId).Distinct();
|
||||
|
||||
private static IEnumerable<string> GetInboundActivityPathInternal(
|
||||
this WorkflowExecutionContext workflowExecutionContext,
|
||||
string activityId,
|
||||
string startingPointActivityId)
|
||||
{
|
||||
foreach (var connection in workflowExecutionContext.GetInboundConnections(activity))
|
||||
foreach (var connection in workflowExecutionContext.GetInboundConnections(activityId))
|
||||
{
|
||||
// Circuit breaker: Detect workflows that implement repeating flows to prevent an infinite loop here.
|
||||
if (connection.Source.Activity == startingPointActivity)
|
||||
if (connection.SourceActivityId == startingPointActivityId)
|
||||
yield break;
|
||||
|
||||
yield return connection.Source.Activity.Id;
|
||||
yield return connection.SourceActivityId!;
|
||||
|
||||
foreach (var parentActivityId in workflowExecutionContext
|
||||
.GetInboundActivityPathInternal(connection.Source.Activity, startingPointActivity)
|
||||
.GetInboundActivityPathInternal(connection.SourceActivityId!, startingPointActivityId)
|
||||
.Distinct())
|
||||
yield return parentActivityId;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,10 +8,12 @@ namespace Elsa
|
|||
{
|
||||
public static class WorkflowExtensions
|
||||
{
|
||||
public static IEnumerable<WorkflowBlueprint> WithVersion(this IEnumerable<WorkflowBlueprint> query, VersionOptions version)
|
||||
public static IEnumerable<WorkflowBlueprint> WithVersion(this IEnumerable<WorkflowBlueprint> query,
|
||||
VersionOptions version)
|
||||
=> query.AsQueryable().WithVersion(version);
|
||||
|
||||
public static IQueryable<WorkflowBlueprint> WithVersion(this IQueryable<WorkflowBlueprint> query, VersionOptions version)
|
||||
public static IQueryable<WorkflowBlueprint> WithVersion(this IQueryable<WorkflowBlueprint> query,
|
||||
VersionOptions version)
|
||||
{
|
||||
if (version.IsDraft)
|
||||
query = query.Where(x => !x.IsPublished);
|
||||
|
|
@ -30,10 +32,11 @@ namespace Elsa
|
|||
|
||||
return query.OrderByDescending(x => x.Version);
|
||||
}
|
||||
|
||||
public static IEnumerable<IActivity> GetStartActivities(this WorkflowBlueprint workflowBlueprint)
|
||||
|
||||
public static IEnumerable<IActivityBlueprint> GetStartActivities(this WorkflowBlueprint workflowBlueprint)
|
||||
{
|
||||
var targetActivityIds = workflowBlueprint.Connections.Select(x => x.Target.Activity.Id).Distinct().ToLookup(x => x);
|
||||
var targetActivityIds = workflowBlueprint.Connections.Select(x => x.Target.Activity.Id).Distinct()
|
||||
.ToLookup(x => x);
|
||||
|
||||
var query =
|
||||
from activity in workflowBlueprint.Activities
|
||||
|
|
@ -43,46 +46,50 @@ namespace Elsa
|
|||
return query;
|
||||
}
|
||||
|
||||
public static IActivity GetActivity(this WorkflowBlueprint workflowBlueprint, string id) => workflowBlueprint.Activities.FirstOrDefault(x => x.Id == id);
|
||||
public static IActivityBlueprint? GetActivity(this WorkflowBlueprint workflowBlueprint, string id) =>
|
||||
workflowBlueprint.Activities.FirstOrDefault(x => x.Id == id);
|
||||
|
||||
public static IEnumerable<Connection> GetInboundConnections(this WorkflowBlueprint workflowBlueprint, string activityId)
|
||||
{
|
||||
return workflowBlueprint.Connections.Where(x => x.Target.Activity.Id == activityId).ToList();
|
||||
}
|
||||
public static IEnumerable<IConnection> GetInboundConnections(
|
||||
this WorkflowBlueprint workflowBlueprint,
|
||||
string activityId) => workflowBlueprint.Connections.Where(x => x.Target.Activity.Id == activityId).ToList();
|
||||
|
||||
public static IEnumerable<Connection> GetOutboundConnections(this WorkflowBlueprint workflowBlueprint, string activityId)
|
||||
{
|
||||
return workflowBlueprint.Connections.Where(x => x.Source.Activity.Id == activityId).ToList();
|
||||
}
|
||||
public static IEnumerable<IConnection> GetOutboundConnections(
|
||||
this WorkflowBlueprint workflowBlueprint,
|
||||
string activityId) =>
|
||||
workflowBlueprint.Connections.Where(x => x.Source.Activity.Id == activityId).ToList();
|
||||
|
||||
/// <summary>
|
||||
/// Returns the full path of incoming activities.
|
||||
/// </summary>
|
||||
public static IEnumerable<string> GetInboundActivityPath(this WorkflowBlueprint workflowBlueprint, string activityId)
|
||||
public static IEnumerable<string> GetInboundActivityPath(
|
||||
this WorkflowBlueprint workflowBlueprint,
|
||||
string activityId)
|
||||
{
|
||||
var inspectedActivityIDs = new HashSet<string>();
|
||||
var inspectedActivityIds = new HashSet<string>();
|
||||
|
||||
return workflowBlueprint.GetInboundActivityPathInternal(activityId, activityId, inspectedActivityIDs)
|
||||
.Distinct().ToList();
|
||||
return workflowBlueprint.GetInboundActivityPathInternal(activityId, inspectedActivityIds)
|
||||
.Distinct().ToList();
|
||||
}
|
||||
|
||||
private static IEnumerable<string> GetInboundActivityPathInternal(this WorkflowBlueprint workflowBlueprintBlueprintInstance,
|
||||
string activityId,
|
||||
string startingPointActivityId,
|
||||
HashSet<string> inspectedActivityIDs)
|
||||
private static IEnumerable<string> GetInboundActivityPathInternal(
|
||||
this WorkflowBlueprint workflowBlueprintBlueprintInstance,
|
||||
string activityId,
|
||||
HashSet<string> inspectedActivityIds)
|
||||
{
|
||||
foreach (var connection in workflowBlueprintBlueprintInstance.GetInboundConnections(activityId))
|
||||
{
|
||||
// Circuit breaker: Detect workflows that implement repeating flows to prevent an infinite loop here.
|
||||
if (inspectedActivityIDs.Contains(connection.Source.Activity.Id))
|
||||
if (inspectedActivityIds.Contains(connection.Source.Activity.Id))
|
||||
yield break;
|
||||
|
||||
yield return connection.Source.Activity.Id;
|
||||
|
||||
foreach (var parentActivityId in workflowBlueprintBlueprintInstance.GetInboundActivityPathInternal(connection.Source.Activity.Id, startingPointActivityId, inspectedActivityIDs)
|
||||
.Distinct())
|
||||
foreach (var parentActivityId in workflowBlueprintBlueprintInstance.GetInboundActivityPathInternal(
|
||||
connection.Source.Activity.Id,
|
||||
inspectedActivityIds)
|
||||
.Distinct())
|
||||
{
|
||||
inspectedActivityIDs.Add(parentActivityId);
|
||||
inspectedActivityIds.Add(parentActivityId);
|
||||
yield return parentActivityId;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using Elsa.Services;
|
||||
using Elsa.Models;
|
||||
using Elsa.Services;
|
||||
using Elsa.Services.Models;
|
||||
using MediatR;
|
||||
|
||||
|
|
@ -13,6 +14,6 @@ namespace Elsa.Messaging.Domain
|
|||
|
||||
public ActivityExecutionContext ActivityExecutionContext { get; }
|
||||
public WorkflowExecutionContext WorkflowExecutionContext => ActivityExecutionContext.WorkflowExecutionContext;
|
||||
public IActivity Activity => ActivityExecutionContext.ActivityDefinition;
|
||||
public ActivityDefinition Activity => ActivityExecutionContext.ActivityDefinition;
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@ using System.Collections.Generic;
|
|||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Elsa.ActivityResults;
|
||||
using Elsa.Models;
|
||||
using Elsa.Services.Models;
|
||||
using Microsoft.Extensions.Localization;
|
||||
using ScheduledActivity = Elsa.Services.Models.ScheduledActivity;
|
||||
|
|
@ -40,9 +41,9 @@ namespace Elsa.Services
|
|||
protected OutcomeResult Done(params string[] outcomes) => Done(outcomes, default);
|
||||
protected OutcomeResult Done(object? output) => new OutcomeResult(null, output);
|
||||
protected SuspendResult Suspend() => new SuspendResult();
|
||||
protected ScheduleActivitiesResult Schedule(params IActivity[] activities) => new ScheduleActivitiesResult(activities);
|
||||
protected ScheduleActivitiesResult Schedule(IEnumerable<IActivity> activities, object input) => new ScheduleActivitiesResult(activities, input);
|
||||
protected ScheduleActivitiesResult Schedule(IActivity activity, object input) => Schedule(new[] { activity }, input);
|
||||
protected ScheduleActivitiesResult Schedule(params ActivityDefinition[] activities) => new ScheduleActivitiesResult(activities);
|
||||
protected ScheduleActivitiesResult Schedule(IEnumerable<ActivityDefinition> activities, object input) => new ScheduleActivitiesResult(activities, input);
|
||||
protected ScheduleActivitiesResult Schedule(ActivityDefinition activity, object input) => Schedule(new[] { activity }, input);
|
||||
protected ScheduleActivitiesResult Schedule(IEnumerable<ScheduledActivity> activities) => new ScheduleActivitiesResult(activities);
|
||||
protected CombinedResult Combine(IEnumerable<IActivityExecutionResult> results) => new CombinedResult(results);
|
||||
protected CombinedResult Combine(params IActivityExecutionResult[] results) => new CombinedResult(results);
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ namespace Elsa.Services.Models
|
|||
{
|
||||
public class Connection : IConnection
|
||||
{
|
||||
public Connection(IActivity sourceActivity, IActivity targetActivity, string sourceOutcome)
|
||||
public Connection(IActivityBlueprint sourceActivity, IActivityBlueprint targetActivity, string sourceOutcome)
|
||||
: this(new SourceEndpoint(sourceActivity, sourceOutcome), new TargetEndpoint(targetActivity))
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,15 +2,11 @@ namespace Elsa.Services.Models
|
|||
{
|
||||
public abstract class Endpoint
|
||||
{
|
||||
protected Endpoint()
|
||||
{
|
||||
}
|
||||
|
||||
protected Endpoint(IActivity activity)
|
||||
protected Endpoint(IActivityBlueprint activity)
|
||||
{
|
||||
Activity = activity;
|
||||
}
|
||||
|
||||
public IActivity Activity { get; set; }
|
||||
public IActivityBlueprint Activity { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,6 @@
|
|||
{
|
||||
public interface IEndpoint
|
||||
{
|
||||
IActivity Activity { get; }
|
||||
IActivityBlueprint Activity { get; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +1,11 @@
|
|||
using Microsoft.Extensions.Localization;
|
||||
using Elsa.Models;
|
||||
using Microsoft.Extensions.Localization;
|
||||
|
||||
namespace Elsa.Services.Models
|
||||
{
|
||||
public interface IWorkflowFault
|
||||
{
|
||||
IActivity? FaultedActivity { get; }
|
||||
ActivityDefinition? FaultedActivity { get; }
|
||||
LocalizedString? Message { get; }
|
||||
}
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@ namespace Elsa.Services.Models
|
|||
{
|
||||
public class SourceEndpoint : Endpoint, ISourceEndpoint
|
||||
{
|
||||
public SourceEndpoint(IActivity activity, string outcome) : base(activity) => Outcome = outcome;
|
||||
public SourceEndpoint(IActivityBlueprint activity, string outcome) : base(activity) => Outcome = outcome;
|
||||
public string Outcome { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@ namespace Elsa.Services.Models
|
|||
{
|
||||
public class TargetEndpoint : Endpoint, ITargetEndpoint
|
||||
{
|
||||
public TargetEndpoint(IActivity activity) : base(activity)
|
||||
public TargetEndpoint(IActivityBlueprint activity) : base(activity)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ namespace Elsa.Services.Models
|
|||
|
||||
public void Suspend() => Status = WorkflowStatus.Suspended;
|
||||
|
||||
public void Fault(IActivity? activity, LocalizedString? message)
|
||||
public void Fault(ActivityDefinition? activity, LocalizedString? message)
|
||||
{
|
||||
Status = WorkflowStatus.Faulted;
|
||||
WorkflowFault = new WorkflowFault(activity, message);
|
||||
|
|
@ -106,7 +106,7 @@ namespace Elsa.Services.Models
|
|||
|
||||
public void Complete() => Status = WorkflowStatus.Completed;
|
||||
|
||||
public IActivity? GetActivity(string id) => WorkflowBlueprint.Activities.FirstOrDefault(x => x.Id == id);
|
||||
public IActivityBlueprint? GetActivity(string id) => WorkflowBlueprint.Activities.FirstOrDefault(x => x.Id == id);
|
||||
|
||||
public void UpdateWorkflowInstance(WorkflowInstance workflowInstance)
|
||||
{
|
||||
|
|
@ -115,8 +115,8 @@ namespace Elsa.Services.Models
|
|||
workflowInstance.ScheduledActivities = new Stack<Elsa.Models.ScheduledActivity>(
|
||||
ScheduledActivities.Select(x => new Elsa.Models.ScheduledActivity(x.ActivityDefinition.Id, x.Input)));
|
||||
|
||||
workflowInstance.Activities =
|
||||
WorkflowBlueprint.Activities.Select(x => new ActivityInstance(x.Id, x.Type, x.Output, Serialize(x))).ToList();
|
||||
//workflowInstance.Activities =
|
||||
// WorkflowBlueprint.Activities.Select(x => new ActivityInstance(x.Id, x.Type, x.Output, Serialize(x))).ToList();
|
||||
|
||||
workflowInstance.BlockingActivities = BlockingActivities;
|
||||
workflowInstance.Status = Status;
|
||||
|
|
|
|||
|
|
@ -1,16 +1,17 @@
|
|||
using Microsoft.Extensions.Localization;
|
||||
using Elsa.Models;
|
||||
using Microsoft.Extensions.Localization;
|
||||
|
||||
namespace Elsa.Services.Models
|
||||
{
|
||||
public class WorkflowFault : IWorkflowFault
|
||||
{
|
||||
public WorkflowFault(IActivity? activity = default, LocalizedString? message = default)
|
||||
public WorkflowFault(ActivityDefinition? activity = default, LocalizedString? message = default)
|
||||
{
|
||||
FaultedActivity = activity;
|
||||
Message = message;
|
||||
}
|
||||
|
||||
public IActivity? FaultedActivity { get; }
|
||||
public ActivityDefinition? FaultedActivity { get; }
|
||||
public LocalizedString? Message { get; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
using Elsa.ActivityResults;
|
||||
using Elsa.Attributes;
|
||||
using Elsa.Services;
|
||||
using Elsa.Services.Models;
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
namespace Elsa.Activities.ControlFlow
|
||||
|
|
@ -24,7 +25,7 @@ namespace Elsa.Activities.ControlFlow
|
|||
|
||||
private int? CurrentValue { get; set; }
|
||||
|
||||
protected override IActivityExecutionResult OnExecute()
|
||||
protected override IActivityExecutionResult OnExecute(ActivityExecutionContext context)
|
||||
{
|
||||
var currentValue = CurrentValue ?? Start;
|
||||
|
||||
|
|
@ -33,7 +34,7 @@ namespace Elsa.Activities.ControlFlow
|
|||
var input = currentValue;
|
||||
currentValue += Step;
|
||||
CurrentValue = currentValue;
|
||||
return Combine(Schedule(this), Done(OutcomeNames.Iterate, input));
|
||||
return Combine(Schedule(context.ActivityDefinition), Done(OutcomeNames.Iterate, input));
|
||||
}
|
||||
|
||||
CurrentValue = null;
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ namespace Elsa.Activities.ControlFlow
|
|||
Category = "Control Flow",
|
||||
Description = "Iterate over a collection.",
|
||||
Icon = "far fa-circle",
|
||||
Outcomes = new[] {OutcomeNames.Iterate, OutcomeNames.Done}
|
||||
Outcomes = new[] { OutcomeNames.Iterate, OutcomeNames.Done }
|
||||
)]
|
||||
public class ForEach : Activity
|
||||
{
|
||||
|
|
@ -27,9 +27,7 @@ namespace Elsa.Activities.ControlFlow
|
|||
|
||||
private int? CurrentIndex { get; set; }
|
||||
|
||||
protected override async Task<IActivityExecutionResult> OnExecuteAsync(
|
||||
ActivityExecutionContext context,
|
||||
CancellationToken cancellationToken)
|
||||
protected override IActivityExecutionResult OnExecute(ActivityExecutionContext context)
|
||||
{
|
||||
var collection = CollectionCopy;
|
||||
|
||||
|
|
@ -42,7 +40,7 @@ namespace Elsa.Activities.ControlFlow
|
|||
{
|
||||
var input = collection[currentIndex];
|
||||
CurrentIndex = currentIndex + 1;
|
||||
return Combine(Schedule(this), Done(OutcomeNames.Iterate, input));
|
||||
return Combine(Schedule(context.ActivityDefinition), Done(OutcomeNames.Iterate, input));
|
||||
}
|
||||
|
||||
CurrentIndex = null;
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ namespace Elsa.Activities.ControlFlow
|
|||
public ForkBuilder(IActivityBuilder activityBuilder)
|
||||
{
|
||||
_activityBuilder = activityBuilder;
|
||||
_fork = (Fork)activityBuilder.Activity;
|
||||
//_fork = (Fork)activityBuilder.Activity;
|
||||
}
|
||||
|
||||
public IOutcomeBuilder When(string branch)
|
||||
|
|
|
|||
|
|
@ -8,11 +8,12 @@ namespace Elsa.Activities.ControlFlow
|
|||
{
|
||||
public static IWorkflowBuilder Fork(this IBuilder builder, Action<ForkBuilder> setup)
|
||||
{
|
||||
var activityBuilder = builder.Then<Fork>();
|
||||
var forkBuilder = new ForkBuilder(activityBuilder);
|
||||
//var activityBuilder = builder.Then<Fork>();
|
||||
//var forkBuilder = new ForkBuilder(activityBuilder);
|
||||
|
||||
setup(forkBuilder);
|
||||
return activityBuilder.WorkflowBuilder;
|
||||
//setup(forkBuilder);
|
||||
//return activityBuilder.WorkflowBuilder;
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -12,40 +12,8 @@ namespace Elsa.Activities.Primitives
|
|||
/// </summary>
|
||||
public class Inline : Activity
|
||||
{
|
||||
public Inline()
|
||||
{
|
||||
Function = context => Task.FromResult<IActivityExecutionResult>(Done());
|
||||
}
|
||||
|
||||
public Inline(Func<ActivityExecutionContext, Task<IActivityExecutionResult>> function)
|
||||
{
|
||||
Function = function;
|
||||
}
|
||||
|
||||
public Inline(Func<ActivityExecutionContext, Task> function)
|
||||
{
|
||||
Function = context =>
|
||||
{
|
||||
function(context);
|
||||
return Task.FromResult<IActivityExecutionResult>(Done());
|
||||
};
|
||||
}
|
||||
|
||||
public Inline(Action<ActivityExecutionContext> function)
|
||||
{
|
||||
Function = context =>
|
||||
{
|
||||
function(context);
|
||||
return Task.FromResult<IActivityExecutionResult>(Done());
|
||||
};
|
||||
}
|
||||
|
||||
public Inline(Action function) : this(context => function())
|
||||
{
|
||||
}
|
||||
|
||||
public Func<ActivityExecutionContext, Task<IActivityExecutionResult>> Function { get; set; }
|
||||
|
||||
protected override Task<IActivityExecutionResult> OnExecuteAsync(ActivityExecutionContext context, CancellationToken cancellationToken) => Function(context);
|
||||
public Inline() => Function = context => new ValueTask<IActivityExecutionResult>(Done());
|
||||
public Func<ActivityExecutionContext, ValueTask<IActivityExecutionResult>> Function { get; set; }
|
||||
protected override ValueTask<IActivityExecutionResult> OnExecuteAsync(ActivityExecutionContext context, CancellationToken cancellationToken) => Function(context);
|
||||
}
|
||||
}
|
||||
|
|
@ -8,9 +8,57 @@ namespace Elsa.Builders
|
|||
{
|
||||
public static class ActivityBuilderExtensions
|
||||
{
|
||||
public static IActivityBuilder Then(this IBuilder builder, Func<ActivityExecutionContext, Task<IActivityExecutionResult>> activity) => builder.Then(new Inline(activity));
|
||||
public static IActivityBuilder Then(this IBuilder builder, Func<ActivityExecutionContext, Task> activity) => builder.Then(new Inline(activity));
|
||||
public static IActivityBuilder Then(this IBuilder builder, Action<ActivityExecutionContext> activity) => builder.Then(new Inline(activity));
|
||||
public static IActivityBuilder Then(this IBuilder builder, Action activity) => builder.Then(new Inline(activity));
|
||||
public static IActivityBuilder Then(this IBuilder builder,
|
||||
Func<ActivityExecutionContext, ValueTask<IActivityExecutionResult>> activity) =>
|
||||
builder.Then<Inline>(x => x.Function = RunInline(activity));
|
||||
|
||||
public static IActivityBuilder
|
||||
Then(this IBuilder builder, Func<ActivityExecutionContext, ValueTask> activity) =>
|
||||
builder.Then<Inline>(x => x.Function = RunInline(activity));
|
||||
|
||||
public static IActivityBuilder Then(this IBuilder builder, Action<ActivityExecutionContext> activity) =>
|
||||
builder.Then<Inline>(x => x.Function = RunInline(activity));
|
||||
|
||||
public static IActivityBuilder Then(this IBuilder builder, Action activity) =>
|
||||
builder.Then<Inline>(x => x.Function = RunInline(activity));
|
||||
|
||||
private static Func<ActivityExecutionContext, ValueTask<IActivityExecutionResult>> RunInline(
|
||||
Func<ActivityExecutionContext, ValueTask<IActivityExecutionResult>> activity) =>
|
||||
async context =>
|
||||
{
|
||||
await activity(context);
|
||||
return new OutcomeResult();
|
||||
};
|
||||
|
||||
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());
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -18,6 +18,6 @@ namespace Elsa.Builders
|
|||
Outcome = outcome;
|
||||
}
|
||||
|
||||
public Connection BuildConnection() => new Connection(Source().Activity, Target().Activity, Outcome);
|
||||
//public Connection BuildConnection() => new Connection(Source, Target().Activity, Outcome);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue