Phân biệt IOptions, IOptionsSnapshot và IOptionsMonitor trong ASP.NET Core: Hướng dẫn chi tiết
Khi làm việc với Options Pattern trong ASP.NET Core, việc map (ánh xạ) file appsettings.json sang class C# chỉ là bước đầu tiên. Câu hỏi quan trọng tiếp theo là: Làm thế nào để inject và sử dụng class đó hiệu quả?
Microsoft cung cấp 3 interface chính để làm việc này:
IOptions<T>IOptionsSnapshot<T>IOptionsMonitor<T>
Thoạt nhìn chúng có vẻ giống nhau, nhưng việc chọn sai interface có thể dẫn đến lỗi nghiêm trọng (như memory leak, crash ứng dụng) hoặc ứng dụng không cập nhật cấu hình mới. Bài viết này sẽ giúp bạn hiểu rõ bản chất và sự khác biệt của từng loại.
1. IOptions<T> - Lựa chọn cơ bản nhất
Đây là interface đơn giản nhất và thường được sử dụng mặc định khi bạn mới học về Options Pattern.
Đặc điểm cốt lõi:
Lifetime:
Singleton.Cơ chế: Khi ứng dụng khởi động, nó đọc file cấu hình một lần duy nhất, bind dữ liệu vào class POCO và lưu vào bộ nhớ.
Khả năng cập nhật (Hot-reload): KHÔNG. Nếu bạn sửa file
appsettings.jsonkhi ứng dụng đang chạy, giá trị trongIOptionssẽ không thay đổi. Bạn bắt buộc phải restart ứng dụng.
Khi nào nên dùng?
Dùng cho các cấu hình tĩnh, không bao giờ thay đổi trong suốt vòng đời ứng dụng (ví dụ: Domain name, thông tin license, các hằng số hệ thống).
Khi bạn cần hiệu năng cao nhất (vì không tốn chi phí đọc lại file).
C#
// Đăng ký (Program.cs)
builder.Services.Configure<MyConfig>(builder.Configuration.GetSection("MyConfig"));
// Sử dụng
public class HomeController : Controller
{
private readonly MyConfig _config;
// Inject IOptions<T>
public HomeController(IOptions<MyConfig> options)
{
_config = options.Value; // Lấy giá trị
}
}
2. IOptionsSnapshot<T> - Cập nhật theo Request
Nếu bạn muốn thay đổi cấu hình mà không cần restart server, IOptionsSnapshot là giải pháp đầu tiên.
Đặc điểm cốt lõi:
Lifetime:
Scoped.Cơ chế: Dữ liệu cấu hình được tính toán lại mỗi khi có một Request mới.
Khả năng cập nhật (Hot-reload): CÓ.
Tính nhất quán (Consistency): Trong cùng một HTTP Request, giá trị của nó là bất biến. Dù bạn gọi nó ở 10 service khác nhau trong cùng 1 request, nó vẫn trả về cùng 1 giá trị (kể cả khi file config bị sửa giữa chừng quá trình xử lý request đó).
Khi nào nên dùng?
Khi bạn cần cấu hình có thể thay đổi "nóng" (ví dụ: bật/tắt tính năng bằng Feature Flag, thay đổi tỷ lệ khuyến mãi).
Lưu ý quan trọng: Vì nó là
Scoped, bạn không thể injectIOptionsSnapshotvào một service làSingleton. Nếu cố tình làm vậy, ứng dụng sẽ báo lỗi (hoặc gây ra lỗi logic nghiêm trọng).
C#
// Sử dụng
public class OrderService
{
private readonly MyConfig _config;
// Inject IOptionsSnapshot<T>
public OrderService(IOptionsSnapshot<MyConfig> options)
{
_config = options.Value; // Giá trị mới nhất tại thời điểm request bắt đầu
}
}
3. IOptionsMonitor<T> - Theo dõi thời gian thực
Đây là interface mạnh mẽ nhất, dùng cho các kịch bản phức tạp hoặc khi cần inject cấu hình động vào các Singleton service.
Đặc điểm cốt lõi:
Lifetime:
Singleton.Cơ chế: Nó hoạt động như một "người giám sát". Nó luôn trả về giá trị mới nhất tại thời điểm bạn truy cập thuộc tính
.CurrentValue.Khả năng cập nhật (Hot-reload): CÓ.
Sự kiện (Events): Hỗ trợ
OnChangeđể bắn ra sự kiện khi file cấu hình thay đổi.
Khi nào nên dùng?
Khi bạn cần đọc cấu hình mới nhất trong một Singleton Service (nơi mà
IOptionsSnapshotkhông dùng được).Khi bạn cần thực hiện một hành động nào đó ngay khi cấu hình thay đổi (ví dụ: xóa cache khi connection string thay đổi).
C#
public class SingletonService
{
private readonly IOptionsMonitor<MyConfig> _monitor;
public SingletonService(IOptionsMonitor<MyConfig> monitor)
{
_monitor = monitor;
// Đăng ký sự kiện khi config thay đổi
_monitor.OnChange(config => {
Console.WriteLine("Config has changed!");
});
}
public void DoWork()
{
// Luôn lấy giá trị mới nhất qua .CurrentValue
var currentValue = _monitor.CurrentValue;
}
}
Bảng so sánh tóm tắt (Cheat Sheet)
Đặc điểmIOptions<T>IOptionsSnapshot<T>IOptionsMonitor<T>LifetimeSingletonScopedSingletonĐọc lại dữ liệuChỉ khi App StartMỗi RequestKhi có thay đổiHot ReloadKhôngCóCóHiệu năngTốt nhấtThấp hơn (do đọc lại)TốtTruy cập giá trị.Value.Value.CurrentValueDùng trong Singleton?CóKHÔNGCó
Kết luận: Nên chọn cái nào?
Mặc định hãy dùng
IOptions<T>vì nó nhẹ và nhanh nhất.Nếu cần thay đổi cấu hình mà không restart app, hãy dùng
IOptionsSnapshot<T>.Nếu cần dùng cấu hình động bên trong một Singleton Service, hoặc cần bắt sự kiện
OnChange, hãy dùngIOptionsMonitor<T>.
Hiểu rõ 3 class này giúp bạn làm chủ hoàn toàn việc quản lý cấu hình trong .NET Core, tránh được các lỗi "inject Scoped vào Singleton" kinh điển.
Tác giả: Bạch Ngọc Toàn
Chú ý: Tất cả các bài viết trên TEDU.COM.VN đều thuộc bản quyền TEDU, yêu cầu dẫn nguồn khi trích lại trên website khác.
Tags:
Bài viết liên quan
Xây dựng menu đa cấp với ASP.NET Core MVC
Cách xây dựng menu đa cấp sử dụng đệ quy trong ASP.NET Core MVC
Đọc thêm
Tìm hiểu về ABP Framework, một framework mã nguồn mở trên .NET
ABP Framework là một framework hoàn chỉnh để xây dựng ứng dụng web hiện đại bằng cách áp dụng các best practice và tiêu chuẩn trong phát triển phần mềm.
Đọc thêm
Tìm lỗi ứng dụng ASP.NET Core trên Windows Server sử dụng stdout log
Một số lỗi trong lúc khởi động hệ thống ASP.NET Core trên Windows Server mà chúng ta chưa rõ nguyên nhân tại sao ứng dụng không hoạt động. Vậy bạn có thể dùng đểns stdout để chẩn đoán lỗi.
Đọc thêmVòng đời của Dependency Injection: Transient, Singleton và Scoped
Hiểu về vòng đời của các service được tạo sử dụng Dependency Injection là rất quan trọng trước khi sử dụng chúng.
Đọc thêm
Cơ chế Dependency Injection trong ASP.NET Core
Dependency Injection giờ đã trở thành thành phần chính thức mặc định của ASP.NET Core.
Đọc thêm
Unobtrusive Client Validation trong ASP.NET Corre
Trong bài viết này chúng ta sẽ thực hiện validation phía client sử dụng Javascript.
Đọc thêm
Validation Tag Helper trong ASP.NET Core
ASP.NET cung cấp các tag helper liên quan đến hiển thị validation message cho người dùng.
Đọc thêm
Model Validation trong ASP.NET Core
Bài viết này chúng ta sẽ học về cơ chế Model Validation.
Đọc thêm
Cơ chế Model Binding: Truyền dữ liệu từ View lên Controller
Trong cơ chế Model Binding của ASP.NET Core chúng ta sẽ học cách làm sao để truyền dữ liệu từ View lên Controller.
Đọc thêm
Environment Tag Helper trong ASP.NET Core
Environment tag helper hỗ trợ tạo ra các nội dung phụ thuộc vào biến quy định môi trường trong ASP.NET Core.
Đọc thêm