diff --git a/Directory.Packages.props b/Directory.Packages.props
index 0cd8288..00c5a71 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -31,6 +31,7 @@
+
diff --git a/src/HelloShop.BasketService/HelloShop.BasketService.csproj b/src/HelloShop.BasketService/HelloShop.BasketService.csproj
index 2b317ee..1dcee1a 100644
--- a/src/HelloShop.BasketService/HelloShop.BasketService.csproj
+++ b/src/HelloShop.BasketService/HelloShop.BasketService.csproj
@@ -17,6 +17,7 @@
+
diff --git a/src/HelloShop.BasketService/Program.cs b/src/HelloShop.BasketService/Program.cs
index 966bc47..203cddf 100644
--- a/src/HelloShop.BasketService/Program.cs
+++ b/src/HelloShop.BasketService/Program.cs
@@ -28,7 +28,8 @@ builder.Services.AddAuthentication().AddJwtBearer(options =>
builder.Services.AddHttpContextAccessor();
builder.AddRedisDistributedCache("cache");
-builder.Services.AddSingleton();
+builder.Services.AddHybridCache();
+builder.Services.AddSingleton();
builder.Services.AddGrpc().AddJsonTranscoding();
builder.Services.AddGrpcSwagger();
diff --git a/src/HelloShop.BasketService/Repositories/BasketRepository.cs b/src/HelloShop.BasketService/Repositories/BasketRepository.cs
new file mode 100644
index 0000000..52480d4
--- /dev/null
+++ b/src/HelloShop.BasketService/Repositories/BasketRepository.cs
@@ -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 GetBasketAsync(int customerId, CancellationToken cancellationToken = default)
+ {
+ return await cache.GetOrCreateAsync(GetBasketKey(customerId), async cancel => await Task.FromResult(default), cancellationToken: cancellationToken);
+ }
+
+ public async Task 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);
+ }
+ }
+}
diff --git a/src/HelloShop.BasketService/Repositories/DistributedCacheBasketRepository.cs b/src/HelloShop.BasketService/Repositories/DistributedCacheBasketRepository.cs
deleted file mode 100644
index 135609f..0000000
--- a/src/HelloShop.BasketService/Repositories/DistributedCacheBasketRepository.cs
+++ /dev/null
@@ -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 GetBasketAsync(int customerId, CancellationToken token = default) => await cache.GetObjectAsync(GetBasketKey(customerId), token);
-
- public async Task 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);
- }
- }
-}
diff --git a/src/HelloShop.BasketService/Repositories/IBasketRepository.cs b/src/HelloShop.BasketService/Repositories/IBasketRepository.cs
index 835a026..00694f9 100644
--- a/src/HelloShop.BasketService/Repositories/IBasketRepository.cs
+++ b/src/HelloShop.BasketService/Repositories/IBasketRepository.cs
@@ -7,10 +7,10 @@ namespace HelloShop.BasketService.Repositories
{
public interface IBasketRepository
{
- Task GetBasketAsync(int customerId, CancellationToken token = default);
+ Task GetBasketAsync(int customerId, CancellationToken cancellationToken = default);
- Task UpdateBasketAsync(CustomerBasket basket, CancellationToken token = default);
+ Task UpdateBasketAsync(CustomerBasket basket, CancellationToken cancellationToken = default);
- Task DeleteBasketAsync(int customerId, CancellationToken token = default);
+ Task DeleteBasketAsync(int customerId, CancellationToken cancellationToken = default);
}
}