使用 HybridCache 混合缓存库

This commit is contained in:
hello 2025-03-29 10:15:15 +08:00
parent f007572e7f
commit 718be3b05c
6 changed files with 44 additions and 32 deletions

View File

@ -31,6 +31,7 @@
<PackageVersion Include="Microsoft.EntityFrameworkCore.InMemory" Version="9.0.3" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Relational" Version="9.0.3" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite" Version="9.0.3" />
<PackageVersion Include="Microsoft.Extensions.Caching.Hybrid" Version="9.3.0" />
<PackageVersion Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="9.0.2" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="9.0.3" />
<PackageVersion Include="Microsoft.Extensions.Hosting.Abstractions" Version="9.0.3" />

View File

@ -17,6 +17,7 @@
<PackageReference Include="Grpc.AspNetCore" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" />
<PackageReference Include="Microsoft.AspNetCore.Grpc.Swagger" />
<PackageReference Include="Microsoft.Extensions.Caching.Hybrid" />
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" />
</ItemGroup>
<ItemGroup>

View File

@ -28,7 +28,8 @@ builder.Services.AddAuthentication().AddJwtBearer(options =>
builder.Services.AddHttpContextAccessor();
builder.AddRedisDistributedCache("cache");
builder.Services.AddSingleton<IBasketRepository, DistributedCacheBasketRepository>();
builder.Services.AddHybridCache();
builder.Services.AddSingleton<IBasketRepository, BasketRepository>();
builder.Services.AddGrpc().AddJsonTranscoding();
builder.Services.AddGrpcSwagger();

View File

@ -0,0 +1,37 @@
// Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information.
using HelloShop.BasketService.Entities;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Caching.Hybrid;
using System.Threading;
namespace HelloShop.BasketService.Repositories
{
public class BasketRepository(HybridCache cache) : IBasketRepository
{
private const string BasketKeyPrefix = "basket";
private static string GetBasketKey(int customerId) => $"{BasketKeyPrefix}:{customerId}";
public async Task DeleteBasketAsync(int customerId, CancellationToken cancellationToken = default) => await cache.RemoveAsync(GetBasketKey(customerId), cancellationToken);
public async Task<CustomerBasket?> GetBasketAsync(int customerId, CancellationToken cancellationToken = default)
{
return await cache.GetOrCreateAsync(GetBasketKey(customerId), async cancel => await Task.FromResult<CustomerBasket?>(default), cancellationToken: cancellationToken);
}
public async Task<CustomerBasket?> UpdateBasketAsync(CustomerBasket basket, CancellationToken cancellationToken = default)
{
HybridCacheEntryOptions options = new()
{
Expiration = TimeSpan.MaxValue,
LocalCacheExpiration = TimeSpan.FromMinutes(5),
};
await cache.SetAsync(GetBasketKey(basket.BuyerId), basket, options, cancellationToken: cancellationToken);
return await GetBasketAsync(basket.BuyerId, cancellationToken);
}
}
}

View File

@ -1,28 +0,0 @@
// Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information.
using HelloShop.BasketService.Entities;
using Microsoft.Extensions.Caching.Distributed;
namespace HelloShop.BasketService.Repositories
{
public class DistributedCacheBasketRepository(IDistributedCache cache) : IBasketRepository
{
private const string BasketKeyPrefix = "basket";
private static string GetBasketKey(int customerId) => $"{BasketKeyPrefix}:{customerId}";
public async Task DeleteBasketAsync(int customerId, CancellationToken token = default) => await cache.RemoveAsync(GetBasketKey(customerId), token);
public async Task<CustomerBasket?> GetBasketAsync(int customerId, CancellationToken token = default) => await cache.GetObjectAsync<CustomerBasket>(GetBasketKey(customerId), token);
public async Task<CustomerBasket?> UpdateBasketAsync(CustomerBasket basket, CancellationToken token = default)
{
DistributedCacheEntryOptions options = new() { SlidingExpiration = TimeSpan.MaxValue };
await cache.SetObjectAsync(GetBasketKey(basket.BuyerId), basket, options, token);
return await GetBasketAsync(basket.BuyerId, token);
}
}
}

View File

@ -7,10 +7,10 @@ namespace HelloShop.BasketService.Repositories
{
public interface IBasketRepository
{
Task<CustomerBasket?> GetBasketAsync(int customerId, CancellationToken token = default);
Task<CustomerBasket?> GetBasketAsync(int customerId, CancellationToken cancellationToken = default);
Task<CustomerBasket?> UpdateBasketAsync(CustomerBasket basket, CancellationToken token = default);
Task<CustomerBasket?> UpdateBasketAsync(CustomerBasket basket, CancellationToken cancellationToken = default);
Task DeleteBasketAsync(int customerId, CancellationToken token = default);
Task DeleteBasketAsync(int customerId, CancellationToken cancellationToken = default);
}
}