Skip to content

Serialization Options

WillHirsch edited this page May 24, 2018 · 5 revisions

MessagePack for CLI has various options to tweak serializer behaviors. This page describe about their meaning and how to use them.

Overview

Currently, following options are configurable via SerializationContext:

  • CompatibilityOptions.PackerCompatibilityOptions controls behavior of Packer that whether using new types like bin8 str8 ext1, etc. or not.
  • EnumSerializationMethod controls behavior of generated serializers that they pack enums by their name (default, more interoperable, more version tolerant) or their underlying (integral) value (more efficient).
  • SerializationMethod controls behavior of generated serializers that they pack object properties/fields with array type (default, de-facto standard, and more efficient) or map type (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.

Compatibility and Configuration

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.

Details about PackerCompabitibilityOptions

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.

Details about EnumSerializationMethod

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 SerializationMethod named argument in MessagePackEnumMemberAttribute custom 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 SerializationMethod named argument in MessagePackEnumAttribute custom 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 EnumSerializationMethod named argument in SerializationContext, you can specify fallback behavior of the enum types which are not marked with MessagePackEnumAttribute. The default is ByName for 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.

Details about SerializationMethod

See Interoperability Considerations for details.