first commit

This commit is contained in:
2026-02-26 14:04:18 +07:00
parent 57ac80a666
commit 4b7236493f
92 changed files with 4999 additions and 0 deletions

View File

@@ -0,0 +1,157 @@
# Options Pattern - Hướng dẫn sử dụng
## Tổng quan
Options Pattern là cách tiếp cận **Strongly-Typed** để quản lý cấu hình trong .NET, thay vì sử dụng `IConfiguration` trực tiếp với magic strings.
## Lợi ích
1. **Type Safety**: IntelliSense hỗ trợ, tránh lỗi chính tả
2. **Validation**: Validate cấu hình ngay khi khởi động ứng dụng
3. **Separation of Concerns**: Tách biệt Infrastructure (config) khỏi Application logic
4. **Testability**: Dễ dàng mock và test
## Cách sử dụng trong Service
### Ví dụ: Sử dụng JwtOptions trong Service
```csharp
using Microsoft.Extensions.Options;
using MyNewProjectName.Infrastructure.Options;
public class JwtTokenService
{
private readonly JwtOptions _jwtOptions;
// Inject IOptions<JwtOptions> thay vì IConfiguration
public JwtTokenService(IOptions<JwtOptions> jwtOptions)
{
_jwtOptions = jwtOptions.Value;
}
public string GenerateToken()
{
// Sử dụng với IntelliSense hỗ trợ
var secretKey = _jwtOptions.SecretKey;
var issuer = _jwtOptions.Issuer;
var expiration = _jwtOptions.ExpirationInMinutes;
// ... logic tạo token
return token;
}
}
```
### Ví dụ: Sử dụng DatabaseOptions
```csharp
using Microsoft.Extensions.Options;
using MyNewProjectName.Infrastructure.Options;
public class DatabaseService
{
private readonly DatabaseOptions _dbOptions;
public DatabaseService(IOptions<DatabaseOptions> dbOptions)
{
_dbOptions = dbOptions.Value;
}
public string GetConnectionString()
{
return _dbOptions.DefaultConnection;
}
}
```
## Các Options Classes có sẵn
1. **DatabaseOptions** - Cấu hình kết nối database
2. **JwtOptions** - Cấu hình JWT authentication
3. **RedisOptions** - Cấu hình Redis cache
4. **SerilogOptions** - Cấu hình Serilog logging
## Thêm Options Class mới
### Bước 1: Tạo Options Class
```csharp
// MyNewProjectName.Infrastructure/Options/EmailOptions.cs
using System.ComponentModel.DataAnnotations;
namespace MyNewProjectName.Infrastructure.Options;
public class EmailOptions
{
public const string SectionName = "Email";
[Required]
public string SmtpServer { get; set; } = string.Empty;
[Range(1, 65535)]
public int SmtpPort { get; set; } = 587;
[Required]
[EmailAddress]
public string FromAddress { get; set; } = string.Empty;
}
```
### Bước 2: Đăng ký trong DependencyInjection.cs
```csharp
// Trong MyNewProjectName.Infrastructure/DependencyInjection.cs
services.Configure<EmailOptions>(configuration.GetSection(EmailOptions.SectionName));
// Validate (optional)
services.AddOptions<EmailOptions>()
.Bind(configuration.GetSection(EmailOptions.SectionName))
.ValidateDataAnnotations()
.ValidateOnStart();
```
### Bước 3: Thêm vào appsettings.json
```json
{
"Email": {
"SmtpServer": "smtp.gmail.com",
"SmtpPort": 587,
"FromAddress": "noreply@example.com"
}
}
```
### Bước 4: Sử dụng trong Service
```csharp
public class EmailService
{
private readonly EmailOptions _emailOptions;
public EmailService(IOptions<EmailOptions> emailOptions)
{
_emailOptions = emailOptions.Value;
}
}
```
## Validation
Options classes sử dụng Data Annotations để validate:
- `[Required]` - Bắt buộc phải có giá trị
- `[MinLength]` - Độ dài tối thiểu
- `[Range]` - Giá trị trong khoảng
- `[EmailAddress]` - Định dạng email
- Và nhiều attributes khác...
Nếu validation fail, ứng dụng sẽ **không khởi động** và báo lỗi rõ ràng.
## IOptions vs IOptionsSnapshot vs IOptionsMonitor
- **IOptions<T>**: Giá trị được cache, không tự động reload khi config thay đổi
- **IOptionsSnapshot<T>**: Tự động reload khi config thay đổi (scoped)
- **IOptionsMonitor<T>**: Tự động reload và có thể subscribe để nhận thông báo (singleton)
Thông thường, sử dụng **IOptions<T>** là đủ.