# 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 thay vì IConfiguration public JwtTokenService(IOptions 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 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(configuration.GetSection(EmailOptions.SectionName)); // Validate (optional) services.AddOptions() .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.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à đủ.