Skip to content

Serializers

Aghogho Bernard edited this page May 6, 2026 · 1 revision

Serializers

CacheWeave serializes cached values to JSON strings before writing to the backing store. Two built-in serializers are provided, and you can supply your own.

Built-in Serializers

System.Text.Json (default)

builder.Services.AddCacheWeave(options =>
{
    options.Serializer = CacheWeaveSerializerType.SystemTextJson;
});

Uses System.Text.Json.JsonSerializer with the following defaults:

Setting Value
PropertyNamingPolicy JsonNamingPolicy.CamelCase
DefaultIgnoreCondition JsonIgnoreCondition.WhenWritingNull
WriteIndented false

Note: CamelCase applies to property names only — string values are preserved as-is. A property Name = "Steel" serializes to "name":"Steel", not "name":"steel".

Newtonsoft.Json

builder.Services.AddCacheWeave(options =>
{
    options.Serializer = CacheWeaveSerializerType.NewtonsoftJson;
});

Uses Newtonsoft.Json.JsonConvert with the following defaults:

Setting Value
NullValueHandling NullValueHandling.Ignore
DateParseHandling DateParseHandling.DateTimeOffset
Formatting Formatting.None
ReferenceLoopHandling ReferenceLoopHandling.Ignore

ReferenceLoopHandling.Ignore is set by default so that object graphs with circular references (e.g. EF Core entities with navigation properties that are not projected to DTOs) serialize without throwing JsonSerializationException. Circular references are silently omitted from the serialized output.

Requires Newtonsoft.Json 13.x to be available in the consuming project (it is a direct dependency of CacheWeave.Core).

Custom Serializer

Implement ICacheSerializer and register it before AddCacheWeave:

public interface ICacheSerializer
{
    string Serialize<T>(T value);
    T? Deserialize<T>(string json);
    string Serialize(object value, Type type);
    object? Deserialize(string json, Type type);
}

Example — MessagePack Serializer

using MessagePack;

public class MessagePackCacheSerializer : ICacheSerializer
{
    public string Serialize<T>(T value)
        => Convert.ToBase64String(MessagePackSerializer.Serialize(value));

    public T? Deserialize<T>(string data)
        => MessagePackSerializer.Deserialize<T>(Convert.FromBase64String(data));

    public string Serialize(object value, Type type)
        => Convert.ToBase64String(MessagePackSerializer.Serialize(type, value));

    public object? Deserialize(string data, Type type)
        => MessagePackSerializer.Deserialize(type, Convert.FromBase64String(data));
}

Register it before AddCacheWeave so TryAddSingleton does not overwrite it:

builder.Services.AddSingleton<ICacheSerializer, MessagePackCacheSerializer>();
builder.Services.AddCacheWeave(options => { ... });

Example — Custom STJ Options

public class CustomStjSerializer : ICacheSerializer
{
    private static readonly JsonSerializerOptions _opts = new()
    {
        PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower,
        DefaultIgnoreCondition = JsonIgnoreCondition.Never,
        WriteIndented = false,
    };

    public string Serialize<T>(T value) => JsonSerializer.Serialize(value, _opts);
    public T? Deserialize<T>(string json) => JsonSerializer.Deserialize<T>(json, _opts);
    public string Serialize(object value, Type type) => JsonSerializer.Serialize(value, type, _opts);
    public object? Deserialize(string json, Type type) => JsonSerializer.Deserialize(json, type, _opts);
}

Serializer and Compression

When EnableCompression = true, the serializer runs first, then the compressor:

object → Serialize → JSON string → GZip compress → byte[] → Base64 → stored string

On retrieval:

stored string → Base64 decode → GZip decompress → JSON string → Deserialize → object

The serializer and compressor are independent — any combination works.

Clone this wiki locally