diff --git a/src/api/Elsa.Api/Endpoints/WorkflowInstances/Get.cs b/src/api/Elsa.Api/Endpoints/WorkflowInstances/Get.cs
index 7fee63a3c..9a3afdbe7 100644
--- a/src/api/Elsa.Api/Endpoints/WorkflowInstances/Get.cs
+++ b/src/api/Elsa.Api/Endpoints/WorkflowInstances/Get.cs
@@ -1,8 +1,8 @@
using System.Threading;
using System.Threading.Tasks;
-using Elsa.Management.Serialization;
using Elsa.Mediator.Contracts;
using Elsa.Persistence.Requests;
+using Elsa.Serialization;
using Microsoft.AspNetCore.Http;
namespace Elsa.Api.Endpoints.WorkflowInstances;
diff --git a/src/api/Elsa.Api/Endpoints/WorkflowInstances/List.cs b/src/api/Elsa.Api/Endpoints/WorkflowInstances/List.cs
index 886a5cea8..c92698b5b 100644
--- a/src/api/Elsa.Api/Endpoints/WorkflowInstances/List.cs
+++ b/src/api/Elsa.Api/Endpoints/WorkflowInstances/List.cs
@@ -1,9 +1,9 @@
using System.Threading;
using System.Threading.Tasks;
-using Elsa.Management.Serialization;
using Elsa.Mediator.Contracts;
using Elsa.Persistence.Entities;
using Elsa.Persistence.Requests;
+using Elsa.Serialization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
diff --git a/src/api/Elsa.Api/Endpoints/Workflows/Get.cs b/src/api/Elsa.Api/Endpoints/Workflows/Get.cs
index d344654d5..a9ba6b8dc 100644
--- a/src/api/Elsa.Api/Endpoints/Workflows/Get.cs
+++ b/src/api/Elsa.Api/Endpoints/Workflows/Get.cs
@@ -1,9 +1,9 @@
using System.Threading;
using System.Threading.Tasks;
-using Elsa.Management.Serialization;
using Elsa.Mediator.Contracts;
using Elsa.Persistence.Models;
using Elsa.Persistence.Requests;
+using Elsa.Serialization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
diff --git a/src/api/Elsa.Api/Endpoints/Workflows/GetMany.cs b/src/api/Elsa.Api/Endpoints/Workflows/GetMany.cs
index d08b898b6..f60c65704 100644
--- a/src/api/Elsa.Api/Endpoints/Workflows/GetMany.cs
+++ b/src/api/Elsa.Api/Endpoints/Workflows/GetMany.cs
@@ -1,10 +1,10 @@
using System;
using System.Threading;
using System.Threading.Tasks;
-using Elsa.Management.Serialization;
using Elsa.Mediator.Contracts;
using Elsa.Persistence.Models;
using Elsa.Persistence.Requests;
+using Elsa.Serialization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
diff --git a/src/api/Elsa.Api/Endpoints/Workflows/List.cs b/src/api/Elsa.Api/Endpoints/Workflows/List.cs
index 8267b2d3a..e0d2a2bf8 100644
--- a/src/api/Elsa.Api/Endpoints/Workflows/List.cs
+++ b/src/api/Elsa.Api/Endpoints/Workflows/List.cs
@@ -1,9 +1,9 @@
using System.Threading;
using System.Threading.Tasks;
-using Elsa.Management.Serialization;
using Elsa.Mediator.Contracts;
using Elsa.Persistence.Models;
using Elsa.Persistence.Requests;
+using Elsa.Serialization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
diff --git a/src/api/Elsa.Api/Endpoints/Workflows/Post.cs b/src/api/Elsa.Api/Endpoints/Workflows/Post.cs
index a9c735daa..68772b6e1 100644
--- a/src/api/Elsa.Api/Endpoints/Workflows/Post.cs
+++ b/src/api/Elsa.Api/Endpoints/Workflows/Post.cs
@@ -3,8 +3,8 @@ using System.Threading.Tasks;
using Elsa.Activities;
using Elsa.Contracts;
using Elsa.Management.Contracts;
-using Elsa.Management.Serialization;
using Elsa.Persistence.Mappers;
+using Elsa.Serialization;
using Microsoft.AspNetCore.Http;
namespace Elsa.Api.Endpoints.Workflows;
diff --git a/src/core/Elsa.Management/Contracts/ISerializationOptionsConfigurator.cs b/src/core/Elsa.Core/Contracts/ISerializationOptionsConfigurator.cs
similarity index 77%
rename from src/core/Elsa.Management/Contracts/ISerializationOptionsConfigurator.cs
rename to src/core/Elsa.Core/Contracts/ISerializationOptionsConfigurator.cs
index e90e9d2b6..14ccde39d 100644
--- a/src/core/Elsa.Management/Contracts/ISerializationOptionsConfigurator.cs
+++ b/src/core/Elsa.Core/Contracts/ISerializationOptionsConfigurator.cs
@@ -1,6 +1,6 @@
using System.Text.Json;
-namespace Elsa.Management.Contracts;
+namespace Elsa.Contracts;
public interface ISerializationOptionsConfigurator
{
diff --git a/src/core/Elsa.Core/Elsa.Core.csproj b/src/core/Elsa.Core/Elsa.Core.csproj
index d9bbeb2d2..46a3bda7a 100644
--- a/src/core/Elsa.Core/Elsa.Core.csproj
+++ b/src/core/Elsa.Core/Elsa.Core.csproj
@@ -9,10 +9,15 @@
+
+
+
+
+
diff --git a/src/core/Elsa.Core/Extensions/PropertyAccessorExtensions.cs b/src/core/Elsa.Core/Extensions/PropertyAccessorExtensions.cs
index a468c5afc..295ba4545 100644
--- a/src/core/Elsa.Core/Extensions/PropertyAccessorExtensions.cs
+++ b/src/core/Elsa.Core/Extensions/PropertyAccessorExtensions.cs
@@ -1,4 +1,3 @@
-using System;
using System.Linq.Expressions;
using System.Reflection;
diff --git a/src/core/Elsa.Core/Helpers/ObjectConverter.cs b/src/core/Elsa.Core/Helpers/ObjectConverter.cs
index 039cca57b..02a57522f 100644
--- a/src/core/Elsa.Core/Helpers/ObjectConverter.cs
+++ b/src/core/Elsa.Core/Helpers/ObjectConverter.cs
@@ -1,5 +1,11 @@
using System.ComponentModel;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+using Dahomey.Json;
+using Dahomey.Json.Serialization.Conventions;
using Elsa.Exceptions;
+using DahomeyJsonObject = System.Text.Json.JsonObject;
+using DahomeyJsonNode = System.Text.Json.JsonNode;
namespace Elsa.Helpers;
@@ -11,17 +17,34 @@ public static class ObjectConverter
{
if (value == null)
return default!;
-
+
var sourceType = value.GetType();
if (sourceType == targetType)
return value;
+ var options = new JsonSerializerOptions();
+ options.SetupExtensions().SetReferenceHandling(ReferenceHandling.Preserve);
+ var registry = options.GetDiscriminatorConventionRegistry();
+ registry.ClearConventions();
+ registry.RegisterConvention(new DefaultDiscriminatorConvention(options, "_type"));
+
+ options.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
+ options.ReferenceHandler = ReferenceHandler.Preserve;
+ options.PropertyNameCaseInsensitive = true;
+ options.Converters.Add(new JsonStringEnumConverter());
+
+ if (value is DahomeyJsonNode { ValueKind: JsonValueKind.Object } dahomyJsonObject)
+ return ToObject(dahomyJsonObject, targetType, options);
+
+ if (value is JsonElement { ValueKind: JsonValueKind.Object } jsonObject)
+ return jsonObject.Deserialize(targetType, options);
+
var underlyingTargetType = Nullable.GetUnderlyingType(targetType) ?? targetType;
-
+
if (targetType == typeof(object))
return value;
-
+
if (underlyingTargetType.IsInstanceOfType(value))
return value;
@@ -29,7 +52,7 @@ public static class ObjectConverter
if (underlyingSourceType == underlyingTargetType)
return value;
-
+
var targetTypeConverter = TypeDescriptor.GetConverter(underlyingTargetType);
if (targetTypeConverter.CanConvertFrom(underlyingSourceType))
@@ -55,4 +78,10 @@ public static class ObjectConverter
throw new TypeConversionException($"Failed to convert an object of type {sourceType} to {underlyingTargetType}", value, underlyingTargetType, e);
}
}
+
+ private static object? ToObject(this DahomeyJsonNode node, Type type, JsonSerializerOptions? options = null)
+ {
+ using var arrayBufferWriter = new Dahomey.Json.Util.ArrayBufferWriter();
+ return JsonSerializer.Deserialize(node.ToString(), type, options);
+ }
}
\ No newline at end of file
diff --git a/src/core/Elsa.Core/Models/Variable.cs b/src/core/Elsa.Core/Models/Variable.cs
index 42197f2e6..c7ec48501 100644
--- a/src/core/Elsa.Core/Models/Variable.cs
+++ b/src/core/Elsa.Core/Models/Variable.cs
@@ -20,7 +20,7 @@ public class Variable : RegisterLocationReference
}
public string? Name { get; set; }
- public object? DefaultValue { get; }
+ public object? DefaultValue { get; set; }
public override RegisterLocation Declare() => new(DefaultValue);
}
diff --git a/src/core/Elsa.Core/Serialization/CustomDiscriminatorConvention.cs b/src/core/Elsa.Core/Serialization/CustomDiscriminatorConvention.cs
new file mode 100644
index 000000000..eb8ca0003
--- /dev/null
+++ b/src/core/Elsa.Core/Serialization/CustomDiscriminatorConvention.cs
@@ -0,0 +1,35 @@
+using System.Text;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+using Dahomey.Json;
+using Dahomey.Json.Serialization.Conventions;
+
+namespace Elsa.Serialization;
+
+public class CustomDiscriminatorConvention : IDiscriminatorConvention
+{
+ private readonly JsonSerializerOptions _options;
+ private readonly JsonConverter _jsonConverter;
+
+ public CustomDiscriminatorConvention(JsonSerializerOptions options)
+ {
+ _options = options;
+ _jsonConverter = options.GetConverter();
+ }
+
+ public ReadOnlySpan MemberName => Encoding.UTF8.GetBytes("$type");
+
+ public bool TryRegisterType(Type type) => true;
+
+ public Type ReadDiscriminator(ref Utf8JsonReader reader)
+ {
+ var discriminator = _jsonConverter.Read(ref reader, typeof(string), _options)!;
+ return Type.GetType(discriminator)!;
+ }
+
+ public void WriteDiscriminator(Utf8JsonWriter writer, Type actualType)
+ {
+ var discriminator = actualType.AssemblyQualifiedName!;
+ _jsonConverter.Write(writer, discriminator, _options);
+ }
+}
\ No newline at end of file
diff --git a/src/core/Elsa.Management/Serialization/WorkflowSerializerOptionsProvider.cs b/src/core/Elsa.Core/Serialization/WorkflowSerializerOptionsProvider.cs
similarity index 54%
rename from src/core/Elsa.Management/Serialization/WorkflowSerializerOptionsProvider.cs
rename to src/core/Elsa.Core/Serialization/WorkflowSerializerOptionsProvider.cs
index 62397648f..81cb97838 100644
--- a/src/core/Elsa.Management/Serialization/WorkflowSerializerOptionsProvider.cs
+++ b/src/core/Elsa.Core/Serialization/WorkflowSerializerOptionsProvider.cs
@@ -1,39 +1,47 @@
using System.Text.Json;
using System.Text.Json.Serialization;
-using Elsa.Management.Contracts;
-using Elsa.Management.Serialization.Converters;
+using System.Text.Json.Serialization.Metadata;
+using Dahomey.Json;
+using Dahomey.Json.Attributes;
+using Dahomey.Json.Serialization.Conventions;
+using Elsa.Contracts;
using Microsoft.Extensions.DependencyInjection;
-namespace Elsa.Management.Serialization;
+namespace Elsa.Serialization;
public class WorkflowSerializerOptionsProvider
{
private readonly IEnumerable _configurators;
private readonly IServiceProvider _serviceProvider;
-
+
public WorkflowSerializerOptionsProvider(IEnumerable configurators, IServiceProvider serviceProvider)
{
_configurators = configurators;
_serviceProvider = serviceProvider;
}
- public JsonSerializerOptions CreateApiOptions() => CreateDefaultOptions();
- public JsonSerializerOptions CreatePersistenceOptions() => CreateDefaultOptions(ReferenceHandler.Preserve);
-
- public JsonSerializerOptions CreateDefaultOptions(ReferenceHandler? referenceHandler = default)
+ public JsonSerializerOptions CreateApiOptions() => CreateDefaultOptions(ReferenceHandling.Ignore);
+ public JsonSerializerOptions CreatePersistenceOptions() => CreateDefaultOptions(ReferenceHandling.Preserve);
+
+ public JsonSerializerOptions CreateDefaultOptions(ReferenceHandling referenceHandling)
{
- var options = new JsonSerializerOptions()
+ var options = new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
- ReferenceHandler = referenceHandler,
- Converters =
- {
- Create(),
- Create(),
- Create(),
- Create()
- }
+ PropertyNameCaseInsensitive = true
};
+
+ options.Converters.Add(Create());
+ options.Converters.Add(JsonMetadataServices.TimeSpanConverter);
+
+ // Dahomey.
+ options.SetupExtensions();
+ options.SetReferenceHandling(referenceHandling);
+
+ // Setup polymorphic serialization.
+ var registry = options.GetDiscriminatorConventionRegistry();
+ registry.RegisterConvention(new DefaultDiscriminatorConvention(options));
+ registry.DiscriminatorPolicy = DiscriminatorPolicy.Auto;
// Give external packages a chance to further configure the serializer options. E.g. to add additional converters.
foreach (var configurator in _configurators) configurator.Configure(options);
diff --git a/src/core/Elsa.Management/Elsa.Management.csproj b/src/core/Elsa.Management/Elsa.Management.csproj
index eb3c36847..29ac35e76 100644
--- a/src/core/Elsa.Management/Elsa.Management.csproj
+++ b/src/core/Elsa.Management/Elsa.Management.csproj
@@ -7,6 +7,7 @@
+
diff --git a/src/core/Elsa.Management/Extensions/ServiceCollectionExtensions.cs b/src/core/Elsa.Management/Extensions/ServiceCollectionExtensions.cs
index 3d86b2617..5e1e9ae4a 100644
--- a/src/core/Elsa.Management/Extensions/ServiceCollectionExtensions.cs
+++ b/src/core/Elsa.Management/Extensions/ServiceCollectionExtensions.cs
@@ -4,6 +4,7 @@ using Elsa.Management.Options;
using Elsa.Management.Providers;
using Elsa.Management.Serialization;
using Elsa.Management.Services;
+using Elsa.Serialization;
using Microsoft.Extensions.DependencyInjection;
namespace Elsa.Management.Extensions;
@@ -26,6 +27,7 @@ public static class ServiceCollectionExtensions
.AddSingleton()
.AddSingleton()
.AddSingleton()
+ .AddSingleton()
.AddSingleton();
}
diff --git a/src/core/Elsa.Management/Serialization/SerializationOptionsConfigurator.cs b/src/core/Elsa.Management/Serialization/SerializationOptionsConfigurator.cs
new file mode 100644
index 000000000..719f61cdf
--- /dev/null
+++ b/src/core/Elsa.Management/Serialization/SerializationOptionsConfigurator.cs
@@ -0,0 +1,25 @@
+using System.Text.Json;
+using Elsa.Contracts;
+using Elsa.Management.Serialization.Converters;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace Elsa.Management.Serialization;
+
+public class SerializationOptionsConfigurator : ISerializationOptionsConfigurator
+{
+ private readonly IServiceProvider _serviceProvider;
+
+ public SerializationOptionsConfigurator(IServiceProvider serviceProvider)
+ {
+ _serviceProvider = serviceProvider;
+ }
+
+ public void Configure(JsonSerializerOptions options)
+ {
+ options.Converters.Add(Create());
+ options.Converters.Add(Create());
+ options.Converters.Add(Create());
+ }
+
+ private T Create() => ActivatorUtilities.CreateInstance(_serviceProvider);
+}
\ No newline at end of file
diff --git a/src/modules/Elsa.Modules.Activities/Configurators/CustomSerializationOptionConfigurator.cs b/src/modules/Elsa.Modules.Activities/Configurators/CustomSerializationOptionConfigurator.cs
index bb5921200..ea87fc7b8 100644
--- a/src/modules/Elsa.Modules.Activities/Configurators/CustomSerializationOptionConfigurator.cs
+++ b/src/modules/Elsa.Modules.Activities/Configurators/CustomSerializationOptionConfigurator.cs
@@ -1,6 +1,6 @@
using System.Text.Json;
using System.Text.Json.Serialization;
-using Elsa.Management.Contracts;
+using Elsa.Contracts;
using Elsa.Modules.Activities.Converters;
using Microsoft.Extensions.DependencyInjection;
diff --git a/src/modules/Elsa.Modules.Activities/Elsa.Modules.Activities.csproj b/src/modules/Elsa.Modules.Activities/Elsa.Modules.Activities.csproj
index afddfe6dc..45d71909b 100644
--- a/src/modules/Elsa.Modules.Activities/Elsa.Modules.Activities.csproj
+++ b/src/modules/Elsa.Modules.Activities/Elsa.Modules.Activities.csproj
@@ -7,6 +7,7 @@
+
diff --git a/src/modules/Elsa.Modules.Activities/Extensions/ServiceCollectionExtensions.cs b/src/modules/Elsa.Modules.Activities/Extensions/ServiceCollectionExtensions.cs
index c1161d8b6..0897f2e5b 100644
--- a/src/modules/Elsa.Modules.Activities/Extensions/ServiceCollectionExtensions.cs
+++ b/src/modules/Elsa.Modules.Activities/Extensions/ServiceCollectionExtensions.cs
@@ -1,5 +1,4 @@
using Elsa.Contracts;
-using Elsa.Management.Contracts;
using Elsa.Modules.Activities.Configurators;
using Elsa.Modules.Activities.Resolvers;
using Microsoft.Extensions.DependencyInjection;
diff --git a/src/modules/Elsa.Modules.Scheduling/Handlers/ScheduleWorkflows.cs b/src/modules/Elsa.Modules.Scheduling/Handlers/ScheduleWorkflows.cs
index 3d067493c..a2e2b5740 100644
--- a/src/modules/Elsa.Modules.Scheduling/Handlers/ScheduleWorkflows.cs
+++ b/src/modules/Elsa.Modules.Scheduling/Handlers/ScheduleWorkflows.cs
@@ -2,7 +2,6 @@ using System.Threading;
using System.Threading.Tasks;
using Elsa.Mediator.Contracts;
using Elsa.Modules.Scheduling.Contracts;
-using Elsa.Runtime.Middleware;
using Elsa.Runtime.Models;
using Elsa.Runtime.Notifications;
diff --git a/src/persistence/Elsa.Persistence.EntityFrameworkCore/Handlers/Serialization/WorkflowDefinitionSerializer.cs b/src/persistence/Elsa.Persistence.EntityFrameworkCore/Handlers/Serialization/WorkflowDefinitionSerializer.cs
index 83302e5a0..f1730a67b 100644
--- a/src/persistence/Elsa.Persistence.EntityFrameworkCore/Handlers/Serialization/WorkflowDefinitionSerializer.cs
+++ b/src/persistence/Elsa.Persistence.EntityFrameworkCore/Handlers/Serialization/WorkflowDefinitionSerializer.cs
@@ -1,9 +1,9 @@
using System.Text.Json;
using Elsa.Contracts;
-using Elsa.Management.Serialization;
using Elsa.Models;
using Elsa.Persistence.Entities;
using Elsa.Persistence.EntityFrameworkCore.Contracts;
+using Elsa.Serialization;
namespace Elsa.Persistence.EntityFrameworkCore.Handlers.Serialization;
diff --git a/src/persistence/Elsa.Persistence.EntityFrameworkCore/Handlers/Serialization/WorkflowExecutionLogRecordSerializer.cs b/src/persistence/Elsa.Persistence.EntityFrameworkCore/Handlers/Serialization/WorkflowExecutionLogRecordSerializer.cs
index 2f015438e..55ee5f7a7 100644
--- a/src/persistence/Elsa.Persistence.EntityFrameworkCore/Handlers/Serialization/WorkflowExecutionLogRecordSerializer.cs
+++ b/src/persistence/Elsa.Persistence.EntityFrameworkCore/Handlers/Serialization/WorkflowExecutionLogRecordSerializer.cs
@@ -1,7 +1,7 @@
using System.Text.Json;
-using Elsa.Management.Serialization;
using Elsa.Persistence.Entities;
using Elsa.Persistence.EntityFrameworkCore.Contracts;
+using Elsa.Serialization;
namespace Elsa.Persistence.EntityFrameworkCore.Handlers.Serialization;
diff --git a/src/persistence/Elsa.Persistence.EntityFrameworkCore/Handlers/Serialization/WorkflowInstanceSerializer.cs b/src/persistence/Elsa.Persistence.EntityFrameworkCore/Handlers/Serialization/WorkflowInstanceSerializer.cs
index f67346924..9e15c99f6 100644
--- a/src/persistence/Elsa.Persistence.EntityFrameworkCore/Handlers/Serialization/WorkflowInstanceSerializer.cs
+++ b/src/persistence/Elsa.Persistence.EntityFrameworkCore/Handlers/Serialization/WorkflowInstanceSerializer.cs
@@ -1,8 +1,8 @@
using System.Text.Json;
-using Elsa.Management.Serialization;
using Elsa.Persistence.Entities;
using Elsa.Persistence.EntityFrameworkCore.Contracts;
using Elsa.Persistence.Models;
+using Elsa.Serialization;
using Elsa.State;
namespace Elsa.Persistence.EntityFrameworkCore.Handlers.Serialization;
diff --git a/src/runtime/Elsa.Runtime.ProtoActor/Actors/WorkflowInstanceActor.cs b/src/runtime/Elsa.Runtime.ProtoActor/Actors/WorkflowInstanceActor.cs
index a4d496061..480d1815f 100644
--- a/src/runtime/Elsa.Runtime.ProtoActor/Actors/WorkflowInstanceActor.cs
+++ b/src/runtime/Elsa.Runtime.ProtoActor/Actors/WorkflowInstanceActor.cs
@@ -48,7 +48,10 @@ public class WorkflowInstanceActor : IActor
private PID GetWorkflowOperatorPid(IContext context, string workflowInstanceId)
{
var actorName = $"workflow-operator:{workflowInstanceId}";
- var pid = context.System.ProcessRegistry.SearchByName(actorName).FirstOrDefault();
+ var pid = context.System.ProcessRegistry.Find(x =>
+ {
+ return x == actorName;
+ }).FirstOrDefault();
if (pid != null)
return pid;
diff --git a/src/runtime/Elsa.Runtime.ProtoActor/Actors/WorkflowOperatorActor.cs b/src/runtime/Elsa.Runtime.ProtoActor/Actors/WorkflowOperatorActor.cs
index 4ee575dab..95b204317 100644
--- a/src/runtime/Elsa.Runtime.ProtoActor/Actors/WorkflowOperatorActor.cs
+++ b/src/runtime/Elsa.Runtime.ProtoActor/Actors/WorkflowOperatorActor.cs
@@ -5,7 +5,6 @@ using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using Elsa.Contracts;
-using Elsa.Management.Serialization;
using Elsa.Mediator.Contracts;
using Elsa.Models;
using Elsa.Persistence.Models;
@@ -13,6 +12,7 @@ using Elsa.Persistence.Requests;
using Elsa.Runtime.Contracts;
using Elsa.Runtime.ProtoActor.Extensions;
using Elsa.Runtime.ProtoActor.Messages;
+using Elsa.Serialization;
using Elsa.State;
using Proto;
using Bookmark = Elsa.Runtime.ProtoActor.Messages.Bookmark;
diff --git a/src/samples/aspnet/Elsa.Samples.Web1/Models/Order.cs b/src/samples/aspnet/Elsa.Samples.Web1/Models/Order.cs
new file mode 100644
index 000000000..738678f44
--- /dev/null
+++ b/src/samples/aspnet/Elsa.Samples.Web1/Models/Order.cs
@@ -0,0 +1,4 @@
+namespace Elsa.Samples.Web1.Models;
+
+public record Order(string Id, int Number, string CustomerId, OrderItem[] Items);
+public record OrderItem(string ProductId, int Quantity);
\ No newline at end of file
diff --git a/src/samples/aspnet/Elsa.Samples.Web1/Program.cs b/src/samples/aspnet/Elsa.Samples.Web1/Program.cs
index cb3b5b014..de8825039 100644
--- a/src/samples/aspnet/Elsa.Samples.Web1/Program.cs
+++ b/src/samples/aspnet/Elsa.Samples.Web1/Program.cs
@@ -1,11 +1,15 @@
+using System;
+using System.Text.Json;
using Elsa.Activities;
using Elsa.Api.Extensions;
+using Elsa.Contracts;
using Elsa.Extensions;
using Elsa.Jobs.Extensions;
using Elsa.Management.Contracts;
using Elsa.Management.Extensions;
using Elsa.Modules.Activities.Activities.Console;
using Elsa.Modules.Activities.Activities.Workflows;
+using Elsa.Modules.Activities.Configurators;
using Elsa.Modules.AzureServiceBus.Activities;
using Elsa.Modules.AzureServiceBus.Extensions;
using Elsa.Modules.Hangfire.Services;
@@ -14,6 +18,7 @@ using Elsa.Modules.Http.Extensions;
using Elsa.Modules.JavaScript.Activities;
using Elsa.Modules.Quartz.Services;
using Elsa.Modules.Scheduling.Activities;
+using Elsa.Modules.Scheduling.Extensions;
using Elsa.Modules.WorkflowContexts.Extensions;
using Elsa.Persistence.EntityFrameworkCore.Extensions;
using Elsa.Persistence.EntityFrameworkCore.Sqlite;
@@ -21,9 +26,12 @@ using Elsa.Pipelines.WorkflowExecution.Components;
using Elsa.Runtime.Extensions;
using Elsa.Runtime.ProtoActor.Extensions;
using Elsa.Samples.Web1.Activities;
+using Elsa.Samples.Web1.Models;
+using Elsa.Samples.Web1.Serialization;
using Elsa.Samples.Web1.Workflows;
using Elsa.Scripting.JavaScript.Extensions;
using Elsa.Scripting.Liquid.Extensions;
+using Elsa.Serialization;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
@@ -45,13 +53,14 @@ services
.IndexWorkflowTriggers()
.AddElsaManagement()
.AddJobServices(new QuartzJobSchedulerProvider(), new HangfireJobQueueProvider(sqlServerConnectionString))
+ .AddSchedulingServices()
.AddHttpActivityServices()
.AddAzureServiceBusServices(options => configuration.GetSection("AzureServiceBus").Bind(options))
.ConfigureWorkflowRuntime(options =>
{
// Register workflows.
options.Workflows.Add();
- options.Workflows.Add();
+ //options.Workflows.Add();
options.Workflows.Add();
options.Workflows.Add();
options.Workflows.Add();
@@ -60,6 +69,8 @@ services
options.Workflows.Add();
options.Workflows.Add();
options.Workflows.Add();
+ options.Workflows.Add();
+ options.Workflows.Add();
});
// Testing only: allow client app to connect from anywhere.
@@ -86,6 +97,10 @@ services
.AddJavaScriptExpressions()
.AddLiquidExpressions();
+// Register serialization configurator for configuring what types to allow to be serialized.
+services.AddSingleton();
+services.AddSingleton();
+
// Configure middleware pipeline.
var app = builder.Build();
var serviceProvider = app.Services;
@@ -97,6 +112,11 @@ wellKnownTypeRegistry.RegisterType("float");
wellKnownTypeRegistry.RegisterType("boolean");
wellKnownTypeRegistry.RegisterType("string");
+var order = new Order("order-1", 1, "customer-1", new[] { new OrderItem("product-i1", 2) });
+var serializationOptions = serviceProvider.GetRequiredService().CreatePersistenceOptions();
+var json = JsonSerializer.Serialize(order, serializationOptions);
+Console.WriteLine(json);
+
// Configure workflow engine execution pipeline.
serviceProvider.ConfigureDefaultWorkflowExecutionPipeline(pipeline =>
pipeline
diff --git a/src/samples/aspnet/Elsa.Samples.Web1/Serialization/SerializationOptionsConfigurator.cs b/src/samples/aspnet/Elsa.Samples.Web1/Serialization/SerializationOptionsConfigurator.cs
new file mode 100644
index 000000000..77380978b
--- /dev/null
+++ b/src/samples/aspnet/Elsa.Samples.Web1/Serialization/SerializationOptionsConfigurator.cs
@@ -0,0 +1,19 @@
+using System.Text.Json;
+using Dahomey.Json;
+using Dahomey.Json.Attributes;
+using Elsa.Contracts;
+using Elsa.Samples.Web1.Models;
+
+namespace Elsa.Samples.Web1.Serialization;
+
+public class SerializationOptionsConfigurator : ISerializationOptionsConfigurator
+{
+ public void Configure(JsonSerializerOptions options)
+ {
+ options.GetObjectMappingRegistry().Register(objectMapping => objectMapping
+ .AutoMap()
+ .SetDiscriminator("Order")
+ .SetDiscriminatorPolicy(DiscriminatorPolicy.Always)
+ .AddDiscriminatorMapping());
+ }
+}
\ No newline at end of file
diff --git a/src/samples/aspnet/Elsa.Samples.Web1/Workflows/DelayWorkflow.cs b/src/samples/aspnet/Elsa.Samples.Web1/Workflows/DelayWorkflow.cs
new file mode 100644
index 000000000..4f8108bd1
--- /dev/null
+++ b/src/samples/aspnet/Elsa.Samples.Web1/Workflows/DelayWorkflow.cs
@@ -0,0 +1,23 @@
+using Elsa.Activities;
+using Elsa.Contracts;
+using Elsa.Modules.Activities.Activities.Console;
+using Elsa.Modules.Scheduling.Activities;
+using Elsa.Runtime.Contracts;
+
+namespace Elsa.Samples.Web1.Workflows;
+
+public class DelayWorkflow : IWorkflow
+{
+ public void Build(IWorkflowDefinitionBuilder workflow)
+ {
+ workflow.WithRoot(new Sequence
+ {
+ Activities =
+ {
+ new WriteLine("Sleeping for 5 seconds..."),
+ Delay.FromSeconds(5),
+ new WriteLine(context => $"Continuing at {context.GetRequiredService().UtcNow}")
+ }
+ });
+ }
+}
\ No newline at end of file
diff --git a/src/samples/aspnet/Elsa.Samples.Web1/Workflows/OrderProcessingWorkflow.cs b/src/samples/aspnet/Elsa.Samples.Web1/Workflows/OrderProcessingWorkflow.cs
new file mode 100644
index 000000000..5f4ea90cf
--- /dev/null
+++ b/src/samples/aspnet/Elsa.Samples.Web1/Workflows/OrderProcessingWorkflow.cs
@@ -0,0 +1,29 @@
+using Elsa.Activities;
+using Elsa.Contracts;
+using Elsa.Models;
+using Elsa.Modules.Activities.Activities.Console;
+using Elsa.Modules.Scheduling.Activities;
+using Elsa.Runtime.Contracts;
+using Elsa.Samples.Web1.Models;
+
+namespace Elsa.Samples.Web1.Workflows;
+
+public class OrderProcessingWorkflow : IWorkflow
+{
+ public void Build(IWorkflowDefinitionBuilder workflow)
+ {
+ var orderVariable = new Variable();
+
+ workflow.WithRoot(new Sequence
+ {
+ Variables = { orderVariable },
+ Activities =
+ {
+ new WriteLine("Creating order..."),
+ new SetVariable(orderVariable, new Order("order-1", 1, "customer-1", new[] { new OrderItem("product-1", 3) })),
+ Delay.FromSeconds(5),
+ new WriteLine(context => $"Shipping order {orderVariable.Get(context)!.Id}."),
+ }
+ });
+ }
+}
\ No newline at end of file
diff --git a/src/samples/aspnet/Elsa.Samples.Web1/Workflows/SubmitJobWorkflow.cs b/src/samples/aspnet/Elsa.Samples.Web1/Workflows/SubmitJobWorkflow.cs
index 848e0fcec..42e350aae 100644
--- a/src/samples/aspnet/Elsa.Samples.Web1/Workflows/SubmitJobWorkflow.cs
+++ b/src/samples/aspnet/Elsa.Samples.Web1/Workflows/SubmitJobWorkflow.cs
@@ -6,6 +6,7 @@ using Elsa.Contracts;
using Elsa.Jobs.Abstractions;
using Elsa.Jobs.Contracts;
using Elsa.Jobs.Models;
+using Elsa.Modules.Activities.Activities.Console;
using Elsa.Runtime.Contracts;
namespace Elsa.Samples.Web1.Workflows;
@@ -14,12 +15,20 @@ public class SubmitJobWorkflow : IWorkflow
{
public void Build(IWorkflowDefinitionBuilder workflow)
{
- workflow.WithRoot(new Inline(async context =>
+ workflow.WithRoot(new Sequence
{
- var jobQueue = context.GetRequiredService();
- var job = new ReadTheInternetJob();
- await jobQueue.SubmitJobAsync(job, cancellationToken: context.CancellationToken);
- }));
+ Activities =
+ {
+ new WriteLine("Downloading..."),
+ new Inline(async context =>
+ {
+ var jobQueue = context.GetRequiredService();
+ var job = new ReadTheInternetJob();
+ await jobQueue.SubmitJobAsync(job, cancellationToken: context.CancellationToken);
+ })
+ // TODO: Implement a "job" activity that blocks the workflow until the job completes.
+ }
+ });
}
}
diff --git a/src/samples/console/Elsa.Samples.Console1/Program.cs b/src/samples/console/Elsa.Samples.Console1/Program.cs
index 1de0055ba..e52e7027e 100644
--- a/src/samples/console/Elsa.Samples.Console1/Program.cs
+++ b/src/samples/console/Elsa.Samples.Console1/Program.cs
@@ -4,7 +4,6 @@ using System.Linq;
using System.Threading.Tasks;
using Elsa.Contracts;
using Elsa.Extensions;
-using Elsa.Mediator.Extensions;
using Elsa.Models;
using Elsa.Persistence.InMemory.Extensions;
using Elsa.Pipelines.ActivityExecution.Components;