Options pattern bind một section trong appsettings.json vào class strongly-typed rồi inject qua DI, thay vì đọc IConfiguration["Key:SubKey"] bằng chuỗi khắp nơi.
csharp
builder.Services.Configure<MailOptions>(
builder.Configuration.GetSection("Mail"));
public class MailSender(IOptions<MailOptions> options)
{
private readonly MailOptions _opt = options.Value;
}Ba interface khác nhau ở lifetime và khả năng nhận thay đổi:
IOptions<T>: singleton, đọc một lần lúc app khởi động, không nhận cấu hình đổi sau đó. Mặc định dùng cái này.IOptionsSnapshot<T>: scoped, tính lại một lần mỗi request nên nhận được giá trị mới khi file config reload. Không inject được vào singleton.IOptionsMonitor<T>: singleton, đọc giá trị hiện tại bất kỳ lúc nào qua.CurrentValuevà cóOnChangeđể đăng ký callback. Đây là lựa chọn khi cần đọc cấu hình động từ trong một singleton hoặcBackgroundService.
Thêm .ValidateDataAnnotations().ValidateOnStart() để app fail ngay lúc khởi động nếu cấu hình thiếu, thay vì lỗi khi request đầu tiên chạy vào.