【C#】在.NET Aspire 中使用 Dapr 状态管理(State management)

【C#】在.NET Aspire 中使用 Dapr 状态管理(State management)

一、AppHost项目

statestore.yaml

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: statestore
spec:
  type: state.redis
  version: v1
  metadata:
  - name: redisHost
    value: localhost:6379
  - name: redisPassword
    value: ""
  - name: actorStateStore
    value: "true"
Componenttype
In-memorystate.in-memory
Redisstate.redis
SQLitestate.sqlite

在AppHost项目添加组件:

var stateStore = builder.AddDaprComponent("statestore", "state.redis",
    new DaprComponentOptions
    {
        LocalPath = "Resources\\statestore.yaml"
    });

在其他项目中添加引用:

builder.AddProject<Projects.Aspire_WPF>("wpfclient")
	// ...
	.WithReference(stateStore)  // 添加引用
	// ...

二、使用方法

private const string storeName = "statestore";

1、设置值

await _client.SaveStateAsync(storeName, "key1", DateTimeOffset.Now.ToUnixTimeMilliseconds().ToString(), cancellationToken: cts.Token);

2、读取值

var state = await _client.GetStateAsync<long>(storeName, "key1", cancellationToken: cts.Token);

3、删除键

await _client.DeleteStateAsync(storeName, "key1", cancellationToken: cts.Token);

三、其它方法

Binary数据

写二进制数据

var stateBytes = Encoding.UTF8.GetBytes(state);
await client.SaveByteStateAsync(storeName, stateKeyName, stateBytes.AsMemory(), cancellationToken: cancellationToken);

读二进制数据

var responseBytes = await client.GetByteStateAsync(storeName, stateKeyName, cancellationToken: cancellationToken);
var savedState = Encoding.UTF8.GetString(ByteString.CopyFrom(responseBytes.Span).ToByteArray());

ETag使用

保存状态,每次保存都会更新 ETag (SaveStateAsync)

await client.SaveStateAsync<Widget>(storeName, stateKeyName,  new Widget() { Size = "small", Color = "yellow", }, cancellationToken: cancellationToken);

读取状态和ETag (GetStateAndETagAsync)

var (original, originalETag) = await client.GetStateAndETagAsync<Widget>(storeName, stateKeyName, cancellationToken: cancellationToken);
Console.WriteLine($"Retrieved state: {original.Size}  {original.Color} with etag: {originalETag}");

使用 ETag 来更新状态 (TrySaveStateAsync

original.Color = "purple";
var isSaveStateSuccess = await client.TrySaveStateAsync<Widget>(storeName, stateKeyName, original, originalETag, cancellationToken: cancellationToken);
Console.WriteLine($"Saved state with old etag: {originalETag} successfully? {isSaveStateSuccess}");

注意:ETag 是否有效 。每次 SaveStateAsync 后都会更新ETag,原ETag将失效。

使用 ETag 来删除状态(TryDeleteStateAsync

var isDeleteStateSuccess = await client.TryDeleteStateAsync(storeName, stateKeyName, originalETag, cancellationToken: cancellationToken);
Console.WriteLine($"Deleted state with old etag: {originalETag} successfully? {isDeleteStateSuccess}");

批量操作

批量存

var state1 = new Widget() { Size = "small", Color = "yellow", };
var state2 = new Widget() { Size = "big", Color = "green", };

var stateItem1 = new SaveStateItem<Widget>(firstKey, state1, firstEtag);
var stateItem2 = new SaveStateItem<Widget>(secondKey, state2, secondEtag);

await client.SaveBulkStateAsync(storeName, new List<SaveStateItem<Widget>>() { stateItem1, stateItem2});

指量取

IReadOnlyList<BulkStateItem> states = await client.GetBulkStateAsync(storeName, 
	new List<string>(){firstKey, secondKey}, null);

批量删

var deleteBulkStateItem1 = new BulkDeleteStateItem(states[0].Key, states[0].ETag);
var deleteBulkStateItem2 = new BulkDeleteStateItem(states[1].Key, states[1].ETag);

await client.DeleteBulkStateAsync(storeName, new List<BulkDeleteStateItem>() { deleteBulkStateItem1, deleteBulkStateItem2 });

事务操作

var bytes = JsonSerializer.SerializeToUtf8Bytes(value); // System.Text.Json
// var bytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(value)); // Newtonsoft.Json

var requests = new List<StateTransactionRequest>()
{
	new StateTransactionRequest("widget", bytes, StateOperationType.Upsert),
	new StateTransactionRequest("oldwidget", null, StateOperationType.Delete)
};

await client.ExecuteStateTransactionAsync(storeName, requests, cancellationToken: cancellationToken);

StateOperationType

  • Upsert :插入或更新状态
  • Delete:删除状态

四、附配置文件

详情:docs.dapr.io/reference/components-reference/supported-state-stores/

In-Memory

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: <NAME>
spec:
  type: state.in-memory
  version: v1
  metadata: 
  # Uncomment this if you wish to use In-memory as a state store for actors (optional)
  #- name: actorStateStore
  #  value: "true"

Sqlite

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: <NAME>
spec:
  type: state.sqlite
  version: v1
  metadata:
  # Connection string
  - name: connectionString
    value: "data.db"
  # Timeout for database operations, in seconds (optional)
  #- name: timeoutInSeconds
  #  value: 20
  # Name of the table where to store the state (optional)
  #- name: tableName
  #  value: "state"
  # Cleanup interval in seconds, to remove expired rows (optional)
  #- name: cleanupInterval
  #  value: "1h"
  # Set busy timeout for database operations
  #- name: busyTimeout
  #  value: "2s"
  # Uncomment this if you wish to use SQLite as a state store for actors (optional)
  #- name: actorStateStore
  #  value: "true"
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值