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
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Hexalith.KeyValueStorages.DaprComponents" Version="2.1.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Hexalith.KeyValueStorages.DaprComponents" Version="2.1.2" />
                    
Directory.Packages.props
<PackageReference Include="Hexalith.KeyValueStorages.DaprComponents" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Hexalith.KeyValueStorages.DaprComponents --version 2.1.2
                    
#r "nuget: Hexalith.KeyValueStorages.DaprComponents, 2.1.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Hexalith.KeyValueStorages.DaprComponents@2.1.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Hexalith.KeyValueStorages.DaprComponents&version=2.1.2
                    
Install as a Cake Addin
#tool nuget:?package=Hexalith.KeyValueStorages.DaprComponents&version=2.1.2
                    
Install as a Cake Tool

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.

  1. Each key-value pair is stored in the actor's state
  2. The actor handles concurrency control using etags
  3. 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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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