JasperFx / wolverine

Supercharged .NET server side development!
https://wolverinefx.net
MIT License
1.23k stars 133 forks source link

MessagePackSerializerOptions support for WolverineOptions and IEndpointConfiguration<T> #848

Closed lokeshkumarbalu closed 5 months ago

lokeshkumarbalu commented 5 months ago

MessagePack serialization provides flexibility for configuring serialization options via the MessagePackSerializerOptions. This is achieved through an immutable object implementation, ensuring that modifications cannot be made once the options are set.

Wolverine extensions provide an option to configure MessagePackSerializationOptions via an action. However, the referenced object remains unaltered despite this feature, leading to the failure to apply the required options.

// From the MessagePack Repository
// src/MessagePack.UnityClient/Assets/Scripts/MessagePack/MessagePackSerializerOptions.cs
public MessagePackSerializerOptions WithResolver(IFormatterResolver resolver)
{
    if (this.Resolver == resolver)
    {
        return this;
    }

    var result = this.Clone();
    result.Resolver = resolver;
    return result;
}
// From the WolverineFx repository
// src/Extensions/Wolverine.MessagePack/WolverineMessagePackSerializationExtensions.cs
public static T UseMessagePackSerialization<T>(this T endpoint,
    Action<MessagePackSerializerOptions>? configuration = null) where T : IEndpointConfiguration<T>
{
    var serializerOptions = MessagePackSerializerOptions.Standard;

    configuration?.Invoke(serializerOptions);

    var serializer = new MessagePackMessageSerializer(serializerOptions);
    endpoint.DefaultSerializer(serializer);
    return endpoint;
}
// The action parameter I'm providing to the WolverineFx extension method above
internal static void ConfigureMessagePackSerializerOptions(MessagePackSerializerOptions options)
    {
        var formatterResolver = CompositeResolver.Create(
            BuiltinResolver.Instance, NodatimeResolver.Instance, AttributeFormatterResolver.Instance,
            DynamicEnumAsStringResolver.Instance, ContractlessStandardResolver.Instance);

        options.WithResolver(formatterResolver);
    }
// The stack trace generated by the MessagePack serializer
 ---> MessagePack.FormatterNotRegisteredException: NodaTime.LocalDate is not registered in resolver: MessagePack.Resolvers.StandardResolver
   at MessagePack.FormatterResolverExtensions.Throw(Type t, IFormatterResolver resolver)
   at MessagePack.Formatters.CustomObject2Formatter2.Serialize(MessagePackWriter& writer, ScheduleDetail value, MessagePackSerializerOptions options)
   at MessagePack.Formatters.CollectionFormatterBase`4.Serialize(MessagePackWriter& writer, TCollection value, MessagePackSerializerOptions options)
   at MessagePack.Formatters.CustomObject1Formatter1.Serialize(MessagePackWriter& writer, VolumeSchedule value, MessagePackSerializerOptions options)
   at MessagePack.MessagePackSerializer.Serialize[T](MessagePackWriter& writer, T value, MessagePackSerializerOptions options)
   --- End of inner exception stack trace ---
   at MessagePack.MessagePackSerializer.Serialize[T](MessagePackWriter& writer, T value, MessagePackSerializerOptions options)
   at lambda_method43(Closure, Object, MessagePackSerializerOptions, CancellationToken)
   at MessagePack.MessagePackSerializer.Serialize(Type type, Object obj, MessagePackSerializerOptions options, CancellationToken cancellationToken)
   at Wolverine.MessagePack.Internal.MessagePackMessageSerializer.Write(Envelope envelope) in /home/runner/work/wolverine/wolverine/src/Extensions/Wolverine.MessagePack/Internal/MessagePackMessageSerializer.cs:line 19
   at Wolverine.Envelope.get_Data() in /home/runner/work/wolverine/wolverine/src/Wolverine/Envelope.cs:line 124
   at Wolverine.Transports.Sending.BatchedSender.<.ctor>b__9_0(Envelope e) in /home/runner/work/wolverine/wolverine/src/Wolverine/Transports/Sending/BatchedSender.cs:line 41

Expected behavior The WolverineFx library must apply the updated MessagePackSerializerOptions, allowing serialization of custom types such as NodaTime.LocalDate in my scenario.

Desktop:

jeremydmiller commented 5 months ago

Very happy for a pull request for that!

jeremydmiller commented 5 months ago

Closed by https://github.com/JasperFx/wolverine/pull/849