Skip to content

Commit a6b3801

Browse files
committed
Add and configure custom MongoDB serializers
Introduced MongoDB serializers for various types, including `FlowScope`, to support custom serialization needs. Registered the serializers during application startup via a hosted service, ensuring seamless integration with MongoDB operations.
1 parent e979c9d commit a6b3801

6 files changed

Lines changed: 100 additions & 9 deletions

File tree

Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<Project>
22
<PropertyGroup>
3-
<UseProjectReferences>false</UseProjectReferences>
3+
<UseProjectReferences>true</UseProjectReferences>
44
</PropertyGroup>
55
<PropertyGroup>
66
<Authors>Elsa Workflows Community</Authors>

src/modules/persistence/Elsa.Persistence.EFCore/Modules/Runtime/WorkflowExecutionLogStore.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,5 +103,4 @@ private bool ShouldSerializePayload(WorkflowExecutionLogRecord source)
103103
}
104104

105105
private static IQueryable<WorkflowExecutionLogRecord> Filter(IQueryable<WorkflowExecutionLogRecord> queryable, WorkflowExecutionLogRecordFilter filter) => filter.Apply(queryable);
106-
}
107-
}
106+
}

src/modules/persistence/Elsa.Persistence.MongoDb/Features/MongoDbFeature.cs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,16 @@
1-
using System.Text.Json;
2-
using System.Text.Json.Nodes;
31
using Elsa.Features.Abstractions;
42
using Elsa.Features.Services;
53
using Elsa.KeyValues.Entities;
64
using Elsa.Persistence.MongoDb.Contracts;
5+
using Elsa.Persistence.MongoDb.HostedServices;
76
using Elsa.Persistence.MongoDb.NamingStrategies;
87
using Elsa.Persistence.MongoDb.Options;
9-
using Elsa.Persistence.MongoDb.Serializers;
10-
using Elsa.Workflows.Memory;
8+
using Elsa.Workflows.Activities.Flowchart.Models;
119
using Elsa.Workflows.Runtime.Entities;
1210
using Microsoft.Extensions.DependencyInjection;
1311
using Microsoft.Extensions.DependencyInjection.Extensions;
1412
using Microsoft.Extensions.Options;
15-
using MongoDB.Bson;
1613
using MongoDB.Bson.Serialization;
17-
using MongoDB.Bson.Serialization.Serializers;
1814
using MongoDB.Driver;
1915

2016
namespace Elsa.Persistence.MongoDb.Features;
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
using System.Text.Json;
2+
using System.Text.Json.Nodes;
3+
using Elsa.Persistence.MongoDb.Serializers;
4+
using Elsa.Workflows;
5+
using Elsa.Workflows.Activities.Flowchart.Models;
6+
using Elsa.Workflows.Memory;
7+
using JetBrains.Annotations;
8+
using Microsoft.Extensions.Hosting;
9+
using MongoDB.Bson.Serialization.Serializers;
10+
using static MongoDB.Bson.Serialization.BsonSerializer;
11+
12+
namespace Elsa.Persistence.MongoDb.HostedServices;
13+
14+
/// <summary>
15+
/// A hosted service that configures and registers custom MongoDB serializers for various types.
16+
/// </summary>
17+
/// <remarks>
18+
/// This class implements <see cref="IHostedService"/> and is responsible for registering serializers to handle
19+
/// specific types such as <see cref="object"/>, <see cref="Type"/>, <see cref="Variable"/>, <see cref="Version"/>,
20+
/// <see cref="JsonElement"/>, <see cref="JsonNode"/>, and <see cref="FlowScope"/>.
21+
/// It uses helper methods to register these serializers during the application's startup process.
22+
/// </remarks>
23+
[UsedImplicitly]
24+
public class ConfigureMongoDbSerializers(IPayloadSerializer payloadSerializer) : IHostedService
25+
{
26+
public Task StartAsync(CancellationToken cancellationToken)
27+
{
28+
TryRegisterSerializer(typeof(object), new PolymorphicSerializer());
29+
TryRegisterSerializer(typeof(Type), new TypeSerializer());
30+
TryRegisterSerializer(typeof(Variable), new VariableSerializer());
31+
TryRegisterSerializer(typeof(Version), new VersionSerializer());
32+
TryRegisterSerializer(typeof(JsonElement), new JsonElementSerializer());
33+
TryRegisterSerializer(typeof(JsonNode), new JsonNodeBsonConverter());
34+
TryRegisterSerializer(typeof(FlowScope), new FlowScopeSerializer(payloadSerializer));
35+
36+
return Task.CompletedTask;
37+
}
38+
39+
public Task StopAsync(CancellationToken cancellationToken)
40+
{
41+
return Task.CompletedTask;
42+
}
43+
}

src/modules/persistence/Elsa.Persistence.MongoDb/Modules/Management/WorkflowInstanceStore.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using Elsa.Workflows.Management.Filters;
99
using Elsa.Workflows.Management.Models;
1010
using JetBrains.Annotations;
11+
using Microsoft.Extensions.Logging;
1112
using MongoDB.Driver;
1213
using MongoDB.Driver.Linq;
1314
using Open.Linq.AsyncExtensions;
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
using Elsa.Workflows;
2+
using Elsa.Workflows.Activities.Flowchart.Models;
3+
using MongoDB.Bson;
4+
using MongoDB.Bson.Serialization;
5+
6+
namespace Elsa.Persistence.MongoDb.Serializers;
7+
8+
/// <summary>
9+
/// Serializes a <see cref="FlowScope"/>.
10+
/// </summary>
11+
public class FlowScopeSerializer(IPayloadSerializer payloadSerializer) : IBsonSerializer<FlowScope?>
12+
{
13+
/// <inheritdoc />
14+
public Type ValueType => typeof(FlowScope);
15+
16+
void IBsonSerializer.Serialize(BsonSerializationContext context, BsonSerializationArgs args, object value) => Serialize(context, args, (FlowScope)value);
17+
object IBsonSerializer.Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) => Deserialize(context, args);
18+
19+
/// <inheritdoc />
20+
public void Serialize(BsonSerializationContext context, BsonSerializationArgs args, FlowScope? value)
21+
{
22+
if (value is null)
23+
context.Writer.WriteNull();
24+
else
25+
{
26+
var json = payloadSerializer.Serialize(value);
27+
context.Writer.WriteString(json);
28+
}
29+
}
30+
31+
/// <inheritdoc />
32+
public FlowScope Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
33+
{
34+
var reader = context.Reader;
35+
var bsonType = reader.GetCurrentBsonType();
36+
37+
if (bsonType == BsonType.Null)
38+
{
39+
reader.ReadNull();
40+
return new();
41+
}
42+
43+
if(bsonType == BsonType.String)
44+
{
45+
var json = context.Reader.ReadString();
46+
47+
return string.IsNullOrEmpty(json) ? new() : payloadSerializer.Deserialize<FlowScope>(json);
48+
}
49+
50+
return new();
51+
}
52+
}

0 commit comments

Comments
 (0)