pardahlman / RawRabbit

A modern .NET framework for communication over RabbitMq
MIT License
747 stars 144 forks source link

Beta2: Customize NewtonSoft Serializer Settings? #251

Closed ChristianSauer closed 7 years ago

ChristianSauer commented 7 years ago

Hello, Would it be possible to add custom serializer settings to each PublishAsync call? I have a situation where I would like to overwrite the defaults, but I have no access to the serializer.

e.g.

            var jsonSerializerSettings = new JsonSerializerSettings()
            {
                PreserveReferencesHandling = PreserveReferencesHandling.None,
                ReferenceLoopHandling = ReferenceLoopHandling.Ignore
            };

            await client.PublishAsync(result,
                ctx => ctx.WithSerializerSettings(jsonSerializerSettings ));

Reason: NewtonSoft Sometimes inserts $ids for reference handling, which the underlying API does not expect at all. Getting rid of them would be great.

pardahlman commented 7 years ago

Hello, @ChristianSauer - thanks for reporting this. There are currently no plans for supporting this in the default client. However, RawRabbit is quite customizable, so there are a few options for you.

The least-effort approach is most likely to register a custom implementation of ISerializer with your desired Newtonsoft configuration

var customSerializer = new JsonSerializer(new Newtonsoft.Json.JsonSerializer
{
    PreserveReferencesHandling = PreserveReferencesHandling.None,
    ReferenceLoopHandling = ReferenceLoopHandling.Ignore
});
var client = RawRabbitFactory.CreateSingleton(new RawRabbitOptions
{
    DependencyInjection = ioc => ioc.AddSingleton<ISerializer>(customSerializer)
});

This serializer will be used for all serialization in RawRabbit. This is perhaps enough to mitigate your problem?

If not, your other option is to create a custom body serialization middleware, that can replace the default BodySerializationMiddleware and implement the SerializeMessage method so that it looks in the context for a serializer setting and if exist uses it. The new middleware can be registered to replace the existing one

_client = RawRabbitFactory.CreateSingleton(new RawRabbitOptions
{
    Plugins = p => p
        .Register(b => b.Replace<BodySerializationMiddleware, CustomBodySerializationMiddleware>())
});

Hope this helps!

pardahlman commented 7 years ago

Closing this for now. Feel free to re-open it 😄