-
Notifications
You must be signed in to change notification settings - Fork 174
Serialization Options
MessagePack for CLI has various options to tweak serializer behaviors. This page describe about their meaning and how to use them.
Currently, following options are configurable via SerializationContext:
-
CompatibilityOptions.PackerCompatibilityOptionscontrols behavior ofPackerthat whether using new types likebin8str8ext1, etc. or not. -
EnumSerializationMethodcontrols behavior of generated serializers that they packenums by their name (default, more interoperable, more version tolerant) or their underlying (integral) value (more efficient). -
SerializationMethodcontrols behavior of generated serializers that they pack object properties/fields witharraytype (default, de-facto standard, and more efficient) ormaptype (more version tolerant, and the default of MessagePack C#).
Remember that all settings related to serializers are managed in single SerializationContext which was used to generate serializers or was registered custom serializers. That means you can manage multiple configuration using multiple SerializationContext objects.
As of 0.6.0, default behavior uses new and safe format, so some behaviors are not compatible with older versions default settings. If you face issues for them, you can easily switch back to older compatible "classic" behavior with SerializationContext.ConfigureClassic() method.
Historically, MessagePack protocol had not supported distinction between strings and raw binaries to acomplish flexibility like Ruby and C. But some people argued that the distinction was useful in Web languages like JavaScript in patricular. In the end, a protocol author @fsyuki and each language binding comitters decided to extend prptocol. But, unfortunatelly, because there ware many bindins already implemented, it was hard to switch all users to new protocol, so it was recommended that each bindings implemented 'compatibility mode' to absove protocol incompatibility.
MessagePack for CLI supports both of old protocol and new protocol. Its Unpacker and Unpacking API accept all variants like int32 typed numeric value 0. And Packer accepts PackerCompatibilityOptions as constructor parameter, it controls that whether Packer uses new types (bin8, str8, or so) or not. MessagePackSerializer<T>.Pack(Stream) method internally refers SerializationContext.CompatibilityOptions.PackerCompatibilityOptions, so you can use its property like 'global' switch.
For preventing unexpected communication error for other bindings, the default value is Classic, it does not use new types (note that many bindings now support new types). If you enable more efficient and more rich new types, specify PackerCompatibilityOptions.None.
Because of interoperability, MessagePack for CLI uses names as enum serialization methods. .NET or C people think enums as named integrals, but this idea is not universal. For example, Java does not any gurantee about enums are mappable to integrals - they are just named objects usable in switch statement (they can have methods and fields, and can hold integral values). This means that integral enum serialization is not interoperable.
While by-integral-enum-serialization is not interoperable, its efficiency is not ignorable. Prior to 0.5, it is hard to serialize enums as their integral value because you have to implement custom serializers by hand. As of 0.5, you can control enum serialization behavior in 3 levels:
- You can specify enum serialization method in member level. Specifying
SerializationMethodnamed argument inMessagePackEnumMemberAttributecustom attribute for the target members (properties or fields), you will get fine grained controll for the enums in usage basis. This option is preferred to others. - You can specify enum serialization method in type level. Specifying
SerializationMethodnamed argument inMessagePackEnumAttributecustom attribute for the own enum types, you can specify default behavior of the enum type. This option is preferred to global fallback value, but will be overriden by member level specification. - You can specify enum serialization method in global level. Specifying
EnumSerializationMethodnamed argument inSerializationContext, you can specify fallback behavior of the enum types which are not marked withMessagePackEnumAttribute. The default isByNamefor compatibility and interoperability reasons.
Note that this options controls serializer generation behavior instead of serializer behavior itself. So you cannot change on-the-fly.
To retrieve enum serializers for specific enum serializer options in your own custom serializer, you can use providerParameter parameter of SerializerContext.GetSerializer overloads as following:
// Gets SomeEnum serializer which uses integral value to serialize value.
var enumSerializer = context.GetSerializer<SomeEnum>( EnumSerializationMethod.ByUnderlyingValue );Finally, enum serializers can unpack both of string value and integral value, so you do not have to worry about incoming message.
See Interoperability Considerations for details.