diff --git a/src/modules/Elsa.Workflows.Core/Activities/SetName.cs b/src/modules/Elsa.Workflows.Core/Activities/SetName.cs
index 3c4fbf1df..82e565c49 100644
--- a/src/modules/Elsa.Workflows.Core/Activities/SetName.cs
+++ b/src/modules/Elsa.Workflows.Core/Activities/SetName.cs
@@ -1,4 +1,5 @@
using System.Runtime.CompilerServices;
+using Elsa.Extensions;
using Elsa.Workflows.Attributes;
using Elsa.Workflows.Models;
using JetBrains.Annotations;
@@ -12,18 +13,13 @@ namespace Elsa.Workflows.Activities;
[PublicAPI]
public class SetName : CodeActivity
{
- ///
- /// The property key name used to store the workflow instance name.
- ///
- public const string WorkflowInstanceNameKey = "WorkflowInstanceName";
-
///
- public SetName([CallerFilePath] string? source = default, [CallerLineNumber] int? line = default) : base(source, line)
+ public SetName([CallerFilePath] string? source = null, [CallerLineNumber] int? line = null) : base(source, line)
{
}
///
- public SetName(Input value, [CallerFilePath] string? source = default, [CallerLineNumber] int? line = default) : this(source, line)
+ public SetName(Input value, [CallerFilePath] string? source = null, [CallerLineNumber] int? line = null) : this(source, line)
{
Value = value;
}
@@ -36,7 +32,7 @@ public class SetName : CodeActivity
///
protected override void Execute(ActivityExecutionContext context)
{
- var value = context.Get(Value);
- context.WorkflowExecutionContext.SetProperty(WorkflowInstanceNameKey, value!);
+ var value = Value.GetOrDefault(context);
+ context.WorkflowExecutionContext.Name = value;
}
}
\ No newline at end of file
diff --git a/src/modules/Elsa.Workflows.Core/Contexts/WorkflowExecutionContext.cs b/src/modules/Elsa.Workflows.Core/Contexts/WorkflowExecutionContext.cs
index 345295d32..f57350d48 100644
--- a/src/modules/Elsa.Workflows.Core/Contexts/WorkflowExecutionContext.cs
+++ b/src/modules/Elsa.Workflows.Core/Contexts/WorkflowExecutionContext.cs
@@ -71,8 +71,8 @@ public partial class WorkflowExecutionContext : IExecutionContext
_activityExecutionContexts = new List();
Scheduler = serviceProvider.GetRequiredService().CreateScheduler();
IdentityGenerator = serviceProvider.GetRequiredService();
- Input = input != null ? new Dictionary(input, StringComparer.OrdinalIgnoreCase) : new Dictionary(StringComparer.OrdinalIgnoreCase);
- Properties = properties != null ? new Dictionary(properties, StringComparer.OrdinalIgnoreCase) : new Dictionary(StringComparer.OrdinalIgnoreCase);
+ Input = input != null ? new(input, StringComparer.OrdinalIgnoreCase) : new Dictionary(StringComparer.OrdinalIgnoreCase);
+ Properties = properties != null ? new(properties, StringComparer.OrdinalIgnoreCase) : new Dictionary(StringComparer.OrdinalIgnoreCase);
ExecuteDelegate = executeDelegate;
TriggerActivityId = triggerActivityId;
CreatedAt = createdAt;
@@ -193,7 +193,7 @@ public partial class WorkflowExecutionContext : IExecutionContext
MemoryRegister = workflowGraph.Workflow.CreateRegister()
};
- workflowExecutionContext.ExpressionExecutionContext = new ExpressionExecutionContext(serviceProvider, workflowExecutionContext.MemoryRegister, cancellationToken: cancellationToken);
+ workflowExecutionContext.ExpressionExecutionContext = new(serviceProvider, workflowExecutionContext.MemoryRegister, cancellationToken: cancellationToken);
await workflowExecutionContext.SetWorkflowGraphAsync(workflowGraph);
return workflowExecutionContext;
@@ -253,6 +253,9 @@ public partial class WorkflowExecutionContext : IExecutionContext
/// An application-specific identifier associated with the execution context.
public string? CorrelationId { get; set; }
+ /// Gets or sets the name of the workflow instance.
+ public string? Name { get; set; }
+
/// The ID of the workflow instance that triggered this instance.
public string? ParentWorkflowInstanceId { get; set; }
diff --git a/src/modules/Elsa.Workflows.Core/Serialization/Serializers/JsonWorkflowStateSerializer.cs b/src/modules/Elsa.Workflows.Core/Serialization/Serializers/JsonWorkflowStateSerializer.cs
index d23869f4a..ad664f7e8 100644
--- a/src/modules/Elsa.Workflows.Core/Serialization/Serializers/JsonWorkflowStateSerializer.cs
+++ b/src/modules/Elsa.Workflows.Core/Serialization/Serializers/JsonWorkflowStateSerializer.cs
@@ -128,7 +128,7 @@ public class JsonWorkflowStateSerializer : ConfigurableSerializer, IWorkflowStat
public override JsonSerializerOptions GetOptions()
{
var options = base.GetOptions();
- return new JsonSerializerOptions(options)
+ return new(options)
{
ReferenceHandler = new CrossScopedReferenceHandler()
};
diff --git a/src/modules/Elsa.Workflows.Core/Services/WorkflowRunner.cs b/src/modules/Elsa.Workflows.Core/Services/WorkflowRunner.cs
index a79842799..46ae8efdb 100644
--- a/src/modules/Elsa.Workflows.Core/Services/WorkflowRunner.cs
+++ b/src/modules/Elsa.Workflows.Core/Services/WorkflowRunner.cs
@@ -25,7 +25,7 @@ public class WorkflowRunner(
: IWorkflowRunner
{
///
- public async Task RunAsync(IActivity activity, RunWorkflowOptions? options = default, CancellationToken cancellationToken = default)
+ public async Task RunAsync(IActivity activity, RunWorkflowOptions? options = null, CancellationToken cancellationToken = default)
{
var workflow = Workflow.FromActivity(activity);
var workflowGraph = await workflowGraphBuilder.BuildAsync(workflow, cancellationToken);
@@ -33,7 +33,7 @@ public class WorkflowRunner(
}
///
- public async Task RunAsync(IWorkflow workflow, RunWorkflowOptions? options = default, CancellationToken cancellationToken = default)
+ public async Task RunAsync(IWorkflow workflow, RunWorkflowOptions? options = null, CancellationToken cancellationToken = default)
{
var builder = workflowBuilderFactory.CreateBuilder();
var workflowDefinition = await builder.BuildWorkflowAsync(workflow, cancellationToken);
@@ -41,14 +41,14 @@ public class WorkflowRunner(
}
///
- public async Task> RunAsync(WorkflowBase workflow, RunWorkflowOptions? options = default, CancellationToken cancellationToken = default)
+ public async Task> RunAsync(WorkflowBase workflow, RunWorkflowOptions? options = null, CancellationToken cancellationToken = default)
{
var result = await RunAsync((IWorkflow)workflow, options, cancellationToken);
return new(result.WorkflowState, result.Workflow, (TResult)result.Result!);
}
///
- public async Task RunAsync(RunWorkflowOptions? options = default, CancellationToken cancellationToken = default) where T : IWorkflow, new()
+ public async Task RunAsync(RunWorkflowOptions? options = null, CancellationToken cancellationToken = default) where T : IWorkflow, new()
{
var builder = workflowBuilderFactory.CreateBuilder();
var workflowDefinition = await builder.BuildWorkflowAsync(cancellationToken);
@@ -56,7 +56,7 @@ public class WorkflowRunner(
}
///
- public async Task RunAsync(RunWorkflowOptions? options = default, CancellationToken cancellationToken = default) where T : WorkflowBase, new()
+ public async Task RunAsync(RunWorkflowOptions? options = null, CancellationToken cancellationToken = default) where T : WorkflowBase, new()
{
var builder = workflowBuilderFactory.CreateBuilder();
var workflow = await builder.BuildWorkflowAsync(cancellationToken);
@@ -65,7 +65,7 @@ public class WorkflowRunner(
}
///
- public async Task RunAsync(WorkflowGraph workflowGraph, RunWorkflowOptions? options = default, CancellationToken cancellationToken = default)
+ public async Task RunAsync(WorkflowGraph workflowGraph, RunWorkflowOptions? options = null, CancellationToken cancellationToken = default)
{
// Set up a workflow execution context.
var instanceId = options?.WorkflowInstanceId ?? identityGenerator.GenerateId();
@@ -82,7 +82,7 @@ public class WorkflowRunner(
parentWorkflowInstanceId,
input,
properties,
- default,
+ null,
triggerActivityId,
cancellationToken);
@@ -93,21 +93,21 @@ public class WorkflowRunner(
}
///
- public async Task RunAsync(Workflow workflow, RunWorkflowOptions? options = default, CancellationToken cancellationToken = default)
+ public async Task RunAsync(Workflow workflow, RunWorkflowOptions? options = null, CancellationToken cancellationToken = default)
{
var workflowGraph = await workflowGraphBuilder.BuildAsync(workflow, cancellationToken);
return await RunAsync(workflowGraph, options, cancellationToken);
}
///
- public async Task RunAsync(Workflow workflow, WorkflowState workflowState, RunWorkflowOptions? options = default, CancellationToken cancellationToken = default)
+ public async Task RunAsync(Workflow workflow, WorkflowState workflowState, RunWorkflowOptions? options = null, CancellationToken cancellationToken = default)
{
var workflowGraph = await workflowGraphBuilder.BuildAsync(workflow, cancellationToken);
return await RunAsync(workflowGraph, workflowState, options, cancellationToken);
}
///
- public async Task RunAsync(WorkflowGraph workflowGraph, WorkflowState workflowState, RunWorkflowOptions? options = default, CancellationToken cancellationToken = default)
+ public async Task RunAsync(WorkflowGraph workflowGraph, WorkflowState workflowState, RunWorkflowOptions? options = null, CancellationToken cancellationToken = default)
{
// Create a workflow execution context.
var input = options?.Input;
@@ -123,7 +123,7 @@ public class WorkflowRunner(
parentWorkflowInstanceId,
input,
properties,
- default,
+ null,
triggerActivityId,
cancellationToken);
diff --git a/src/modules/Elsa.Workflows.Core/Services/WorkflowStateExtractor.cs b/src/modules/Elsa.Workflows.Core/Services/WorkflowStateExtractor.cs
index 99a11a214..e63e1c92c 100644
--- a/src/modules/Elsa.Workflows.Core/Services/WorkflowStateExtractor.cs
+++ b/src/modules/Elsa.Workflows.Core/Services/WorkflowStateExtractor.cs
@@ -18,6 +18,7 @@ public class WorkflowStateExtractor : IWorkflowStateExtractor
DefinitionVersionId = workflowExecutionContext.Workflow.Identity.Id,
DefinitionVersion = workflowExecutionContext.Workflow.Identity.Version,
CorrelationId = workflowExecutionContext.CorrelationId,
+ Name = workflowExecutionContext.Name,
ParentWorkflowInstanceId = workflowExecutionContext.ParentWorkflowInstanceId,
Status = workflowExecutionContext.Status,
SubStatus = workflowExecutionContext.SubStatus,
@@ -45,6 +46,7 @@ public class WorkflowStateExtractor : IWorkflowStateExtractor
{
workflowExecutionContext.Id = state.Id;
workflowExecutionContext.CorrelationId = state.CorrelationId;
+ workflowExecutionContext.Name = state.Name;
workflowExecutionContext.ParentWorkflowInstanceId = state.ParentWorkflowInstanceId;
workflowExecutionContext.SubStatus = state.SubStatus;
workflowExecutionContext.Bookmarks = state.Bookmarks;
diff --git a/src/modules/Elsa.Workflows.Core/State/WorkflowState.cs b/src/modules/Elsa.Workflows.Core/State/WorkflowState.cs
index 8bc2cd1a0..43887b16b 100644
--- a/src/modules/Elsa.Workflows.Core/State/WorkflowState.cs
+++ b/src/modules/Elsa.Workflows.Core/State/WorkflowState.cs
@@ -11,17 +11,17 @@ public class WorkflowState
///
/// Gets or sets the ID.
///
- public string Id { get; set; } = default!;
+ public string Id { get; set; } = null!;
///
/// The workflow definition ID.
///
- public string DefinitionId { get; set; } = default!;
+ public string DefinitionId { get; set; } = null!;
///
/// The workflow definition version ID.
///
- public string DefinitionVersionId { get; set; } = default!;
+ public string DefinitionVersionId { get; set; } = null!;
///
/// The workflow definition version.
@@ -37,6 +37,11 @@ public class WorkflowState
/// The correlation ID of the workflow, if any.
///
public string? CorrelationId { get; set; }
+
+ ///
+ /// Gets or sets the name of the workflow instance.
+ ///
+ public string? Name { get; set; }
///
/// The status of the workflow.
diff --git a/src/modules/Elsa.Workflows.Management/Mappers/WorkflowStateMapper.cs b/src/modules/Elsa.Workflows.Management/Mappers/WorkflowStateMapper.cs
index 30af5ac0c..c909073db 100644
--- a/src/modules/Elsa.Workflows.Management/Mappers/WorkflowStateMapper.cs
+++ b/src/modules/Elsa.Workflows.Management/Mappers/WorkflowStateMapper.cs
@@ -1,5 +1,3 @@
-using Elsa.Extensions;
-using Elsa.Workflows.Activities;
using Elsa.Workflows.Management.Entities;
using Elsa.Workflows.State;
@@ -16,14 +14,14 @@ public class WorkflowStateMapper
public WorkflowInstance? Map(WorkflowState? source)
{
if (source == null)
- return default;
+ return null;
var workflowInstance = new WorkflowInstance();
Apply(source, workflowInstance);
return workflowInstance;
}
-
+
///
/// Maps a workflow state to a workflow instance.
///
@@ -38,14 +36,12 @@ public class WorkflowStateMapper
target.Status = source.Status;
target.SubStatus = source.SubStatus;
target.CorrelationId = source.CorrelationId;
+ target.Name = source.Name;
target.IncidentCount = source.Incidents.Count;
target.IsSystem = source.IsSystem;
target.UpdatedAt = source.UpdatedAt;
target.FinishedAt = source.FinishedAt;
target.WorkflowState = source;
-
- if (source.Properties.TryGetValue(SetName.WorkflowInstanceNameKey, out var name))
- target.Name = name;
}
///
@@ -54,7 +50,7 @@ public class WorkflowStateMapper
public WorkflowState? Map(WorkflowInstance? source)
{
if (source == null)
- return default;
+ return null;
var workflowState = source.WorkflowState;
workflowState.Id = source.Id;
@@ -66,13 +62,11 @@ public class WorkflowStateMapper
workflowState.Status = source.Status;
workflowState.SubStatus = source.SubStatus;
workflowState.CorrelationId = source.CorrelationId;
+ workflowState.Name = source.Name;
workflowState.UpdatedAt = source.UpdatedAt;
workflowState.FinishedAt = source.FinishedAt;
workflowState.IsSystem = source.IsSystem;
- if (source.Name != null)
- workflowState.Properties[SetName.WorkflowInstanceNameKey] = source.Name;
-
return workflowState;
}
}
\ No newline at end of file
diff --git a/src/modules/Elsa.Workflows.Management/Options/WorkflowInstanceOptions.cs b/src/modules/Elsa.Workflows.Management/Options/WorkflowInstanceOptions.cs
index 9cdc133ad..76051aed2 100644
--- a/src/modules/Elsa.Workflows.Management/Options/WorkflowInstanceOptions.cs
+++ b/src/modules/Elsa.Workflows.Management/Options/WorkflowInstanceOptions.cs
@@ -13,6 +13,11 @@ public class WorkflowInstanceOptions
///
public string? CorrelationId { get; set; }
+ ///
+ /// The name of the workflow instance.
+ ///
+ public string? Name { get; set; }
+
///
/// The input to the workflow instance, if any.
///
diff --git a/src/modules/Elsa.Workflows.Management/Services/WorkflowInstanceFactory.cs b/src/modules/Elsa.Workflows.Management/Services/WorkflowInstanceFactory.cs
index 9175158d4..aada085a6 100644
--- a/src/modules/Elsa.Workflows.Management/Services/WorkflowInstanceFactory.cs
+++ b/src/modules/Elsa.Workflows.Management/Services/WorkflowInstanceFactory.cs
@@ -14,13 +14,14 @@ public class WorkflowInstanceFactory(IIdentityGenerator identityGenerator, ISyst
public WorkflowState CreateWorkflowState(Workflow workflow, WorkflowInstanceOptions? options = null)
{
var now = systemClock.UtcNow;
- return new WorkflowState
+ return new()
{
Id = string.IsNullOrEmpty(options?.WorkflowInstanceId) ? identityGenerator.GenerateId() : options.WorkflowInstanceId,
DefinitionId = workflow.Identity.DefinitionId,
DefinitionVersionId = workflow.Identity.Id,
DefinitionVersion = workflow.Identity.Version,
CorrelationId = options?.CorrelationId,
+ Name = options?.Name,
Input = options?.Input ?? new Dictionary(),
Properties = options?.Properties ?? new Dictionary(),
Status = WorkflowStatus.Running,
@@ -36,7 +37,7 @@ public class WorkflowInstanceFactory(IIdentityGenerator identityGenerator, ISyst
public WorkflowInstance CreateWorkflowInstance(Workflow workflow, WorkflowInstanceOptions? options = null)
{
var workflowState = CreateWorkflowState(workflow, options);
- return new WorkflowInstance
+ return new()
{
Id = workflowState.Id,
ParentWorkflowInstanceId = workflowState.ParentWorkflowInstanceId,
@@ -45,6 +46,7 @@ public class WorkflowInstanceFactory(IIdentityGenerator identityGenerator, ISyst
DefinitionVersionId = workflowState.DefinitionVersionId,
Version = workflowState.DefinitionVersion,
CorrelationId = workflowState.CorrelationId,
+ Name = workflowState.Name,
Status = workflowState.Status,
SubStatus = workflowState.SubStatus,
IncidentCount = workflowState.Incidents.Count,
diff --git a/src/modules/Elsa.Workflows.Runtime.ProtoActor/Mappers/CreateAndRunWorkflowInstanceRequestMapper.cs b/src/modules/Elsa.Workflows.Runtime.ProtoActor/Mappers/CreateAndRunWorkflowInstanceRequestMapper.cs
index 14caababa..b81c07960 100644
--- a/src/modules/Elsa.Workflows.Runtime.ProtoActor/Mappers/CreateAndRunWorkflowInstanceRequestMapper.cs
+++ b/src/modules/Elsa.Workflows.Runtime.ProtoActor/Mappers/CreateAndRunWorkflowInstanceRequestMapper.cs
@@ -23,6 +23,7 @@ public class CreateAndRunWorkflowInstanceRequestMapper(WorkflowDefinitionHandleM
WorkflowDefinitionHandle = workflowDefinitionHandleMapper.Map(source.WorkflowDefinitionHandle),
WorkflowInstanceId = workflowInstanceId.EmptyIfNull(),
CorrelationId = source.CorrelationId.EmptyIfNull(),
+ Name = source.Name.EmptyIfNull(),
ParentId = source.ParentId.EmptyIfNull(),
Input = source.Input?.SerializeInput() ?? new ProtoInput(),
Properties = source.Properties?.SerializeProperties() ?? new ProtoProperties(),
@@ -41,8 +42,9 @@ public class CreateAndRunWorkflowInstanceRequestMapper(WorkflowDefinitionHandleM
return new()
{
WorkflowDefinitionHandle = workflowDefinitionHandleMapper.Map(source.WorkflowDefinitionHandle),
- CorrelationId = source.CorrelationId,
- ParentId = source.ParentId,
+ CorrelationId = source.CorrelationId.NullIfEmpty(),
+ Name = source.Name.NullIfEmpty(),
+ ParentId = source.ParentId.NullIfEmpty(),
Input = source.Input?.DeserializeInput(),
Properties = source.Properties?.DeserializeProperties(),
ActivityHandle = activityHandleMapper.Map(source.ActivityHandle),
diff --git a/src/modules/Elsa.Workflows.Runtime.ProtoActor/Mappers/CreateWorkflowInstanceRequestMapper.cs b/src/modules/Elsa.Workflows.Runtime.ProtoActor/Mappers/CreateWorkflowInstanceRequestMapper.cs
index 2c0358ebe..0d8ce651a 100644
--- a/src/modules/Elsa.Workflows.Runtime.ProtoActor/Mappers/CreateWorkflowInstanceRequestMapper.cs
+++ b/src/modules/Elsa.Workflows.Runtime.ProtoActor/Mappers/CreateWorkflowInstanceRequestMapper.cs
@@ -24,6 +24,7 @@ public class CreateWorkflowInstanceRequestMapper(WorkflowDefinitionHandleMapper
WorkflowDefinitionHandle = workflowDefinitionHandleMapper.Map(source.WorkflowDefinitionHandle),
WorkflowInstanceId = workflowInstanceId,
CorrelationId = source.CorrelationId.EmptyIfNull(),
+ Name = source.Name.EmptyIfNull(),
ParentId = source.ParentId.EmptyIfNull(),
Input = source.Input?.SerializeInput() ?? new ProtoInput(),
Properties = source.Properties?.SerializeProperties() ?? new ProtoProperties()
@@ -40,8 +41,9 @@ public class CreateWorkflowInstanceRequestMapper(WorkflowDefinitionHandleMapper
return new()
{
WorkflowDefinitionHandle = workflowDefinitionHandleMapper.Map(source.WorkflowDefinitionHandle),
- CorrelationId = source.CorrelationId,
- ParentId = source.ParentId,
+ CorrelationId = source.CorrelationId.NullIfEmpty(),
+ Name = source.Name.NullIfEmpty(),
+ ParentId = source.ParentId.NullIfEmpty(),
Input = source.Input?.DeserializeInput(),
Properties = source.Properties?.DeserializeProperties()
};
diff --git a/src/modules/Elsa.Workflows.Runtime.ProtoActor/Proto/WorkflowInstance.Messages.proto b/src/modules/Elsa.Workflows.Runtime.ProtoActor/Proto/WorkflowInstance.Messages.proto
index 719572c28..bb1683fab 100644
--- a/src/modules/Elsa.Workflows.Runtime.ProtoActor/Proto/WorkflowInstance.Messages.proto
+++ b/src/modules/Elsa.Workflows.Runtime.ProtoActor/Proto/WorkflowInstance.Messages.proto
@@ -45,9 +45,10 @@ message CreateWorkflowInstanceRequest{
WorkflowDefinitionHandle WorkflowDefinitionHandle = 1;
string WorkflowInstanceId = 2;
optional string CorrelationId = 3;
- optional string ParentId = 4;
- optional Input input = 5;
- optional Properties properties = 6;
+ optional string Name = 4;
+ optional string ParentId = 5;
+ optional Input input = 6;
+ optional Properties properties = 7;
}
message CreateWorkflowInstanceResponse{
@@ -71,11 +72,12 @@ message CreateAndRunWorkflowInstanceRequest{
WorkflowDefinitionHandle WorkflowDefinitionHandle = 1;
string WorkflowInstanceId = 2;
optional string CorrelationId = 3;
- optional string ParentId = 4;
- optional Input input = 5;
- optional Properties properties = 6;
- optional ActivityHandle ActivityHandle = 7;
- optional string TriggerActivityId = 8;
+ optional string Name = 4;
+ optional string ParentId = 5;
+ optional Input input = 6;
+ optional Properties properties = 7;
+ optional ActivityHandle ActivityHandle = 8;
+ optional string TriggerActivityId = 9;
}
message ExportWorkflowStateResponse {
diff --git a/src/modules/Elsa.Workflows.Runtime/Messages/CreateAndRunWorkflowInstanceRequest.cs b/src/modules/Elsa.Workflows.Runtime/Messages/CreateAndRunWorkflowInstanceRequest.cs
index 07c812077..69901ec03 100644
--- a/src/modules/Elsa.Workflows.Runtime/Messages/CreateAndRunWorkflowInstanceRequest.cs
+++ b/src/modules/Elsa.Workflows.Runtime/Messages/CreateAndRunWorkflowInstanceRequest.cs
@@ -12,12 +12,17 @@ public class CreateAndRunWorkflowInstanceRequest
///
/// The ID of the workflow definition version to create an instance of.
///
- public WorkflowDefinitionHandle WorkflowDefinitionHandle { get; set; } = default!;
+ public WorkflowDefinitionHandle WorkflowDefinitionHandle { get; set; } = null!;
///
/// The correlation ID of the workflow, if any.
///
public string? CorrelationId { get; set; }
+
+ ///
+ /// The name of the workflow instance to be created.
+ ///
+ public string? Name { get; set; }
///
/// The input to the workflow instance, if any.
diff --git a/src/modules/Elsa.Workflows.Runtime/Messages/CreateWorkflowInstanceRequest.cs b/src/modules/Elsa.Workflows.Runtime/Messages/CreateWorkflowInstanceRequest.cs
index ab55c3891..8cebf9d6f 100644
--- a/src/modules/Elsa.Workflows.Runtime/Messages/CreateWorkflowInstanceRequest.cs
+++ b/src/modules/Elsa.Workflows.Runtime/Messages/CreateWorkflowInstanceRequest.cs
@@ -12,13 +12,18 @@ public class CreateWorkflowInstanceRequest
///
/// The ID of the workflow definition version to create an instance of.
///
- public WorkflowDefinitionHandle WorkflowDefinitionHandle { get; set; } = default!;
+ public WorkflowDefinitionHandle WorkflowDefinitionHandle { get; set; } = null!;
///
/// The correlation ID of the workflow, if any.
///
public string? CorrelationId { get; set; }
+ ///
+ /// The name of the workflow instance to be created.
+ ///
+ public string? Name { get; set; }
+
///
/// The input to the workflow instance, if any.
///
diff --git a/src/modules/Elsa.Workflows.Runtime/Services/LocalWorkflowClient.cs b/src/modules/Elsa.Workflows.Runtime/Services/LocalWorkflowClient.cs
index 8497c99dc..358849bb7 100644
--- a/src/modules/Elsa.Workflows.Runtime/Services/LocalWorkflowClient.cs
+++ b/src/modules/Elsa.Workflows.Runtime/Services/LocalWorkflowClient.cs
@@ -35,6 +35,7 @@ public class LocalWorkflowClient(
{
WorkflowInstanceId = WorkflowInstanceId,
CorrelationId = request.CorrelationId,
+ Name = request.Name,
ParentWorkflowInstanceId = request.ParentId,
Input = request.Input,
Properties = request.Properties
@@ -58,6 +59,7 @@ public class LocalWorkflowClient(
{
Properties = request.Properties,
CorrelationId = request.CorrelationId,
+ Name = request.Name,
Input = request.Input,
WorkflowDefinitionHandle = request.WorkflowDefinitionHandle,
ParentId = request.ParentId
@@ -148,6 +150,7 @@ public class LocalWorkflowClient(
{
WorkflowInstanceId = WorkflowInstanceId,
CorrelationId = request.CorrelationId,
+ Name = request.Name,
ParentWorkflowInstanceId = request.ParentId,
Input = request.Input,
Properties = request.Properties
diff --git a/test/integration/Elsa.Activities.IntegrationTests/SetNameTests.cs b/test/integration/Elsa.Activities.IntegrationTests/SetNameTests.cs
index 3524b588d..91de62ddd 100644
--- a/test/integration/Elsa.Activities.IntegrationTests/SetNameTests.cs
+++ b/test/integration/Elsa.Activities.IntegrationTests/SetNameTests.cs
@@ -15,13 +15,13 @@ public class SetNameTests
_serviceProvider = new TestApplicationBuilder(testOutputHelper).WithCapturingTextWriter(_capturingTextWriter).Build();
}
- [Fact(DisplayName = "WriteLine prints the expected line to the console.")]
+ [Fact(DisplayName = "SetName sets the workflow instance name.")]
public async Task Test1()
{
const string expectedName = "Foo";
var setName = new SetName(new Input(expectedName));
var result = await _serviceProvider.RunActivityAsync(setName);
- var actualName = result.WorkflowState.Properties[SetName.WorkflowInstanceNameKey];
+ var actualName = result.WorkflowState.Name;
Assert.Equal(expectedName, actualName);
}
}
\ No newline at end of file
diff --git a/test/integration/Elsa.Workflows.IntegrationTests/Scenarios/WorkflowCancellation/DefaultRuntimeTests.cs b/test/integration/Elsa.Workflows.IntegrationTests/Scenarios/WorkflowCancellation/DefaultRuntimeTests.cs
index 2cad71e66..704efe89c 100644
--- a/test/integration/Elsa.Workflows.IntegrationTests/Scenarios/WorkflowCancellation/DefaultRuntimeTests.cs
+++ b/test/integration/Elsa.Workflows.IntegrationTests/Scenarios/WorkflowCancellation/DefaultRuntimeTests.cs
@@ -59,7 +59,7 @@ public class DefaultRuntimeTests
const string workflowDefinitionId = nameof(SimpleSuspendedWorkflow);
var workflowClient = await _workflowRuntime.CreateClientAsync();
- await workflowClient.CreateInstanceAsync(new CreateWorkflowInstanceRequest
+ await workflowClient.CreateInstanceAsync(new()
{
WorkflowDefinitionHandle = WorkflowDefinitionHandle.ByDefinitionId(workflowDefinitionId, VersionOptions.Published)
});
diff --git a/test/integration/Elsa.Workflows.IntegrationTests/Scenarios/WorkflowInstanceName/WorkflowInstanceNameTests.cs b/test/integration/Elsa.Workflows.IntegrationTests/Scenarios/WorkflowInstanceName/WorkflowInstanceNameTests.cs
new file mode 100644
index 000000000..b7ebfb427
--- /dev/null
+++ b/test/integration/Elsa.Workflows.IntegrationTests/Scenarios/WorkflowInstanceName/WorkflowInstanceNameTests.cs
@@ -0,0 +1,46 @@
+using Elsa.Common.Models;
+using Elsa.Testing.Shared;
+using Elsa.Workflows.IntegrationTests.Scenarios.WorkflowInstanceName.Workflows;
+using Elsa.Workflows.Models;
+using Elsa.Workflows.Runtime;
+using Elsa.Workflows.Runtime.Messages;
+using Microsoft.Extensions.DependencyInjection;
+using Xunit.Abstractions;
+
+namespace Elsa.Workflows.IntegrationTests.Scenarios.WorkflowInstanceName;
+
+public class WorkflowInstanceNameTests
+{
+ private readonly IServiceProvider _services;
+ private readonly CapturingTextWriter _capturingTextWriter = new();
+ private readonly IWorkflowRuntime _workflowRuntime;
+
+ public WorkflowInstanceNameTests(ITestOutputHelper testOutputHelper)
+ {
+ _services = new TestApplicationBuilder(testOutputHelper)
+ .WithCapturingTextWriter(_capturingTextWriter)
+ .AddWorkflow()
+ .Build();
+
+ _workflowRuntime = _services.GetRequiredService();
+ }
+
+ [Fact(DisplayName = "Setting a workflow instance name keeps the workflow instance name when the workflow is executed")]
+ public async Task SuspendedCancelTest()
+ {
+ await _services.PopulateRegistriesAsync();
+ const string workflowDefinitionId = nameof(NamedWorkflow);
+ var desiredName = Guid.NewGuid().ToString();
+ var workflowClient = await _workflowRuntime.CreateClientAsync();
+ await workflowClient.CreateInstanceAsync(new()
+ {
+ Name = desiredName,
+ WorkflowDefinitionHandle = WorkflowDefinitionHandle.ByDefinitionId(workflowDefinitionId, VersionOptions.Published)
+ });
+ await workflowClient.RunInstanceAsync(RunWorkflowInstanceRequest.Empty);
+ var workflowState = await workflowClient.ExportStateAsync();
+
+ Assert.Equal([desiredName], _capturingTextWriter.Lines);
+ Assert.Equal(desiredName, workflowState.Name);
+ }
+}
\ No newline at end of file
diff --git a/test/integration/Elsa.Workflows.IntegrationTests/Scenarios/WorkflowInstanceName/Workflows/NamedWorkflow.cs b/test/integration/Elsa.Workflows.IntegrationTests/Scenarios/WorkflowInstanceName/Workflows/NamedWorkflow.cs
new file mode 100644
index 000000000..62a2aaff8
--- /dev/null
+++ b/test/integration/Elsa.Workflows.IntegrationTests/Scenarios/WorkflowInstanceName/Workflows/NamedWorkflow.cs
@@ -0,0 +1,12 @@
+using Elsa.Extensions;
+using Elsa.Workflows.Activities;
+
+namespace Elsa.Workflows.IntegrationTests.Scenarios.WorkflowInstanceName.Workflows;
+
+public class NamedWorkflow : WorkflowBase
+{
+ protected override void Build(IWorkflowBuilder builder)
+ {
+ builder.Root = new WriteLine(x => x.GetWorkflowExecutionContext().Name);
+ }
+}
\ No newline at end of file