MessagePack-backed binary IDataSerializer/IDataDeserializer for SquidStd. MessagePackDataSerializer
implements both of SquidStd's serialization contracts over the MessagePack contractless resolver, so
plain public POCOs round-trip with no [MessagePackObject] attributes and no key annotations. It is the
recommended serializer for SquidStd.Persistence journals and snapshots: payloads are a fraction of the
size of JSON and (de)serialization is faster, which matters when every entity write is appended to a
binary journal. SquidStd.Core ships a JSON default; pull this package in when you want compact binary
payloads instead.
dotnet add package SquidStd.Persistence.MessagePackThe serializer is a single stateless class - construct it and use it directly. Serialize<T> returns a
ReadOnlyMemory<byte> and Deserialize<T> reads one back:
using SquidStd.Core.Interfaces.Serialization;
using SquidStd.Persistence.MessagePack;
public sealed class Player
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
}
var serializer = new MessagePackDataSerializer();
ReadOnlyMemory<byte> bytes = serializer.Serialize(new Player { Id = 1, Name = "Bob" });
Player back = serializer.Deserialize<Player>(bytes);PersistenceEntityDescriptor<T, TKey> takes the serializer and deserializer explicitly, so you can use
MessagePack for entity payloads without touching the rest of the app:
using SquidStd.Persistence.Data;
using SquidStd.Persistence.MessagePack;
using SquidStd.Persistence.Services;
var serializer = new MessagePackDataSerializer();
var registry = new PersistenceEntityRegistry();
registry.Register(new PersistenceEntityDescriptor<Player, int>(
serializer, serializer, typeId: 1, typeName: "Player", schemaVersion: 1, keySelector: p => p.Id));RegisterCoreServices() registers the JSON default via RegisterDataSerializer(), which uses
IfAlreadyRegistered.Keep - an already-registered serializer wins. So to make MessagePack the app-wide
IDataSerializer/IDataDeserializer (used by messaging, caching, and DI-registered persistence
descriptors), register it before RegisterCoreServices():
using DryIoc;
using SquidStd.Core.Interfaces.Serialization;
using SquidStd.Persistence.MessagePack;
using SquidStd.Services.Core.Extensions;
using SquidStd.Services.Core.Services.Bootstrap;
var bootstrap = SquidStdBootstrap.Create(o => o.ConfigName = "myapp");
bootstrap.ConfigureServices(c =>
{
var serializer = new MessagePackDataSerializer();
c.RegisterInstance<IDataSerializer>(serializer);
c.RegisterInstance<IDataDeserializer>(serializer);
return c.RegisterCoreServices(); // keeps your MessagePack registration
});
await bootstrap.StartAsync();If you register it after RegisterCoreServices(), the JSON default is already in place and stays -
the order matters, so always register MessagePack first.
- Public types only: the contractless resolver requires public entity types. For non-public
types, use the JSON serializer from
SquidStd.Core(JsonDataSerializer) instead. - Attribute-free:
ContractlessStandardResolverserializes by member name, so no[MessagePackObject]/[Key]attributes are needed - but member names become part of the payload contract, so renaming a property is a schema change (bumpschemaVersionon persisted entities). - There is no registration extension - the class is the whole package. Register the same instance for both interfaces so serialize and deserialize agree.
| Type | Purpose |
|---|---|
MessagePackDataSerializer |
Contractless MessagePack IDataSerializer/IDataDeserializer. |
- Article: Serialization
- Article: SquidStd.Persistence
- Article: SquidStd.Persistence.Abstractions
- Tutorial: Durable entity persistence
MIT - part of SquidStd.