Hi all, 來到 21天 今天就來把 Redis apply 至專案中吧!
來清點下,今日目標:
首先,必須在專案上安裝此 package: **StackExchange.Redis
,**再來到 program.cs
進行DI 註冊 。
切記這邊建議還是使用 Singleton進行 DI,以個人的工作經驗來說有一次使用 Transient 進行DI 結果把 Sever 的 Performance 耗能拉高了至少20% ( 至於 Transient 跟 Singleton 的差別,有空再做篇文章說)
builder.Services.AddSingleton<IConnectionMultiplexer>(
ConnectionMultiplexer.Connect(
new ConfigurationOptions
{
EndPoints = { { Environment.GetEnvironmentVariables()["Redis"]!.ToString()!, 6379} }
}
)
);
接著,我的策略是透過 Decorator Pattern 在我們的 IChainService
介面底下再實作一個 ChainCacheService
來做 Redis 快取的讀取。
Scrutor
替 ChainCacheService
做一層 DI ( 透過 Decorator 模式)
builder.Services.AddTransient<IChainService, ChainService>();
builder.Services.Decorate<IChainService, ChainCacheService>();
public class ChainCacheService(IConnectionMultiplexer redisRepository, IChainService chainService)
: IChainService
{
private readonly IDatabase _db = redisRepository.GetDatabase();
public async Task<BlockDomain> GetBlockById(int id)
{
var cachedBlock = await _db.StringGetAsync($"block:{id}");
if (!cachedBlock.IsNullOrEmpty)
{
return JsonSerializer.Deserialize<BlockDomain>(cachedBlock!)!;
}
var blockDomain = await chainService.GetBlockById(id);
await _db.StringSetAsync($"block:{id}", JsonSerializer.Serialize(blockDomain), TimeSpan.FromMinutes(5));
return blockDomain;
}
public async Task<BlockDomain> GenerateNewBlock(GenerateNewBlockDto dto)
{
var generateNewBlock = await chainService.GenerateNewBlock(dto);
await _db.StringSetAsync($"block:{generateNewBlock.Id}", JsonSerializer.Serialize(generateNewBlock),TimeSpan.FromMinutes(5) );
return generateNewBlock;
}
public async Task<BlockDomain> EditBlock(EditBlockDto editBlockDto)
{
var editBlock = await chainService.EditBlock(editBlockDto);
await _db.StringSetAsync($"block:{editBlock.Id}", JsonSerializer.Serialize(editBlock), TimeSpan.FromMinutes(5));
return editBlock;
}
}
執行專案起來 e2e瞧瞧啦~~~
今天把 Redis 與專案串通,但突然腦袋閃過一絲想法,我把Redis 這邊的讀寫稍稍封裝下,做個 SDK 直接讓專案 import 好像也不賴。