Tyto.Materializer.Redis
0.0.1-alpha.47
dotnet add package Tyto.Materializer.Redis --version 0.0.1-alpha.47
NuGet\Install-Package Tyto.Materializer.Redis -Version 0.0.1-alpha.47
<PackageReference Include="Tyto.Materializer.Redis" Version="0.0.1-alpha.47" />
<PackageVersion Include="Tyto.Materializer.Redis" Version="0.0.1-alpha.47" />
<PackageReference Include="Tyto.Materializer.Redis" />
paket add Tyto.Materializer.Redis --version 0.0.1-alpha.47
#r "nuget: Tyto.Materializer.Redis, 0.0.1-alpha.47"
#:package Tyto.Materializer.Redis@0.0.1-alpha.47
#addin nuget:?package=Tyto.Materializer.Redis&version=0.0.1-alpha.47&prerelease
#tool nuget:?package=Tyto.Materializer.Redis&version=0.0.1-alpha.47&prerelease
Tyto.Materializer.Redis
This package provides a high-performance, distributed IViewStore<TView, TKey> implementation using Redis. It is designed to work seamlessly with the Tyto.Materializer core library, enabling resilient, eventually consistent read models in distributed systems.
🚀 Features
- Atomic Optimistic Locking: Uses custom Lua Scripts to perform atomic "Compare-and-Swap" operations on version numbers directly on the Redis server. This guarantees data consistency without external locks.
- Binary Serialization: Integrated with
Wiaoj.Serializationto store data as byte arrays. Supports System.Text.Json (default), MessagePack, Protobuf, etc. - Shadow Versioning: Maintains a separate shadow key (suffix
:v) for version tracking. This ensures version integrity even if the data payload structure changes or serialization fails. - Pluggable Key Strategies: Includes
IViewKeyGeneratorabstraction to customize how Redis keys are named (e.g., handling prefixes for multi-tenant applications).
📦 Installation
dotnet add package Tyto.Materializer.Redis
⚡ Usage
1. Basic Configuration
In your application startup (Program.cs), configure Tyto to use the Redis store provider. You can provide a connection string or an existing IConnectionMultiplexer.
builder.Services.AddTytoConfiguration(tyto =>
{
tyto.AddMaterializer(materializer =>
{
materializer.ForView<UserBalanceView>()
.IdentifiedAs<Guid>(c => c.From<UserCreated>(e => e.UserId))
// Configure Redis as the View Store
.Store.UseRedis("localhost:6379,abortConnect=false");
});
});
2. High-Performance Binary Serialization
By default, the provider uses System.Text.Json. For production scenarios requiring high throughput and smaller payloads, we strongly recommend using MessagePack via the Wiaoj abstraction.
// In Program.cs
builder.Services.AddWiaojSerializer(serializer =>
{
// Configure the default key used by Materializer to use MessagePack
serializer.UseMessagePack<MaterializerDefaultSerializerKey>();
});
// Tyto automatically detects this configuration and switches to MessagePack.
3. Custom Key Generation Strategy
By default, keys are generated in the format: tyto:view:{TypeName}:{Key}.
If you need a custom format (e.g., to include Tenant IDs), implement IViewKeyGenerator:
using Tyto.Materializer.Redis;
public class TenantAwareKeyGenerator : IViewKeyGenerator
{
public string GenerateDataKey<TView, TKey>(TKey key) where TView : IProjectableView
{
// Example: "app:tenant:123:user_balance:guid_key"
return $"app:tenant:{GetCurrentTenantId()}:{typeof(TView).Name.ToLower()}:{key}";
}
public string GenerateVersionKey(string dataKey) => $"{dataKey}:v";
}
// Register your strategy in DI
builder.Services.AddSingleton<IViewKeyGenerator, TenantAwareKeyGenerator>();
🔧 How It Works Internally
Unlike standard cache providers which typically use a "Last-Write-Wins" strategy, Tyto.Materializer.Redis strictly enforces versioning to prevent data loss during concurrent updates.
The Read Operation
- Fetches the binary data from the Data Key.
- Fetches the current version from the Shadow Key (
:v). - Deserializes the view and ensures the in-memory
Versionproperty matches the Shadow Key.
The Write Operation (Atomic Lua Script)
When SaveAsync is called:
- The view is serialized to
byte[]. - A Lua script is sent to Redis containing the
NewDataand theExpectedVersion. - Redis Logic:
local currentVersion = redis.call('GET', VersionKey) if currentVersion == ExpectedVersion then redis.call('SET', DataKey, NewData) redis.call('INCR', VersionKey) -- Increment version atomically return Success else return Fail end - If the script returns Fail, the C# code throws a
ConcurrencyException. - Tyto Core catches this exception, reloads the fresh data, re-applies the projection logic, and retries.
This mechanism guarantees Strong Eventual Consistency. Updates are never lost, even if multiple consumers process events for the same view simultaneously.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- StackExchange.Redis (>= 2.9.17)
- Tyto.Materializer (>= 0.0.1-alpha.47)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.0.1-alpha.47 | 47 | 2/26/2026 |
| 0.0.1-alpha.46 | 43 | 2/22/2026 |
| 0.0.1-alpha.45 | 47 | 2/21/2026 |
| 0.0.1-alpha.44 | 50 | 2/21/2026 |
| 0.0.1-alpha.43 | 45 | 2/21/2026 |
| 0.0.1-alpha.42 | 47 | 2/20/2026 |
| 0.0.1-alpha.41 | 45 | 2/20/2026 |
| 0.0.1-alpha.40 | 47 | 2/20/2026 |
| 0.0.1-alpha.39 | 48 | 2/16/2026 |
| 0.0.1-alpha.38 | 50 | 2/15/2026 |
| 0.0.1-alpha.37 | 48 | 2/15/2026 |
| 0.0.1-alpha.36 | 46 | 2/15/2026 |
| 0.0.1-alpha.35 | 49 | 2/11/2026 |
| 0.0.1-alpha.34 | 46 | 2/11/2026 |
| 0.0.1-alpha.33 | 53 | 2/7/2026 |
| 0.0.1-alpha.32 | 52 | 1/26/2026 |
| 0.0.1-alpha.31 | 50 | 1/20/2026 |
| 0.0.1-alpha.30 | 49 | 1/17/2026 |
| 0.0.1-alpha.29 | 50 | 1/17/2026 |
| 0.0.1-alpha.28 | 53 | 1/14/2026 |