Messagepack-csharp: Mutable models for how the dynamic resolvers format types

Created on 24 Sep 2020  路  3Comments  路  Source: neuecc/MessagePack-CSharp

The MessagePackSerializer comes built-in with support for serializing types that use DataContract/DataMember attributes as well as its own MessagePackObject/Key attributes. It also has "contractless" which require no attributes at all but leaves some to be desired (e.g. camelCase conversion option, serializing properties and their backing fields).

Today, our dynamic resolvers have hard-coded interpretations of these attributes and feed that model directly into the dynamic code generation.
I propose we break this up into two steps:

  1. reflecting over the types to create a serialization model
  2. providing the model to the code generator.

Of course all existing scenarios would continue to work as-is without changes to user code. But by separating these internally and exposing the intermediate model we give applications a chance to:

  1. Modify the produced model (e.g. apply camelCase conversion).
  2. Create a model from scratch using whatever means they choose (e.g. a new contractless discovery system that works better, perhaps like the DataContractSerializer does for unattributed types).

This shouldn't impact perf significantly since once the codegen has done its work it's all the same.
There's even a possibility a model creator/mutator could be fed into mpc such that AOT code gen could benefit from this.

This could help start an ecosystem of independent messagepack 'extensions' and reduce the rate of incoming feature requests to our dynamic resolvers. It would also give us a way to offer 'fixes' that otherwise would be breaking changes to existing code.

Issues to consider 'fixing' during this refactoring: #800

enhancement

Most helpful comment

I would love an option to serialize/deserialize using camelCasing and looking at all the closed issue's about it I am not the only one. We are currently converting large models that are passed to front-end from Json to MessagePack format and Javascript likes them models camelCased. The workaround to add [MessagePack.Key("camelCaseName")] attribute on all the public properties is cumbersome.

For us it would be a big relief to be able to this by either setting this in MessagePackSerializerOptions
or by attributing only the model i.e. :
[MessagePackObject(keyAsPropertyNameCamelCased: true)]

All 3 comments

Agreed.
Utf8Json that I created after MessaegPack-CSharp has an intermediate type called MetaType, MetaMember, which was intended to be used by users eventually (but not yet).
https://github.com/neuecc/Utf8Json/blob/master/src/Utf8Json/Internal/Emit/MetaType.cs ...
https://github.com/neuecc/Utf8Json/blob/master/src/Utf8Json/Internal/Emit/MetaMember.cs

It is also available as a MetaType in protobuf-net.

This would also allow for the create Union at runtime that requested frequently.

I would love an option to serialize/deserialize using camelCasing and looking at all the closed issue's about it I am not the only one. We are currently converting large models that are passed to front-end from Json to MessagePack format and Javascript likes them models camelCased. The workaround to add [MessagePack.Key("camelCaseName")] attribute on all the public properties is cumbersome.

For us it would be a big relief to be able to this by either setting this in MessagePackSerializerOptions
or by attributing only the model i.e. :
[MessagePackObject(keyAsPropertyNameCamelCased: true)]

Was this page helpful?
0 / 5 - 0 ratings