Update Workflow builder API with support for property storage providers
This commit is contained in:
parent
f67140f7e2
commit
d787ca34ca
|
|
@ -14,6 +14,7 @@ namespace Elsa.Builders
|
|||
IActivityBuilder New<T>(
|
||||
string activityTypeName,
|
||||
IDictionary<string, IActivityPropertyValueProvider>? propertyValueProviders = default,
|
||||
IDictionary<string, string>? storageProviders = default,
|
||||
[CallerLineNumber] int lineNumber = default,
|
||||
[CallerFilePath] string? sourceFile = default)
|
||||
where T : class, IActivity;
|
||||
|
|
@ -44,6 +45,7 @@ namespace Elsa.Builders
|
|||
string activityTypeName,
|
||||
Action<IActivityBuilder>? branch = default,
|
||||
IDictionary<string, IActivityPropertyValueProvider>? propertyValueProviders = default,
|
||||
IDictionary<string, string>? storageProviders = default,
|
||||
[CallerLineNumber] int lineNumber = default,
|
||||
[CallerFilePath] string? sourceFile = default)
|
||||
where T : class, IActivity;
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ namespace Elsa.Builders
|
|||
public interface ISetupActivity<T> : ISetupActivity where T : IActivity
|
||||
{
|
||||
ISetupActivity<T> Set<TProperty>(Expression<Func<T, TProperty?>> propertyAccessor, Func<ActivityExecutionContext, ValueTask<TProperty?>> valueFactory);
|
||||
ISetupActivity<T> WithStorageFor<TProperty>(Expression<Func<T, TProperty?>> propertyAccessor, string? storageProviderName);
|
||||
}
|
||||
|
||||
public static class SetupActivityExtensions
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ namespace Elsa.Builders
|
|||
string activityTypeName,
|
||||
ICompositeActivityBuilder workflowBuilder,
|
||||
IDictionary<string, IActivityPropertyValueProvider>? propertyValueProviders,
|
||||
IDictionary<string, string>? storageProviders,
|
||||
int lineNumber,
|
||||
string? sourceFile)
|
||||
{
|
||||
|
|
@ -23,6 +24,7 @@ namespace Elsa.Builders
|
|||
ActivityTypeName = activityTypeName;
|
||||
WorkflowBuilder = workflowBuilder;
|
||||
PropertyValueProviders = propertyValueProviders;
|
||||
StorageProviders = storageProviders;
|
||||
LineNumber = lineNumber;
|
||||
SourceFile = sourceFile;
|
||||
}
|
||||
|
|
@ -42,6 +44,7 @@ namespace Elsa.Builders
|
|||
public bool LoadWorkflowContextEnabled { get; set; }
|
||||
public bool SaveWorkflowContextEnabled { get; set; }
|
||||
public IDictionary<string, IActivityPropertyValueProvider>? PropertyValueProviders { get; protected set; }
|
||||
public IDictionary<string, string>? StorageProviders { get; }
|
||||
public IDictionary<string, string> PropertyStorageProviders { get; set; } = new Dictionary<string, string>();
|
||||
public int LineNumber { get; }
|
||||
public string? SourceFile { get; }
|
||||
|
|
|
|||
|
|
@ -54,20 +54,22 @@ namespace Elsa.Builders
|
|||
Type activityType,
|
||||
string activityTypeName,
|
||||
IDictionary<string, IActivityPropertyValueProvider>? propertyValueProviders = default,
|
||||
IDictionary<string, string>? storageProviders = default,
|
||||
[CallerLineNumber] int lineNumber = default,
|
||||
[CallerFilePath] string? sourceFile = default)
|
||||
{
|
||||
var activityBuilder = new ActivityBuilder(activityType, activityTypeName, this, propertyValueProviders, lineNumber, sourceFile);
|
||||
var activityBuilder = new ActivityBuilder(activityType, activityTypeName, this, propertyValueProviders, storageProviders, lineNumber, sourceFile);
|
||||
return activityBuilder;
|
||||
}
|
||||
|
||||
public IActivityBuilder New<T>(
|
||||
string activityTypeName,
|
||||
IDictionary<string, IActivityPropertyValueProvider>? propertyValueProviders = default,
|
||||
IDictionary<string, string>? storageProviders = default,
|
||||
[CallerLineNumber] int lineNumber = default,
|
||||
[CallerFilePath] string? sourceFile = default)
|
||||
where T : class, IActivity =>
|
||||
New(typeof(T), activityTypeName, propertyValueProviders, lineNumber, sourceFile);
|
||||
New(typeof(T), activityTypeName, propertyValueProviders, storageProviders, lineNumber, sourceFile);
|
||||
|
||||
public IActivityBuilder New<T>(
|
||||
string activityTypeName,
|
||||
|
|
@ -82,7 +84,9 @@ namespace Elsa.Builders
|
|||
x => x.Key,
|
||||
x => (IActivityPropertyValueProvider) new DelegateActivityPropertyValueProvider(x.Value));
|
||||
|
||||
return New<T>(activityTypeName, valueProviders, lineNumber, sourceFile);
|
||||
var storageProviders = propertyValuesBuilder.StorageProviders;
|
||||
|
||||
return New<T>(activityTypeName, valueProviders, storageProviders, lineNumber, sourceFile);
|
||||
}
|
||||
|
||||
public IActivityBuilder StartWith<T>(
|
||||
|
|
@ -98,7 +102,7 @@ namespace Elsa.Builders
|
|||
|
||||
public IActivityBuilder StartWith<T>(string activityTypeName, Action<IActivityBuilder>? branch = default, [CallerLineNumber] int lineNumber = default, [CallerFilePath] string? sourceFile = default)
|
||||
where T : class, IActivity =>
|
||||
Add<T>(activityTypeName, branch, null, lineNumber, sourceFile);
|
||||
Add<T>(activityTypeName, branch, null, null, lineNumber, sourceFile);
|
||||
|
||||
public IActivityBuilder Add<T>(
|
||||
string activityTypeName,
|
||||
|
|
@ -115,11 +119,12 @@ namespace Elsa.Builders
|
|||
string activityTypeName,
|
||||
Action<IActivityBuilder>? branch = default,
|
||||
IDictionary<string, IActivityPropertyValueProvider>? propertyValueProviders = default,
|
||||
IDictionary<string, string>? storageProviders = default,
|
||||
[CallerLineNumber] int lineNumber = default,
|
||||
[CallerFilePath] string? sourceFile = default)
|
||||
where T : class, IActivity
|
||||
{
|
||||
var activityBuilder = new ActivityBuilder(typeof(T), activityTypeName, this, propertyValueProviders, lineNumber, sourceFile);
|
||||
var activityBuilder = new ActivityBuilder(typeof(T), activityTypeName, this, propertyValueProviders, storageProviders, lineNumber, sourceFile);
|
||||
return Add(activityBuilder, branch);
|
||||
}
|
||||
|
||||
|
|
@ -215,6 +220,8 @@ namespace Elsa.Builders
|
|||
|
||||
return compositeActivityBlueprint;
|
||||
}
|
||||
|
||||
protected virtual string? GetCompositeName(string? activityName) => activityName == null ? null : $"{ActivityId}:{activityName}";
|
||||
|
||||
private void BuildCompositeActivities(
|
||||
IEnumerable<IActivityBuilder> compositeActivityBuilders,
|
||||
|
|
@ -237,9 +244,9 @@ namespace Elsa.Builders
|
|||
connections.AddRange(compositeActivityBlueprint.Connections.Select(x => new Connection(activityDictionary[x.Source.Activity.Id], activityDictionary[x.Target.Activity.Id], x.Source.Outcome)));
|
||||
activityPropertyProviders.AddRange(compositeActivityBlueprint.ActivityPropertyProviders);
|
||||
|
||||
compositeActivityBlueprint.Activities = compositeActivityBlueprint.Activities;
|
||||
compositeActivityBlueprint.Connections = compositeActivityBlueprint.Connections;
|
||||
compositeActivityBlueprint.ActivityPropertyProviders = compositeActivityBlueprint.ActivityPropertyProviders;
|
||||
// compositeActivityBlueprint.Activities = compositeActivityBlueprint.Activities;
|
||||
// compositeActivityBlueprint.Connections = compositeActivityBlueprint.Connections;
|
||||
// compositeActivityBlueprint.ActivityPropertyProviders = compositeActivityBlueprint.ActivityPropertyProviders;
|
||||
|
||||
// Connect the composite activity to its starting activities.
|
||||
var startActivities = _startingActivitiesProvider.GetStartActivities(compositeActivityBlueprint).ToList();
|
||||
|
|
@ -257,6 +264,5 @@ namespace Elsa.Builders
|
|||
builder.SaveWorkflowContextEnabled, builder.PropertyStorageProviders, builder.Source);
|
||||
}
|
||||
|
||||
private string? GetCompositeName(string? activityName) => activityName == null ? null : $"{ActivityId}:{activityName}";
|
||||
}
|
||||
}
|
||||
|
|
@ -11,9 +11,10 @@ namespace Elsa.Builders
|
|||
public static IActivityBuilder New<T>(
|
||||
this ICompositeActivityBuilder compositeActivityBuilder,
|
||||
IDictionary<string, IActivityPropertyValueProvider>? propertyValueProviders = default,
|
||||
IDictionary<string, string>? storageProviders = default,
|
||||
[CallerLineNumber] int lineNumber = default,
|
||||
[CallerFilePath] string? sourceFile = default)
|
||||
where T : class, IActivity => compositeActivityBuilder.New<T>(typeof(T).Name, propertyValueProviders, lineNumber, sourceFile);
|
||||
where T : class, IActivity => compositeActivityBuilder.New<T>(typeof(T).Name, propertyValueProviders, storageProviders, lineNumber, sourceFile);
|
||||
|
||||
public static IActivityBuilder New<T>(
|
||||
this ICompositeActivityBuilder compositeActivityBuilder,
|
||||
|
|
@ -45,8 +46,9 @@ namespace Elsa.Builders
|
|||
this ICompositeActivityBuilder compositeActivityBuilder,
|
||||
Action<IActivityBuilder>? branch = default,
|
||||
IDictionary<string, IActivityPropertyValueProvider>? propertyValueProviders = default,
|
||||
IDictionary<string, string>? storageProviders = default,
|
||||
[CallerLineNumber] int lineNumber = default,
|
||||
[CallerFilePath] string? sourceFile = default)
|
||||
where T : class, IActivity => compositeActivityBuilder.Add<T>(typeof(T).Name, branch, propertyValueProviders, lineNumber, sourceFile);
|
||||
where T : class, IActivity => compositeActivityBuilder.Add<T>(typeof(T).Name, branch, propertyValueProviders, storageProviders, lineNumber, sourceFile);
|
||||
}
|
||||
}
|
||||
|
|
@ -35,7 +35,7 @@ namespace Elsa.Builders
|
|||
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>(activityTypeName, branch, null, lineNumber, sourceFile);
|
||||
var activityBuilder = WorkflowBuilder.Add<T>(activityTypeName, branch, null, null, lineNumber, sourceFile);
|
||||
Then(activityBuilder);
|
||||
return activityBuilder;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ namespace Elsa.Builders
|
|||
public class SetupActivity<T> : ISetupActivity<T> where T : IActivity
|
||||
{
|
||||
public IDictionary<string, Func<ActivityExecutionContext, ValueTask<object?>>> ValueProviders { get; } = new Dictionary<string, Func<ActivityExecutionContext, ValueTask<object?>>>();
|
||||
public IDictionary<string, string> StorageProviders { get; } = new Dictionary<string, string>();
|
||||
|
||||
public ISetupActivity<T> Set<TProperty>(Expression<Func<T, TProperty?>> propertyAccessor, Func<ActivityExecutionContext, ValueTask<TProperty?>> valueFactory)
|
||||
{
|
||||
|
|
@ -17,5 +18,17 @@ namespace Elsa.Builders
|
|||
ValueProviders[propertyInfo.Name] = async context => await valueFactory(context);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ISetupActivity<T> WithStorageFor<TProperty>(Expression<Func<T, TProperty?>> propertyAccessor, string? storageProviderName)
|
||||
{
|
||||
var propertyInfo = propertyAccessor.GetProperty()!;
|
||||
|
||||
if(storageProviderName != null)
|
||||
StorageProviders[propertyInfo.Name] = storageProviderName;
|
||||
else
|
||||
StorageProviders.Remove(propertyInfo.Name);
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -178,5 +178,8 @@ namespace Elsa.Builders
|
|||
compositeRoot.Connections,
|
||||
compositeRoot.ActivityPropertyProviders);
|
||||
}
|
||||
|
||||
// Do not qualify root activities.
|
||||
protected override string? GetCompositeName(string? activityName) => activityName;
|
||||
}
|
||||
}
|
||||
13
src/core/Elsa.Core/Extensions/SetupActivityExtensions.cs
Normal file
13
src/core/Elsa.Core/Extensions/SetupActivityExtensions.cs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
using System;
|
||||
using System.Linq.Expressions;
|
||||
using Elsa.Builders;
|
||||
using Elsa.Services;
|
||||
|
||||
namespace Elsa
|
||||
{
|
||||
public static class SetupActivityExtensions
|
||||
{
|
||||
public static ISetupActivity<T> WithTransientStorageFor<T, TProperty>(this ISetupActivity<T> builder, Expression<Func<T, TProperty?>> propertyAccessor) where T : IActivity => builder.WithStorageFor(propertyAccessor, "Transient");
|
||||
public static ISetupActivity<T> WithWorkflowInstanceStorageFor<T, TProperty>(this ISetupActivity<T> builder, Expression<Func<T, TProperty?>> propertyAccessor) where T : IActivity => builder.WithStorageFor(propertyAccessor, "WorkflowInstance");
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue