Files
CleanArchitecture-template/docs/OptionsPattern-Usage.md
2026-02-26 14:04:18 +07:00

4.0 KiB

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

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

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

// 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

// 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

{
  "Email": {
    "SmtpServer": "smtp.gmail.com",
    "SmtpPort": 587,
    "FromAddress": "noreply@example.com"
  }
}

Bước 4: Sử dụng trong Service

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: Giá trị được cache, không tự động reload khi config thay đổi
  • IOptionsSnapshot: Tự động reload khi config thay đổi (scoped)
  • IOptionsMonitor: Tự động reload và có thể subscribe để nhận thông báo (singleton)

Thông thường, sử dụng IOptions là đủ.