Hexalith.KeyValueStorages.DaprComponents
2.1.2
dotnet add package Hexalith.KeyValueStorages.DaprComponents --version 2.1.2
NuGet\Install-Package Hexalith.KeyValueStorages.DaprComponents -Version 2.1.2
<PackageReference Include="Hexalith.KeyValueStorages.DaprComponents" Version="2.1.2" />
<PackageVersion Include="Hexalith.KeyValueStorages.DaprComponents" Version="2.1.2" />
<PackageReference Include="Hexalith.KeyValueStorages.DaprComponents" />
paket add Hexalith.KeyValueStorages.DaprComponents --version 2.1.2
#r "nuget: Hexalith.KeyValueStorages.DaprComponents, 2.1.2"
#:package Hexalith.KeyValueStorages.DaprComponents@2.1.2
#addin nuget:?package=Hexalith.KeyValueStorages.DaprComponents&version=2.1.2
#tool nuget:?package=Hexalith.KeyValueStorages.DaprComponents&version=2.1.2
Hexalith.KeyValueStorages.DaprComponents
This library provides a Dapr actor-based implementation of the key-value storage interface. It uses Dapr actors to ensure concurrency control and data consistency.
Features
- Thread-safe key-value storage using Dapr actors
- Automatic concurrency control with etags
- Serialization support for keys and values
- Easy integration with ASP.NET Core and Dapr applications
Getting Started
Prerequisites
- .NET 9.0 or later
- Dapr runtime installed and configured
Installation
Add the package to your project:
dotnet add package Hexalith.KeyValueStorages.DaprComponents
Usage
1. Register the actor and key-value storage in your ASP.NET Core application
using Hexalith.KeyValueStorages;
using Hexalith.KeyValueStorages.DaprComponents.Extensions;
var builder = WebApplication.CreateBuilder(args);
// Register the Dapr actor key-value storage
builder.Services.AddDaprActorKeyValueStorage<string, MyData, KeyToStringSerializer<string>, MyDataSerializer>();
var app = builder.Build();
// Configure the Dapr actors middleware
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapActorsHandlers();
});
app.Run();
2. Create a value serializer
using System.Text.Json;
using Hexalith.KeyValueStorages;
public class MyDataSerializer : IValueSerializer<MyData, string>
{
public string DataType => "application/json";
public (MyData Value, string Etag) Deserialize(string value)
{
var document = JsonDocument.Parse(value);
var root = document.RootElement;
string etag = root.GetProperty("etag").GetString() ?? throw new InvalidOperationException("Etag is missing");
MyData data = JsonSerializer.Deserialize<MyData>(root.GetProperty("data").GetRawText())
?? throw new InvalidOperationException("Failed to deserialize data");
return (data, etag);
}
public async Task<(MyData Value, string Etag)> DeserializeAsync(Stream stream, CancellationToken cancellationToken)
{
using var document = await JsonDocument.ParseAsync(stream, cancellationToken: cancellationToken);
var root = document.RootElement;
string etag = root.GetProperty("etag").GetString() ?? throw new InvalidOperationException("Etag is missing");
MyData data = JsonSerializer.Deserialize<MyData>(root.GetProperty("data").GetRawText())
?? throw new InvalidOperationException("Failed to deserialize data");
return (data, etag);
}
public string Serialize(MyData value, string etag)
{
var wrapper = new { data = value, etag };
return JsonSerializer.Serialize(wrapper);
}
public async Task SerializeAsync(Stream stream, MyData value, string etag, CancellationToken cancellationToken)
{
var wrapper = new { data = value, etag };
await JsonSerializer.SerializeAsync(stream, wrapper, cancellationToken: cancellationToken);
}
}
3. Use the key-value storage in your application
public class MyService
{
private readonly IKeyValueStore<string, MyData, string> _storage;
public MyService(IKeyValueStore<string, MyData, string> storage)
{
_storage = storage;
}
public async Task SaveDataAsync(string key, MyData data, CancellationToken cancellationToken)
{
// Add new data
string etag = await _storage.AddAsync(key, data, cancellationToken);
// Update existing data
data.UpdatedAt = DateTime.UtcNow;
string newEtag = await _storage.SetAsync(key, data, etag, cancellationToken);
// Get data
StoreResult<MyData, string> result = await _storage.GetAsync(key, cancellationToken);
Console.WriteLine($"Data: {result.Value}, Etag: {result.Etag}");
}
}
How It Works
The Dapr actor-based key-value storage uses Dapr actors to ensure that only one operation can be performed on a key at a time. This prevents race conditions and ensures data consistency.
- Each key-value pair is stored in the actor's state
- The actor handles concurrency control using etags
- The actor ensures that only one operation can be performed on a key at a time
Configuration
You can configure the actor settings when registering the key-value storage:
builder.Services.AddDaprActorKeyValueStorage<string, MyData, KeyToStringSerializer<string>, MyDataSerializer>(
actorTypeName: "CustomKeyValueStoreActor");
Advanced Usage
Custom Actor Type Name
You can specify a custom actor type name when registering the key-value storage:
builder.Services.AddDaprActorKeyValueStorage<string, MyData, KeyToStringSerializer<string>, MyDataSerializer>(
actorTypeName: "CustomKeyValueStoreActor");
Custom Key Serializer
You can create a custom key serializer by implementing the IKeySerializer<TKey>
interface:
public class CustomKeySerializer<TKey> : IKeySerializer<TKey>
where TKey : notnull
{
public string Serialize(TKey key)
{
// Custom serialization logic
return key.ToString() ?? throw new InvalidOperationException("Key cannot be null");
}
}
Custom Value Serializer
You can create a custom value serializer by implementing the IValueSerializer<TValue, TEtag>
interface:
public class CustomValueSerializer<TValue> : IValueSerializer<TValue, string>
{
public string DataType => "application/custom";
public (TValue Value, string Etag) Deserialize(string value)
{
// Custom deserialization logic
// ...
}
public Task<(TValue Value, string Etag)> DeserializeAsync(Stream stream, CancellationToken cancellationToken)
{
// Custom async deserialization logic
// ...
}
public string Serialize(TValue value, string etag)
{
// Custom serialization logic
// ...
}
public Task SerializeAsync(Stream stream, TValue value, string etag, CancellationToken cancellationToken)
{
// Custom async serialization logic
// ...
}
}
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. 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. |
-
net9.0
- Dapr.Actors (>= 1.15.2)
- Dapr.Actors.AspNetCore (>= 1.15.2)
- Dapr.Actors.Generators (>= 1.15.2)
- Hexalith.Commons.StringEncoders (>= 1.65.1)
- Hexalith.Commons.UniqueIds (>= 1.66.3)
- Hexalith.KeyValueStorages (>= 2.1.2)
- Hexalith.KeyValueStorages.Abstractions (>= 2.1.2)
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 |
---|---|---|
2.1.2 | 99 | 4/12/2025 |
2.1.1 | 137 | 4/11/2025 |
2.1.0 | 145 | 4/11/2025 |
2.0.2 | 163 | 4/10/2025 |
2.0.1 | 156 | 4/10/2025 |
2.0.0 | 164 | 4/10/2025 |
1.6.0 | 157 | 4/9/2025 |
1.5.0 | 152 | 4/8/2025 |
1.4.2 | 160 | 4/8/2025 |
1.4.1 | 159 | 4/7/2025 |
1.4.0 | 160 | 4/7/2025 |
1.3.2 | 153 | 4/6/2025 |
1.3.1 | 157 | 4/6/2025 |
1.3.0 | 169 | 4/6/2025 |
1.2.0 | 165 | 4/6/2025 |