【发布时间】:2021-08-30 10:51:20
【问题描述】:
我正在努力实现 pub/sub 模式以供缓存使用。假设以下类用于发布任何类型的数据。订阅者可以在事件上附加ActionT 的回调。但是如果不使类成为通用类,我就无法在类级别创建通用事件,我不想这样做。因此,我尝试使用JsonSerializer 将值来回转换为字符串,如下所示。
public class CacheNotification
{
public Action<string> CachePublished;
public Task Publish<T>(T value)
{
var json = JsonSerializer.Serialize(value);
OnCachePublished(json);
return Task.CompletedTask;
}
public Task Subscribe<T>(Action<T> callback)
{
Action<string> newCallback = (string json) =>
callback(JsonSerializer.Deserialize<T>(json));
CachePublished += newCallback;
return Task.CompletedTask;
}
protected virtual void OnCachePublished(string value)
{
if(CachePublished != null){
CachePublished.Invoke(value);
}
}
}
所以问题出在订阅方法上,我尝试的转换仅适用于Action 字符串。它在 Action int 或 Action object 上失败了
public Task Subscribe<T>(Action<T> callback)
{
Action<string> newCallback = (string json) =>
callback(JsonSerializer.Deserialize<T>(json));
CachePublished += newCallback;
return Task.CompletedTask;
}
这是我使用的一个测试。第二个订阅者失败
Action<string> sub1Callback = msg =>
{
sub1Counter++;
};
Action<int> sub2Callback = num =>
{
sub2Counter++;
};
var sub1 = await cache.Subscribe(sub1Callback);
var sub2 = await cache.Subscribe(sub2Callback);
await cache.Publish("Value1");
Assert.Equal(1, sub1Counter);
Assert.Equal(1, sub2Counter);
【问题讨论】:
-
您好,您的代码失败时会出现什么异常?
-
仅基于您上次的 sn-p,仅发布字符串时您期望发生什么?您的解释对于您期望发生的事情非常混乱。是否应该只触发与传递值相同类型的动作?那么合并这两个完全不同的订阅的目的是什么?您也没有发布
sub1Counter和sub2Counter的初始值,因此断言语句不会向读者传达任何信息。 -
“但是我不能在类级别创建一个通用事件而不使类通用,我不想这样做。” 你为什么不想做解决手头问题的事情吗?
-
另外,虽然整数和(一些!)字符串之间可以进行转换,但在处理无法转换为另一种类型的类型时,您希望发生什么?
-
谢谢你们的cmets。我现在看到了问题。
标签: c# .net-core publish-subscribe