WIP: extract composite activity builder from workflow builder
This commit is contained in:
parent
594853d45c
commit
90c8577864
|
|
@ -9,7 +9,7 @@ namespace Elsa.Builders
|
|||
{
|
||||
public interface IActivityBuilder : IBuilder
|
||||
{
|
||||
IWorkflowBuilder WorkflowBuilder { get; }
|
||||
ICompositeActivityBuilder WorkflowBuilder { get; }
|
||||
public Type ActivityType { get; }
|
||||
string ActivityId { get; set; }
|
||||
public string? Name { get; set; }
|
||||
|
|
@ -23,6 +23,6 @@ namespace Elsa.Builders
|
|||
IActivityBuilder WithId(string? id);
|
||||
IActivityBuilder WithName(string? name);
|
||||
Func<ActivityExecutionContext, CancellationToken, ValueTask<IActivity>> BuildActivityAsync();
|
||||
IWorkflowBlueprint Build();
|
||||
//IWorkflowBlueprint Build();
|
||||
}
|
||||
}
|
||||
11
src/core/Elsa.Abstractions/Builders/ICompositeActivity.cs
Normal file
11
src/core/Elsa.Abstractions/Builders/ICompositeActivity.cs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
namespace Elsa.Builders
|
||||
{
|
||||
public interface ICompositeActivity<in TBuilder> where TBuilder: ICompositeActivityBuilder
|
||||
{
|
||||
void Build(TBuilder compositeActivity);
|
||||
}
|
||||
|
||||
public interface ICompositeActivity : ICompositeActivity<ICompositeActivityBuilder>
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Elsa.Services;
|
||||
using Elsa.Services.Models;
|
||||
|
||||
namespace Elsa.Builders
|
||||
{
|
||||
public interface ICompositeActivityBuilder : IActivityBuilder
|
||||
{
|
||||
IServiceProvider ServiceProvider { get; }
|
||||
IReadOnlyCollection<IActivityBuilder> Activities { get; }
|
||||
|
||||
IActivityBuilder New<T>(
|
||||
Action<IActivityBuilder>? branch = default,
|
||||
IDictionary<string, IActivityPropertyValueProvider>? propertyValueProviders = default)
|
||||
where T : class, IActivity;
|
||||
|
||||
IActivityBuilder New<T>(
|
||||
Action<ISetupActivity<T>>? setup,
|
||||
Action<IActivityBuilder>? branch = default) where T : class, IActivity;
|
||||
|
||||
IActivityBuilder StartWith<T>(
|
||||
Action<ISetupActivity<T>>? setup,
|
||||
Action<IActivityBuilder>? branch = default) where T : class, IActivity;
|
||||
|
||||
IActivityBuilder StartWith<T>(Action<IActivityBuilder>? branch = default)
|
||||
where T : class, IActivity;
|
||||
|
||||
IActivityBuilder Add<T>(
|
||||
Action<ISetupActivity<T>>? setup = default,
|
||||
Action<IActivityBuilder>? branch = default) where T : class, IActivity;
|
||||
|
||||
IActivityBuilder Add<T>(
|
||||
Action<IActivityBuilder>? branch = default,
|
||||
IDictionary<string, IActivityPropertyValueProvider>? propertyValueProviders = default)
|
||||
where T : class, IActivity;
|
||||
|
||||
IConnectionBuilder Connect(
|
||||
IActivityBuilder source,
|
||||
IActivityBuilder target,
|
||||
string outcome = OutcomeNames.Done);
|
||||
|
||||
IConnectionBuilder Connect(
|
||||
Func<IActivityBuilder> source,
|
||||
Func<IActivityBuilder> target,
|
||||
string outcome = OutcomeNames.Done);
|
||||
|
||||
ICompositeActivityBlueprint Build(string activityIdPrefix = "activity");
|
||||
}
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@ namespace Elsa.Builders
|
|||
{
|
||||
public interface IConnectionBuilder
|
||||
{
|
||||
IWorkflowBuilder WorkflowBuilder { get; }
|
||||
ICompositeActivityBuilder WorkflowBuilder { get; }
|
||||
Func<IActivityBuilder> Source { get; }
|
||||
Func<IActivityBuilder> Target{ get; }
|
||||
string Outcome { get; }
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ namespace Elsa.Builders
|
|||
{
|
||||
public interface IOutcomeBuilder : IBuilder
|
||||
{
|
||||
IWorkflowBuilder WorkflowBuilder { get; }
|
||||
ICompositeActivityBuilder WorkflowBuilder { get; }
|
||||
IActivityBuilder Source { get; }
|
||||
string? Outcome { get; }
|
||||
IConnectionBuilder Then(string activityName);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
namespace Elsa.Builders
|
||||
{
|
||||
public interface IWorkflow
|
||||
public interface IWorkflow : ICompositeActivity<IWorkflowBuilder>
|
||||
{
|
||||
void Build(IWorkflowBuilder workflow);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,24 +1,15 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Elsa.Models;
|
||||
using Elsa.Services;
|
||||
using Elsa.Services.Models;
|
||||
|
||||
namespace Elsa.Builders
|
||||
{
|
||||
public interface IWorkflowBuilder : IBuilder
|
||||
public interface IWorkflowBuilder : ICompositeActivityBuilder
|
||||
{
|
||||
string Id { get; }
|
||||
string Name { get; }
|
||||
string Description { get; }
|
||||
int Version { get; }
|
||||
WorkflowPersistenceBehavior PersistenceBehavior { get; }
|
||||
bool DeleteCompletedInstances { get; }
|
||||
bool IsEnabled { get; }
|
||||
IServiceProvider ServiceProvider { get; }
|
||||
IReadOnlyCollection<IActivityBuilder> Activities { get; }
|
||||
IWorkflowBuilder WithId(string value);
|
||||
IWorkflowBuilder WithName(string value);
|
||||
IWorkflowBuilder WithDescription(string value);
|
||||
IWorkflowBuilder WithVersion(int value);
|
||||
IWorkflowBuilder AsSingleton();
|
||||
|
|
@ -29,42 +20,8 @@ namespace Elsa.Builders
|
|||
IWorkflowBuilder WithPersistenceBehavior(WorkflowPersistenceBehavior value);
|
||||
IWorkflowBuilder Enable(bool value);
|
||||
|
||||
IActivityBuilder New<T>(
|
||||
Action<IActivityBuilder>? branch = default,
|
||||
IDictionary<string, IActivityPropertyValueProvider>? propertyValueProviders = default)
|
||||
where T : class, IActivity;
|
||||
|
||||
IActivityBuilder New<T>(
|
||||
Action<ISetupActivity<T>>? setup,
|
||||
Action<IActivityBuilder>? branch = default) where T : class, IActivity;
|
||||
|
||||
IActivityBuilder StartWith<T>(
|
||||
Action<ISetupActivity<T>>? setup,
|
||||
Action<IActivityBuilder>? branch = default) where T : class, IActivity;
|
||||
|
||||
IActivityBuilder StartWith<T>(Action<IActivityBuilder>? branch = default)
|
||||
where T : class, IActivity;
|
||||
|
||||
IActivityBuilder Add<T>(
|
||||
Action<ISetupActivity<T>>? setup = default,
|
||||
Action<IActivityBuilder>? branch = default) where T : class, IActivity;
|
||||
|
||||
IActivityBuilder Add<T>(
|
||||
Action<IActivityBuilder>? branch = default,
|
||||
IDictionary<string, IActivityPropertyValueProvider>? propertyValueProviders = default)
|
||||
where T : class, IActivity;
|
||||
|
||||
IConnectionBuilder Connect(
|
||||
IActivityBuilder source,
|
||||
IActivityBuilder target,
|
||||
string outcome = OutcomeNames.Done);
|
||||
|
||||
IConnectionBuilder Connect(
|
||||
Func<IActivityBuilder> source,
|
||||
Func<IActivityBuilder> target,
|
||||
string outcome = OutcomeNames.Done);
|
||||
|
||||
IWorkflowBlueprint Build(string activityIdPrefix = "activity");
|
||||
IWorkflowBlueprint BuildBlueprint(string activityIdPrefix = "activity");
|
||||
// IWorkflowBlueprint Build(string activityIdPrefix = "activity");
|
||||
IWorkflowBlueprint Build(IWorkflow workflow, string activityIdPrefix = "activity");
|
||||
IWorkflowBlueprint Build(Type workflowType, string activityIdPrefix = "activity");
|
||||
IWorkflowBlueprint Build<T>(string activityIdPrefix = "activity") where T : IWorkflow;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Elsa.Models;
|
||||
|
|
@ -7,36 +7,9 @@ using Elsa.Services.Models;
|
|||
|
||||
namespace Elsa
|
||||
{
|
||||
public static class WorkflowExtensions
|
||||
public static class CompositeActivityBlueprintExtensions
|
||||
{
|
||||
public static IEnumerable<IWorkflowBlueprint> WithVersion(
|
||||
this IEnumerable<IWorkflowBlueprint> query,
|
||||
VersionOptions version) =>
|
||||
query.AsQueryable().WithVersion(version);
|
||||
|
||||
public static IQueryable<IWorkflowBlueprint> WithVersion(
|
||||
this IQueryable<IWorkflowBlueprint> query,
|
||||
VersionOptions version)
|
||||
{
|
||||
if (version.IsDraft)
|
||||
query = query.Where(x => !x.IsPublished);
|
||||
else if (version.IsLatest)
|
||||
query = query.Where(x => x.IsLatest);
|
||||
else if (version.IsPublished)
|
||||
query = query.Where(x => x.IsPublished);
|
||||
else if (version.IsLatestOrPublished)
|
||||
query = query.Where(x => x.IsPublished || x.IsLatest);
|
||||
else if (version.AllVersions)
|
||||
{
|
||||
// Nothing to filter.
|
||||
}
|
||||
else if (version.Version > 0)
|
||||
query = query.Where(x => x.Version == version.Version);
|
||||
|
||||
return query.OrderByDescending(x => x.Version);
|
||||
}
|
||||
|
||||
public static IEnumerable<IActivityBlueprint> GetStartActivities(this IWorkflowBlueprint workflowBlueprint)
|
||||
public static IEnumerable<IActivityBlueprint> GetStartActivities(this ICompositeActivityBlueprint workflowBlueprint)
|
||||
{
|
||||
var targetActivityIds = workflowBlueprint.Connections.Select(x => x.Target.Activity.Id).Distinct()
|
||||
.ToLookup(x => x);
|
||||
|
|
@ -49,22 +22,22 @@ namespace Elsa
|
|||
return query;
|
||||
}
|
||||
|
||||
public static IEnumerable<IActivityBlueprint> GetStartActivities(this IWorkflowBlueprint workflowBlueprint, string activityType) => workflowBlueprint.GetStartActivities().Where(x => x.Type == activityType);
|
||||
public static IEnumerable<IActivityBlueprint> GetStartActivities(this IWorkflowBlueprint workflowBlueprint, Type activityType) => workflowBlueprint.GetStartActivities(activityType.Name);
|
||||
public static IEnumerable<IActivityBlueprint> GetStartActivities<T>(this IWorkflowBlueprint workflowBlueprint) where T : IActivity => workflowBlueprint.GetStartActivities(typeof(T));
|
||||
public static IActivityBlueprint? GetActivity(this IWorkflowBlueprint workflowBlueprint, string id) => workflowBlueprint.Activities.FirstOrDefault(x => x.Id == id);
|
||||
public static IEnumerable<IActivityBlueprint> GetActivities(this IWorkflowBlueprint workflowBlueprint, IEnumerable<string> ids) => workflowBlueprint.Activities.Where(x => ids.Contains(x.Id));
|
||||
public static IEnumerable<IActivityBlueprint> GetStartActivities(this ICompositeActivityBlueprint workflowBlueprint, string activityType) => workflowBlueprint.GetStartActivities().Where(x => x.Type == activityType);
|
||||
public static IEnumerable<IActivityBlueprint> GetStartActivities(this ICompositeActivityBlueprint workflowBlueprint, Type activityType) => workflowBlueprint.GetStartActivities(activityType.Name);
|
||||
public static IEnumerable<IActivityBlueprint> GetStartActivities<T>(this ICompositeActivityBlueprint workflowBlueprint) where T : IActivity => workflowBlueprint.GetStartActivities(typeof(T));
|
||||
public static IActivityBlueprint? GetActivity(this ICompositeActivityBlueprint workflowBlueprint, string id) => workflowBlueprint.Activities.FirstOrDefault(x => x.Id == id);
|
||||
public static IEnumerable<IActivityBlueprint> GetActivities(this ICompositeActivityBlueprint workflowBlueprint, IEnumerable<string> ids) => workflowBlueprint.Activities.Where(x => ids.Contains(x.Id));
|
||||
|
||||
public static IEnumerable<IActivityBlueprint> GetBlockingActivities(this IWorkflowBlueprint workflowBlueprint, WorkflowInstance workflowInstance) =>
|
||||
public static IEnumerable<IActivityBlueprint> GetBlockingActivities(this ICompositeActivityBlueprint workflowBlueprint, WorkflowInstance workflowInstance) =>
|
||||
workflowBlueprint.Activities.Where(activity => workflowInstance.BlockingActivities.Select(x => x.ActivityId).Contains(activity.Id));
|
||||
|
||||
public static IEnumerable<IConnection> GetInboundConnections(
|
||||
this IWorkflowBlueprint workflowBlueprint,
|
||||
this ICompositeActivityBlueprint workflowBlueprint,
|
||||
string activityId) =>
|
||||
workflowBlueprint.Connections.Where(x => x.Target.Activity.Id == activityId).ToList();
|
||||
|
||||
public static IEnumerable<IConnection> GetOutboundConnections(
|
||||
this IWorkflowBlueprint workflowBlueprint,
|
||||
this ICompositeActivityBlueprint workflowBlueprint,
|
||||
string activityId) =>
|
||||
workflowBlueprint.Connections.Where(x => x.Source.Activity.Id == activityId).ToList();
|
||||
|
||||
|
|
@ -72,7 +45,7 @@ namespace Elsa
|
|||
/// Returns the full path of incoming activities.
|
||||
/// </summary>
|
||||
public static IEnumerable<string> GetInboundActivityPath(
|
||||
this IWorkflowBlueprint workflowBlueprint,
|
||||
this ICompositeActivityBlueprint workflowBlueprint,
|
||||
string activityId)
|
||||
{
|
||||
var inspectedActivityIds = new HashSet<string>();
|
||||
|
|
@ -82,7 +55,7 @@ namespace Elsa
|
|||
}
|
||||
|
||||
private static IEnumerable<string> GetInboundActivityPathInternal(
|
||||
this IWorkflowBlueprint workflowBlueprintBlueprintInstance,
|
||||
this ICompositeActivityBlueprint workflowBlueprintBlueprintInstance,
|
||||
string activityId,
|
||||
HashSet<string> inspectedActivityIds)
|
||||
{
|
||||
|
|
@ -1,7 +1,10 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Elsa.Models;
|
||||
using Elsa.Services;
|
||||
using Elsa.Services.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
|
@ -59,5 +62,32 @@ namespace Elsa
|
|||
var serializer = activityExecutionContext.GetService<JsonSerializer>();
|
||||
return activity.Data[propertyName]!.ToObject<T>(serializer)!;
|
||||
}
|
||||
|
||||
public static IEnumerable<IWorkflowBlueprint> WithVersion(
|
||||
this IEnumerable<IWorkflowBlueprint> query,
|
||||
VersionOptions version) =>
|
||||
query.AsQueryable().WithVersion(version);
|
||||
|
||||
public static IQueryable<IWorkflowBlueprint> WithVersion(
|
||||
this IQueryable<IWorkflowBlueprint> query,
|
||||
VersionOptions version)
|
||||
{
|
||||
if (version.IsDraft)
|
||||
query = query.Where(x => !x.IsPublished);
|
||||
else if (version.IsLatest)
|
||||
query = query.Where(x => x.IsLatest);
|
||||
else if (version.IsPublished)
|
||||
query = query.Where(x => x.IsPublished);
|
||||
else if (version.IsLatestOrPublished)
|
||||
query = query.Where(x => x.IsPublished || x.IsLatest);
|
||||
else if (version.AllVersions)
|
||||
{
|
||||
// Nothing to filter.
|
||||
}
|
||||
else if (version.Version > 0)
|
||||
query = query.Where(x => x.Version == version.Version);
|
||||
|
||||
return query.OrderByDescending(x => x.Version);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq;
|
||||
using Elsa.ActivityResults;
|
||||
using Elsa.Builders;
|
||||
using Elsa.Services.Models;
|
||||
|
|
@ -8,11 +7,12 @@ namespace Elsa.Services
|
|||
{
|
||||
public abstract class CompositeActivity : Activity
|
||||
{
|
||||
public abstract void Build(IWorkflowBuilder workflowBuilder);
|
||||
public abstract void Build(ICompositeActivityBuilder composite);
|
||||
|
||||
protected override IActivityExecutionResult OnExecute(ActivityExecutionContext context)
|
||||
{
|
||||
var startActivities = context.ActivityBlueprint.ChildWorkflow!.GetStartActivities().Select(x => x.Id).ToList();
|
||||
var compositeActivityBlueprint = (ICompositeActivityBlueprint)context.ActivityBlueprint;
|
||||
var startActivities = compositeActivityBlueprint.GetStartActivities().Select(x => x.Id).ToList();
|
||||
return Combine(Done(), Schedule(startActivities, null!));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@ namespace Elsa.Services.Models
|
|||
public string? Name { get; set; }
|
||||
public string Type { get; set; } = default!;
|
||||
public bool PersistWorkflow { get; set; }
|
||||
public IWorkflowBlueprint? ChildWorkflow { get; set; }
|
||||
|
||||
|
||||
public Func<ActivityExecutionContext, CancellationToken, ValueTask<IActivity>> CreateActivityAsync { get; set; } = default!;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Elsa.Services.Models
|
||||
{
|
||||
public class CompositeActivityBlueprint : ActivityBlueprint, ICompositeActivityBlueprint
|
||||
{
|
||||
public CompositeActivityBlueprint()
|
||||
{
|
||||
Activities = new List<IActivityBlueprint>();
|
||||
Connections = new List<IConnection>();
|
||||
ActivityPropertyProviders = new ActivityPropertyProviders();
|
||||
}
|
||||
|
||||
public CompositeActivityBlueprint(
|
||||
string id,
|
||||
string? name,
|
||||
string type,
|
||||
bool persistWorkflow,
|
||||
Func<ActivityExecutionContext, CancellationToken, ValueTask<IActivity>> createActivity) : base(id, name, type, persistWorkflow, createActivity)
|
||||
{
|
||||
}
|
||||
|
||||
public ICollection<IActivityBlueprint> Activities { get; set; } = default!;
|
||||
public ICollection<IConnection> Connections { get; set; }= default!;
|
||||
public IActivityPropertyProviders ActivityPropertyProviders { get; set; } = default!;
|
||||
}
|
||||
}
|
||||
|
|
@ -11,6 +11,5 @@ namespace Elsa.Services.Models
|
|||
public string Type { get; }
|
||||
public bool PersistWorkflow { get; }
|
||||
Func<ActivityExecutionContext, CancellationToken, ValueTask<IActivity>> CreateActivityAsync { get; }
|
||||
IWorkflowBlueprint? ChildWorkflow { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace Elsa.Services.Models
|
||||
{
|
||||
public interface ICompositeActivityBlueprint : IActivityBlueprint
|
||||
{
|
||||
public ICollection<IActivityBlueprint> Activities { get; set; }
|
||||
|
||||
public ICollection<IConnection> Connections { get; }
|
||||
IActivityPropertyProviders ActivityPropertyProviders { get; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +1,9 @@
|
|||
using System.Collections.Generic;
|
||||
using Elsa.Models;
|
||||
using Elsa.Models;
|
||||
|
||||
namespace Elsa.Services.Models
|
||||
{
|
||||
public interface IWorkflowBlueprint
|
||||
public interface IWorkflowBlueprint : ICompositeActivityBlueprint
|
||||
{
|
||||
public string? Name { get; }
|
||||
public string Id { get; }
|
||||
public int Version { get; set; }
|
||||
public bool IsSingleton { get; }
|
||||
public bool IsEnabled { get; }
|
||||
|
|
@ -21,8 +18,6 @@ namespace Elsa.Services.Models
|
|||
public WorkflowContextOptions? ContextOptions { get; set; }
|
||||
public WorkflowPersistenceBehavior PersistenceBehavior { get; }
|
||||
public bool DeleteCompletedInstances { get; }
|
||||
public ICollection<IActivityBlueprint> Activities { get; }
|
||||
public ICollection<IConnection> Connections { get; }
|
||||
IActivityPropertyProviders ActivityPropertyProviders { get; }
|
||||
}
|
||||
}
|
||||
|
|
@ -4,12 +4,10 @@ using Elsa.Models;
|
|||
|
||||
namespace Elsa.Services.Models
|
||||
{
|
||||
public class WorkflowBlueprint : IWorkflowBlueprint
|
||||
public class WorkflowBlueprint : CompositeActivityBlueprint, IWorkflowBlueprint
|
||||
{
|
||||
public WorkflowBlueprint()
|
||||
{
|
||||
Activities = new List<IActivityBlueprint>();
|
||||
Connections = new List<IConnection>();
|
||||
ActivityPropertyProviders = new ActivityPropertyProviders();
|
||||
Variables = new Variables();
|
||||
}
|
||||
|
|
@ -29,7 +27,7 @@ namespace Elsa.Services.Models
|
|||
bool deleteCompletedInstances,
|
||||
IEnumerable<IActivityBlueprint> activities,
|
||||
IEnumerable<IConnection> connections,
|
||||
IActivityPropertyProviders activityPropertyValueProviders)
|
||||
IActivityPropertyProviders activityPropertyValueProviders) : base(id, name, id, true, null!)
|
||||
{
|
||||
Id = id;
|
||||
Version = version;
|
||||
|
|
@ -47,12 +45,10 @@ namespace Elsa.Services.Models
|
|||
Connections = connections.ToList();
|
||||
ActivityPropertyProviders = activityPropertyValueProviders;
|
||||
}
|
||||
|
||||
public string Id { get; set; } = default!;
|
||||
|
||||
public int Version { get; set; }
|
||||
public bool IsSingleton { get; set; }
|
||||
public bool IsEnabled { get; set; }
|
||||
public string? Name { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public bool IsPublished { get; set; }
|
||||
public bool IsLatest { get; set; }
|
||||
|
|
@ -60,10 +56,5 @@ namespace Elsa.Services.Models
|
|||
public WorkflowContextOptions? ContextOptions { get; set; }
|
||||
public WorkflowPersistenceBehavior PersistenceBehavior { get; set; }
|
||||
public bool DeleteCompletedInstances { get; set; }
|
||||
public ICollection<IActivityBlueprint> Activities { get; set; }
|
||||
|
||||
public ICollection<IConnection> Connections { get; set; }
|
||||
|
||||
public IActivityPropertyProviders ActivityPropertyProviders { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -12,7 +12,7 @@ namespace Elsa.Builders
|
|||
{
|
||||
public ActivityBuilder(
|
||||
Type activityType,
|
||||
IWorkflowBuilder workflowBuilder,
|
||||
ICompositeActivityBuilder workflowBuilder,
|
||||
IDictionary<string, IActivityPropertyValueProvider>? propertyValueProviders)
|
||||
{
|
||||
ActivityType = activityType;
|
||||
|
|
@ -20,8 +20,8 @@ namespace Elsa.Builders
|
|||
PropertyValueProviders = propertyValueProviders;
|
||||
}
|
||||
|
||||
public Type ActivityType { get; }
|
||||
public IWorkflowBuilder WorkflowBuilder { get; }
|
||||
public Type ActivityType { get; } = null!;
|
||||
public ICompositeActivityBuilder WorkflowBuilder { get; } = default!;
|
||||
public string ActivityId { get; set; } = default!;
|
||||
public string? Name { get; set; }
|
||||
public string? Description { get; set; }
|
||||
|
|
@ -79,6 +79,6 @@ namespace Elsa.Builders
|
|||
return activity;
|
||||
};
|
||||
|
||||
public IWorkflowBlueprint Build() => WorkflowBuilder.Build();
|
||||
//public IWorkflowBlueprint Build() => WorkflowBuilder.Build();
|
||||
}
|
||||
}
|
||||
186
src/core/Elsa.Core/Builders/CompositeActivityBuilder.cs
Normal file
186
src/core/Elsa.Core/Builders/CompositeActivityBuilder.cs
Normal file
|
|
@ -0,0 +1,186 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Elsa.Services;
|
||||
using Elsa.Services.Models;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using NetBox.Extensions;
|
||||
|
||||
namespace Elsa.Builders
|
||||
{
|
||||
public class CompositeActivityBuilder : ActivityBuilder, ICompositeActivityBuilder
|
||||
{
|
||||
private readonly IActivityActivator _activityActivator;
|
||||
private readonly Func<ICompositeActivityBuilder> _workflowBuilderFactory;
|
||||
|
||||
public CompositeActivityBuilder(
|
||||
IIdGenerator idGenerator,
|
||||
IActivityActivator activityActivator,
|
||||
IServiceProvider serviceProvider) : base()
|
||||
{
|
||||
_activityActivator = activityActivator;
|
||||
ServiceProvider = serviceProvider;
|
||||
ActivityId = idGenerator.Generate();
|
||||
ActivityBuilders = new List<IActivityBuilder>();
|
||||
ConnectionBuilders = new List<IConnectionBuilder>();
|
||||
_workflowBuilderFactory = serviceProvider.GetRequiredService<ICompositeActivityBuilder>;
|
||||
}
|
||||
|
||||
public IServiceProvider ServiceProvider { get; }
|
||||
protected IList<IActivityBuilder> ActivityBuilders { get; }
|
||||
protected IList<IConnectionBuilder> ConnectionBuilders { get; }
|
||||
|
||||
public IReadOnlyCollection<IActivityBuilder> Activities => ActivityBuilders.ToList().AsReadOnly();
|
||||
|
||||
public IActivityBuilder New(Type activityType, IDictionary<string, IActivityPropertyValueProvider>? propertyValueProviders = default)
|
||||
{
|
||||
var activityBuilder = new ActivityBuilder(activityType, this, propertyValueProviders);
|
||||
return activityBuilder;
|
||||
}
|
||||
|
||||
public IActivityBuilder New<T>(
|
||||
Action<IActivityBuilder>? branch = default,
|
||||
IDictionary<string, IActivityPropertyValueProvider>? propertyValueProviders = default)
|
||||
where T : class, IActivity =>
|
||||
New(typeof(T), propertyValueProviders);
|
||||
|
||||
public IActivityBuilder New<T>(
|
||||
Action<ISetupActivity<T>>? setup = default,
|
||||
Action<IActivityBuilder>? branch = default) where T : class, IActivity
|
||||
{
|
||||
var propertyValuesBuilder = new SetupActivity<T>();
|
||||
setup?.Invoke(propertyValuesBuilder);
|
||||
|
||||
var valueProviders = propertyValuesBuilder.ValueProviders.ToDictionary(
|
||||
x => x.Key,
|
||||
x => (IActivityPropertyValueProvider)new DelegateActivityPropertyValueProvider(x.Value));
|
||||
|
||||
return New<T>(branch, valueProviders);
|
||||
}
|
||||
|
||||
public IActivityBuilder StartWith<T>(
|
||||
Action<ISetupActivity<T>>? setup = default,
|
||||
Action<IActivityBuilder>? branch = default) where T : class, IActivity
|
||||
{
|
||||
var activityBuilder = New(setup, branch);
|
||||
return Add(activityBuilder, branch);
|
||||
}
|
||||
|
||||
public IActivityBuilder StartWith<T>(Action<IActivityBuilder>? branch = default)
|
||||
where T : class, IActivity =>
|
||||
Add<T>(branch);
|
||||
|
||||
public IActivityBuilder Add<T>(
|
||||
Action<ISetupActivity<T>>? setup = default,
|
||||
Action<IActivityBuilder>? branch = default) where T : class, IActivity
|
||||
{
|
||||
var activityBuilder = New(setup, branch);
|
||||
return Add(activityBuilder, branch);
|
||||
}
|
||||
|
||||
public IActivityBuilder Add<T>(
|
||||
Action<IActivityBuilder>? branch = default,
|
||||
IDictionary<string, IActivityPropertyValueProvider>? propertyValueProviders = default)
|
||||
where T : class, IActivity
|
||||
{
|
||||
var activityBuilder = new ActivityBuilder(typeof(T), this, propertyValueProviders);
|
||||
return Add(activityBuilder);
|
||||
}
|
||||
|
||||
public IActivityBuilder Add(
|
||||
IActivityBuilder activityBuilder,
|
||||
Action<IActivityBuilder>? branch = default)
|
||||
{
|
||||
branch?.Invoke(activityBuilder);
|
||||
ActivityBuilders.Add(activityBuilder);
|
||||
return activityBuilder;
|
||||
}
|
||||
|
||||
public IConnectionBuilder Connect(
|
||||
IActivityBuilder source,
|
||||
IActivityBuilder target,
|
||||
string outcome = OutcomeNames.Done) =>
|
||||
Connect(() => source, () => target, outcome);
|
||||
|
||||
|
||||
public IConnectionBuilder Connect(
|
||||
Func<IActivityBuilder> source,
|
||||
Func<IActivityBuilder> target,
|
||||
string outcome = OutcomeNames.Done)
|
||||
{
|
||||
var connectionBuilder = new ConnectionBuilder(this, source, target, outcome);
|
||||
ConnectionBuilders.Add(connectionBuilder);
|
||||
return connectionBuilder;
|
||||
}
|
||||
|
||||
public ICompositeActivityBlueprint Build(string activityIdPrefix = "activity")
|
||||
{
|
||||
var activityBlueprints = new List<IActivityBlueprint>();
|
||||
var connections = new List<IConnection>();
|
||||
var activityPropertyProviders = new Dictionary<string, IDictionary<string, IActivityPropertyValueProvider>>();
|
||||
|
||||
// Assign automatic ids to activity builders
|
||||
var index = 0;
|
||||
|
||||
foreach (var activityBuilder in ActivityBuilders.Where(x => string.IsNullOrWhiteSpace(x.ActivityId)))
|
||||
activityBuilder.ActivityId = $"{activityIdPrefix}-{++index}";
|
||||
|
||||
activityBlueprints.AddRange(ActivityBuilders.Select(BuildActivityBlueprint));
|
||||
|
||||
// Build composite activities.
|
||||
var compositeActivityBuilders = ActivityBuilders.Where(x => x is ICompositeActivityBuilder).Cast<ICompositeActivityBuilder>();
|
||||
BuildCompositeActivities(compositeActivityBuilders, activityBlueprints, connections, activityPropertyProviders);
|
||||
|
||||
var activityBlueprintDictionary = activityBlueprints.ToDictionary(x => x.Id);
|
||||
|
||||
connections.AddRange(ConnectionBuilders.Select(x => new Connection(activityBlueprintDictionary[x.Source().ActivityId], activityBlueprintDictionary[x.Target().ActivityId], x.Outcome)));
|
||||
|
||||
activityPropertyProviders.AddRange(
|
||||
ActivityBuilders
|
||||
.Select(x => (x.ActivityId, x.PropertyValueProviders))
|
||||
.ToDictionary(x => x.ActivityId!, x => x.PropertyValueProviders!));
|
||||
|
||||
var workflow = new CompositeActivityBlueprint
|
||||
{
|
||||
Connections = connections,
|
||||
Activities = activityBlueprints,
|
||||
ActivityPropertyProviders = new ActivityPropertyProviders(activityPropertyProviders)
|
||||
};
|
||||
|
||||
return workflow;
|
||||
}
|
||||
|
||||
private void BuildCompositeActivities(
|
||||
IEnumerable<ICompositeActivityBuilder> activityBuilders,
|
||||
ICollection<IActivityBlueprint> activityBlueprints,
|
||||
ICollection<IConnection> connections,
|
||||
IDictionary<string, IDictionary<string, IActivityPropertyValueProvider>> activityPropertyProviders)
|
||||
{
|
||||
foreach (var activityBuilder in activityBuilders)
|
||||
{
|
||||
var compositeActivity = (CompositeActivity)_activityActivator.ActivateActivity(activityBuilder.ActivityType.Name);
|
||||
var workflowBuilder = _workflowBuilderFactory();
|
||||
|
||||
compositeActivity.Build(workflowBuilder);
|
||||
|
||||
var workflow = workflowBuilder.Build($"activity-{activityBuilder.ActivityId}:activity");
|
||||
var activityDictionary = workflow.Activities.ToDictionary(x => x.Id);
|
||||
|
||||
activityBlueprints.AddRange(workflow.Activities);
|
||||
connections.AddRange(workflow.Connections.Select(x => new Connection(activityDictionary[x.Source.Activity.Id], activityDictionary[x.Target.Activity.Id], x.Source.Outcome)));
|
||||
activityPropertyProviders.AddRange(workflow.ActivityPropertyProviders);
|
||||
|
||||
var compositeActivityBlueprint = (ICompositeActivityBlueprint)activityBlueprints.Single(x => x.Id == activityBuilder.ActivityId);
|
||||
compositeActivityBlueprint.Activities = workflow.Activities;
|
||||
}
|
||||
}
|
||||
|
||||
private IActivityBlueprint BuildActivityBlueprint(IActivityBuilder builder, int index)
|
||||
{
|
||||
var isComposite = typeof(CompositeActivity).IsAssignableFrom(builder.ActivityType);
|
||||
return isComposite
|
||||
? new CompositeActivityBlueprint(builder.ActivityId, builder.Name, builder.ActivityType.Name, builder.PersistWorkflow, builder.BuildActivityAsync())
|
||||
: new ActivityBlueprint(builder.ActivityId, builder.Name, builder.ActivityType.Name, builder.PersistWorkflow, builder.BuildActivityAsync());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,12 +4,12 @@ namespace Elsa.Builders
|
|||
{
|
||||
public class ConnectionBuilder : IConnectionBuilder
|
||||
{
|
||||
public IWorkflowBuilder WorkflowBuilder { get; }
|
||||
public ICompositeActivityBuilder WorkflowBuilder { get; }
|
||||
public Func<IActivityBuilder> Source { get; }
|
||||
public Func<IActivityBuilder> Target { get; }
|
||||
public string Outcome { get; }
|
||||
|
||||
public ConnectionBuilder(IWorkflowBuilder workflowBuilder, Func<IActivityBuilder> source, Func<IActivityBuilder> target, string outcome = OutcomeNames.Done)
|
||||
public ConnectionBuilder(ICompositeActivityBuilder workflowBuilder, Func<IActivityBuilder> source, Func<IActivityBuilder> target, string outcome = OutcomeNames.Done)
|
||||
{
|
||||
Source = source;
|
||||
Target = target;
|
||||
|
|
|
|||
|
|
@ -7,14 +7,14 @@ namespace Elsa.Builders
|
|||
{
|
||||
public class OutcomeBuilder : IOutcomeBuilder
|
||||
{
|
||||
public OutcomeBuilder(IWorkflowBuilder workflowBuilder, IActivityBuilder source, string outcome = "Done")
|
||||
public OutcomeBuilder(ICompositeActivityBuilder workflowBuilder, IActivityBuilder source, string outcome = "Done")
|
||||
{
|
||||
WorkflowBuilder = workflowBuilder;
|
||||
Source = source;
|
||||
Outcome = outcome;
|
||||
}
|
||||
|
||||
public IWorkflowBuilder WorkflowBuilder { get; }
|
||||
public ICompositeActivityBuilder WorkflowBuilder { get; }
|
||||
public IActivityBuilder Source { get; }
|
||||
public string Outcome { get; }
|
||||
|
||||
|
|
@ -41,6 +41,6 @@ namespace Elsa.Builders
|
|||
return activityBuilder;
|
||||
}
|
||||
|
||||
public IWorkflowBlueprint Build() => WorkflowBuilder.Build();
|
||||
public IWorkflowBlueprint Build() => ((IWorkflowBuilder)WorkflowBuilder).BuildBlueprint();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,40 +1,23 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Elsa.Models;
|
||||
using Elsa.Services;
|
||||
using Elsa.Services.Models;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using NetBox.Extensions;
|
||||
|
||||
namespace Elsa.Builders
|
||||
{
|
||||
public class WorkflowBuilder : IWorkflowBuilder
|
||||
public class WorkflowBuilder : CompositeActivityBuilder, IWorkflowBuilder
|
||||
{
|
||||
private readonly IIdGenerator _idGenerator;
|
||||
private readonly IActivityActivator _activityActivator;
|
||||
private readonly Func<IWorkflowBuilder> _workflowBuilderFactory;
|
||||
private readonly IList<IActivityBuilder> _activityBuilders;
|
||||
private readonly IList<IConnectionBuilder> _connectionBuilders;
|
||||
|
||||
public WorkflowBuilder(IIdGenerator idGenerator, IActivityActivator activityActivator, Func<IWorkflowBuilder> workflowBuilderFactory, IServiceProvider serviceProvider)
|
||||
public WorkflowBuilder(IIdGenerator idGenerator, IActivityActivator activityActivator, IServiceProvider serviceProvider) : base(
|
||||
idGenerator,
|
||||
activityActivator,
|
||||
serviceProvider)
|
||||
{
|
||||
_idGenerator = idGenerator;
|
||||
_activityActivator = activityActivator;
|
||||
_workflowBuilderFactory = workflowBuilderFactory;
|
||||
ServiceProvider = serviceProvider;
|
||||
Id = idGenerator.Generate();
|
||||
Version = 1;
|
||||
IsEnabled = true;
|
||||
Variables = new Variables();
|
||||
_activityBuilders = new List<IActivityBuilder>();
|
||||
_connectionBuilders = new List<IConnectionBuilder>();
|
||||
}
|
||||
|
||||
public IServiceProvider ServiceProvider { get; }
|
||||
public string Id { get; private set; }
|
||||
public string? Name { get; private set; }
|
||||
public string? Description { get; private set; }
|
||||
public int Version { get; private set; }
|
||||
public bool IsSingleton { get; private set; }
|
||||
|
||||
|
|
@ -43,19 +26,6 @@ namespace Elsa.Builders
|
|||
public WorkflowPersistenceBehavior PersistenceBehavior { get; private set; }
|
||||
public bool DeleteCompletedInstances { get; private set; }
|
||||
public bool IsEnabled { get; private set; }
|
||||
public IReadOnlyCollection<IActivityBuilder> Activities => _activityBuilders.ToList().AsReadOnly();
|
||||
|
||||
public IWorkflowBuilder WithId(string value)
|
||||
{
|
||||
Id = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IWorkflowBuilder WithName(string? value)
|
||||
{
|
||||
Name = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IWorkflowBuilder WithDescription(string? value)
|
||||
{
|
||||
|
|
@ -121,137 +91,27 @@ namespace Elsa.Builders
|
|||
return this;
|
||||
}
|
||||
|
||||
public IActivityBuilder New(
|
||||
Type activityType,
|
||||
IDictionary<string, IActivityPropertyValueProvider>? propertyValueProviders = default)
|
||||
{
|
||||
var activityBuilder = new ActivityBuilder(activityType, this, propertyValueProviders);
|
||||
return activityBuilder;
|
||||
}
|
||||
|
||||
public IActivityBuilder New<T>(
|
||||
Action<IActivityBuilder>? branch = default,
|
||||
IDictionary<string, IActivityPropertyValueProvider>? propertyValueProviders = default)
|
||||
where T : class, IActivity =>
|
||||
New(typeof(T), propertyValueProviders);
|
||||
|
||||
public IActivityBuilder New<T>(
|
||||
Action<ISetupActivity<T>>? setup = default,
|
||||
Action<IActivityBuilder>? branch = default) where T : class, IActivity
|
||||
{
|
||||
var propertyValuesBuilder = new SetupActivity<T>();
|
||||
setup?.Invoke(propertyValuesBuilder);
|
||||
|
||||
var valueProviders = propertyValuesBuilder.ValueProviders.ToDictionary(
|
||||
x => x.Key,
|
||||
x => (IActivityPropertyValueProvider)new DelegateActivityPropertyValueProvider(x.Value));
|
||||
|
||||
return New<T>(branch, valueProviders);
|
||||
}
|
||||
|
||||
public IActivityBuilder StartWith<T>(
|
||||
Action<ISetupActivity<T>>? setup = default,
|
||||
Action<IActivityBuilder>? branch = default) where T : class, IActivity
|
||||
{
|
||||
var activityBuilder = New(setup, branch);
|
||||
return Add(activityBuilder, branch);
|
||||
}
|
||||
|
||||
public IActivityBuilder StartWith<T>(Action<IActivityBuilder>? branch = default)
|
||||
where T : class, IActivity =>
|
||||
Add<T>(branch);
|
||||
|
||||
public IActivityBuilder Add<T>(
|
||||
Action<ISetupActivity<T>>? setup = default,
|
||||
Action<IActivityBuilder>? branch = default) where T : class, IActivity
|
||||
{
|
||||
var activityBuilder = New(setup, branch);
|
||||
return Add(activityBuilder, branch);
|
||||
}
|
||||
|
||||
public IActivityBuilder Add<T>(
|
||||
Action<IActivityBuilder>? branch = default,
|
||||
IDictionary<string, IActivityPropertyValueProvider>? propertyValueProviders = default)
|
||||
where T : class, IActivity
|
||||
{
|
||||
var activityBuilder = new ActivityBuilder(typeof(T), this, propertyValueProviders);
|
||||
return Add(activityBuilder);
|
||||
}
|
||||
|
||||
public IActivityBuilder Add(
|
||||
IActivityBuilder activityBuilder,
|
||||
Action<IActivityBuilder>? branch = default)
|
||||
{
|
||||
branch?.Invoke(activityBuilder);
|
||||
_activityBuilders.Add(activityBuilder);
|
||||
return activityBuilder;
|
||||
}
|
||||
|
||||
public IConnectionBuilder Connect(
|
||||
IActivityBuilder source,
|
||||
IActivityBuilder target,
|
||||
string outcome = OutcomeNames.Done) =>
|
||||
Connect(() => source, () => target, outcome);
|
||||
|
||||
|
||||
public IConnectionBuilder Connect(
|
||||
Func<IActivityBuilder> source,
|
||||
Func<IActivityBuilder> target,
|
||||
string outcome = OutcomeNames.Done)
|
||||
{
|
||||
var connectionBuilder = new ConnectionBuilder(this, source, target, outcome);
|
||||
_connectionBuilders.Add(connectionBuilder);
|
||||
return connectionBuilder;
|
||||
}
|
||||
|
||||
public IActivityBuilder Then<T>(
|
||||
Action<ISetupActivity<T>>? setup = default,
|
||||
Action<IActivityBuilder>? branch = default)
|
||||
where T : class, IActivity
|
||||
{
|
||||
var activityBuilder = New(setup, branch);
|
||||
return Add(activityBuilder, branch);
|
||||
}
|
||||
|
||||
public IActivityBuilder Then<T>(Action<IActivityBuilder>? branch = default)
|
||||
where T : class, IActivity =>
|
||||
StartWith<T>(branch);
|
||||
|
||||
public IWorkflowBlueprint Build(IWorkflow workflow, string activityIdPrefix = "activity")
|
||||
public IWorkflowBlueprint Build(IWorkflow workflow, string activityIdPrefix)
|
||||
{
|
||||
WithId(workflow.GetType().Name);
|
||||
workflow.Build(this);
|
||||
return Build(activityIdPrefix);
|
||||
return BuildBlueprint(activityIdPrefix);
|
||||
}
|
||||
|
||||
public IWorkflowBlueprint Build(Type workflowType, string activityIdPrefix)
|
||||
{
|
||||
var workflow = (IWorkflow)ActivatorUtilities.GetServiceOrCreateInstance(ServiceProvider, workflowType);
|
||||
return Build(workflow, activityIdPrefix);
|
||||
}
|
||||
|
||||
public IWorkflowBlueprint Build(string activityIdPrefix = "activity")
|
||||
public IWorkflowBlueprint Build<T>(string activityIdPrefix) where T : IWorkflow => Build(typeof(T), activityIdPrefix);
|
||||
|
||||
public IWorkflowBlueprint BuildBlueprint(string activityIdPrefix)
|
||||
{
|
||||
var definitionId = !string.IsNullOrWhiteSpace(Id) ? Id : _idGenerator.Generate();
|
||||
var activityBlueprints = new List<IActivityBlueprint>();
|
||||
var connections = new List<Connection>();
|
||||
var activityPropertyProviders = new Dictionary<string, IDictionary<string, IActivityPropertyValueProvider>>();
|
||||
|
||||
// Assign automatic ids to activity builders
|
||||
var index = 0;
|
||||
|
||||
foreach (var activityBuilder in _activityBuilders.Where(x => string.IsNullOrWhiteSpace(x.ActivityId)))
|
||||
activityBuilder.ActivityId = $"{activityIdPrefix}-{++index}";
|
||||
var compositeRoot = base.Build(activityIdPrefix);
|
||||
|
||||
activityBlueprints.AddRange(_activityBuilders.Select(BuildActivityBlueprint));
|
||||
|
||||
// Build composite activities.
|
||||
BuildCompositeActivities(_activityBuilders, activityBlueprints, connections, activityPropertyProviders);
|
||||
|
||||
var activityBlueprintDictionary = activityBlueprints.ToDictionary(x => x.Id);
|
||||
|
||||
connections.AddRange(_connectionBuilders.Select(x => new Connection(activityBlueprintDictionary[x.Source().ActivityId], activityBlueprintDictionary[x.Target().ActivityId], x.Outcome)));
|
||||
|
||||
activityPropertyProviders.AddRange(_activityBuilders
|
||||
.Select(x => (x.ActivityId, x.PropertyValueProviders))
|
||||
.ToDictionary(x => x.ActivityId!, x => x.PropertyValueProviders!));
|
||||
|
||||
var workflow = new WorkflowBlueprint(
|
||||
definitionId,
|
||||
return new WorkflowBlueprint(
|
||||
compositeRoot.Id,
|
||||
Version,
|
||||
IsSingleton,
|
||||
IsEnabled,
|
||||
|
|
@ -263,45 +123,9 @@ namespace Elsa.Builders
|
|||
ContextOptions,
|
||||
PersistenceBehavior,
|
||||
DeleteCompletedInstances,
|
||||
activityBlueprints,
|
||||
connections,
|
||||
new ActivityPropertyProviders(activityPropertyProviders));
|
||||
|
||||
return workflow;
|
||||
compositeRoot.Activities,
|
||||
compositeRoot.Connections,
|
||||
compositeRoot.ActivityPropertyProviders);
|
||||
}
|
||||
|
||||
private void BuildCompositeActivities(IEnumerable<IActivityBuilder> activityBuilders, ICollection<IActivityBlueprint> activityBlueprints, ICollection<Connection> connections, IDictionary<string, IDictionary<string, IActivityPropertyValueProvider>> activityPropertyProviders)
|
||||
{
|
||||
var compositeActivityType = typeof(CompositeActivity);
|
||||
var compositeActivityBuilders = activityBuilders.Where(x => compositeActivityType.IsAssignableFrom(x.ActivityType)).ToList();
|
||||
|
||||
foreach (var activityBuilder in compositeActivityBuilders)
|
||||
{
|
||||
var compositeActivity = (CompositeActivity)_activityActivator.ActivateActivity(activityBuilder.ActivityType.Name);
|
||||
var workflowBuilder = _workflowBuilderFactory();
|
||||
|
||||
compositeActivity.Build(workflowBuilder);
|
||||
|
||||
var workflow = workflowBuilder.Build($"composite-{activityBuilder.ActivityId}-activity");
|
||||
var activityDictionary = workflow.Activities.ToDictionary(x => x.Id);
|
||||
|
||||
activityBlueprints.AddRange(workflow.Activities);
|
||||
connections.AddRange(workflow.Connections.Select(x => new Connection(activityDictionary[x.Source.Activity.Id], activityDictionary[x.Target.Activity.Id], x.Source.Outcome)));
|
||||
activityPropertyProviders.AddRange(workflow.ActivityPropertyProviders);
|
||||
|
||||
var compositeActivityBlueprint = activityBlueprints.Single(x => x.Id == activityBuilder.ActivityId);
|
||||
compositeActivityBlueprint.ChildWorkflow = workflow;
|
||||
}
|
||||
}
|
||||
|
||||
public IWorkflowBlueprint Build(Type workflowType, string activityIdPrefix = "activity")
|
||||
{
|
||||
var workflow = (IWorkflow)ActivatorUtilities.GetServiceOrCreateInstance(ServiceProvider, workflowType);
|
||||
return Build(workflow, activityIdPrefix);
|
||||
}
|
||||
|
||||
public IWorkflowBlueprint Build<T>(string activityIdPrefix = "activity") where T : IWorkflow => Build(typeof(T), activityIdPrefix);
|
||||
|
||||
private IActivityBlueprint BuildActivityBlueprint(IActivityBuilder builder, int index) => new ActivityBlueprint(builder.ActivityId, builder.Name, builder.ActivityType.Name, builder.PersistWorkflow, builder.BuildActivityAsync());
|
||||
}
|
||||
}
|
||||
|
|
@ -116,6 +116,7 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
.AddWorkflowProvider<ProgrammaticWorkflowProvider>()
|
||||
.AddWorkflowProvider<StorageWorkflowProvider>()
|
||||
.AddTransient<IWorkflowBuilder, WorkflowBuilder>()
|
||||
.AddTransient<ICompositeActivityBuilder, CompositeActivityBuilder>()
|
||||
.AddTransient<Func<IWorkflowBuilder>>(sp => sp.GetRequiredService<IWorkflowBuilder>)
|
||||
.AddAutoMapperProfile<NodaTimeProfile>()
|
||||
.AddAutoMapperProfile<CloningProfile>()
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@ namespace Elsa.Samples.CompositeActivitiesConsole.Activities
|
|||
{
|
||||
public class CountDownActivity : CompositeActivity
|
||||
{
|
||||
public override void Build(IWorkflowBuilder workflowBuilder)
|
||||
public override void Build(ICompositeActivityBuilder composite)
|
||||
{
|
||||
workflowBuilder
|
||||
composite
|
||||
.WriteLine("3!")
|
||||
.WriteLine("2!")
|
||||
.WriteLine("1!");
|
||||
|
|
|
|||
Loading…
Reference in a new issue