feat(docs): Add Redis Cache integration details to Vietnamese documentation

- Updated README.md to include Redis Cache integration as a new feature.
- Enhanced DependencyInjection.cs to register Redis Cache services and connection settings.
- Improved clarity in Vietnamese documentation regarding Clean Architecture principles.
This commit is contained in:
Ho Ngoc Hai
2026-01-10 21:24:18 +07:00
parent 0b0241143a
commit 2cfbd0706f
4 changed files with 68 additions and 1 deletions

View File

@@ -17,7 +17,8 @@
- ASP.NET Core 10 Web API
- Entity Framework Core 10 (PostgreSQL / Neon)
- **Neon Database Integration** (Connection Resilience)
- 原 tắc Clean Architecture
- **Redis Cache** (StackExchange.Redis)
- Nguyên tắc Clean Architecture
- **CQRS với MediatR**
- **Resilience với Polly**
- **Global Exception Handling (RFC 7807)**

View File

@@ -0,0 +1,8 @@
namespace YourServiceName.Domain.Common.Interfaces;
public interface ICacheService
{
Task<T> GetAsync<T>(string key, CancellationToken cancellationToken = default);
Task SetAsync<T>(string key, T value, TimeSpan? expiration = null, CancellationToken cancellationToken = default);
Task RemoveAsync(string key, CancellationToken cancellationToken = default);
}

View File

@@ -3,6 +3,8 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.EntityFrameworkCore;
using YourServiceName.Infrastructure.Data.Interceptors;
using YourServiceName.Domain.SeedWork;
using StackExchange.Redis;
using YourServiceName.Domain.Common.Interfaces;
namespace YourServiceName.Infrastructure;
@@ -30,6 +32,22 @@ public static class DependencyInjection
services.AddScoped<IUnitOfWork>(provider => provider.GetRequiredService<YourServiceNameContext>());
// EN: Register Redis Cache
// VI: Đăng ký Redis Cache
services.AddSingleton<IConnectionMultiplexer>(sp =>
{
var configuration = sp.GetRequiredService<IConfiguration>();
var connectionString = configuration.GetSection("Redis:ConnectionString").Value;
var instanceName = configuration.GetSection("Redis:InstanceName").Value;
var options = ConfigurationOptions.Parse(connectionString);
// options.ChannelPrefix = instanceName; // Optional prefix
return ConnectionMultiplexer.Connect(options);
});
services.AddScoped<ICacheService, Services.RedisCacheService>();
return services;
}
}

View File

@@ -0,0 +1,40 @@
using System.Text.Json;
using Microsoft.Extensions.Configuration;
using StackExchange.Redis;
using YourServiceName.Domain.Common.Interfaces;
namespace YourServiceName.Infrastructure.Services;
public class RedisCacheService : ICacheService
{
private readonly IConnectionMultiplexer _connectionMultiplexer;
private readonly IDatabase _database;
public RedisCacheService(IConnectionMultiplexer connectionMultiplexer)
{
_connectionMultiplexer = connectionMultiplexer;
_database = _connectionMultiplexer.GetDatabase();
}
public async Task<T> GetAsync<T>(string key, CancellationToken cancellationToken = default)
{
var value = await _database.StringGetAsync(key);
if (value.IsNullOrEmpty)
{
return default;
}
return JsonSerializer.Deserialize<T>(value);
}
public async Task SetAsync<T>(string key, T value, TimeSpan? expiration = null, CancellationToken cancellationToken = default)
{
var json = JsonSerializer.Serialize(value);
await _database.StringSetAsync(key, json, expiration);
}
public async Task RemoveAsync(string key, CancellationToken cancellationToken = default)
{
await _database.KeyDeleteAsync(key);
}
}