According to this answer, IOptionsMonitor
is registered in DI container as singleton and is capable of detecting changes through OnChange
event subscription. It has a CurrentValue
property.
On the other hand, IOptionsSnapshot
is registered as scoped and also has a change detection capability by reading the last options for each request, but it doesn't have the OnChange
event. It has a Value
property.
Using both injected into a view for instance gives us the exact same behavior:
using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.Extensions.Options; using UsingOptionsSample.Models; using UsingOptionsSample.Services; namespace UsingOptionsSample.Pages { public class MyOptions { public MyOptions() { // Set default value. Option1 = "value1_from_ctor"; } public string Option1 { get; set; } public int Option2 { get; set; } = 5; } public class OptionsTestModel : PageModel { private readonly MyOptions _snapshotOptions; private readonly MyOptions _monitorOptions; public OptionsTestModel( IOptionsMonitor<MyOptions> monitorOptionsAcessor, IOptionsSnapshot<MyOptions> snapshotOptionsAccessor) { _snapshotOptions = snapshotOptionsAccessor.Value; _monitorOptions = monitorOptionsAcessor.CurrentValue; } public string SnapshotOptions { get; private set; } public string MonitorOptions { get; private set; } public void OnGetAsync() { //Snapshot options var snapshotOption1 = _snapshotOptions.Option1; var snapshotOption2 = _snapshotOptions.Option2; SnapshotOptions = $"snapshot option1 = {snapshotOption1}, " + $"snapshot option2 = {snapshotOption2}"; //Monitor options var monitorOption1 = _monitorOptions.Option1; var monitorOption2 = _monitorOptions.Option2; MonitorOptions = $"monitor option1 = {monitorOption1}, " + $"monitor option2 = {monitorOption2}"; } } }
So, what's the point of having these two interfaces/implementations if they look like the same thing, just with different lifetimes? The code is based on this sample, which surprisingly doesn't include an IOptionsMonitor
usage sample.
Why does one have a "Value" property and the other have a "CurrentValue" if both return the "current value" of an option?
Why/when should I use IOptionsSnapshot
instead of IOptionsMonitor
?
I don't think I got it straight, I must be missing some very important aspect regarding these and dependency injection.
IOptionsMonitor<T> is itself a Singleton, and it caches both the default and named options for the lifetime of the app.
The IConfiguration is an interface for . Net Core 2.0. The IConfiguration interface need to be injected as dependency in the Controller and then later used throughout the Controller. The IConfiguration interface is used to read Settings and Connection Strings from AppSettings. json file.
AddOptions(IServiceCollection) Adds services required for using options. AddOptions<TOptions>(IServiceCollection) Gets an options builder that forwards Configure calls for the same named TOptions to the underlying service collection. AddOptions<TOptions>(IServiceCollection, String)
AddScoped(IServiceCollection, Type, Type) Adds a scoped service of the type specified in serviceType with an implementation of the type specified in implementationType to the specified IServiceCollection.
IOptionsMonitor
is a singleton service that retrieves current option values at any time, which is especially useful in singleton dependencies.
IOptionsSnapshot
is a scoped service and provides a snapshot of the options at the time the IOptionsSnapshot<T>
object is constructed. Options snapshots are designed for use with transient and scoped dependencies.
Use
IOptions<T>
when you are not expecting your config values to change. UseIOptionsSnaphot<T>
when you are expecting your values to change but want it to be consistent for the entirety of a request. UseIOptionsMonitor<T>
when you need real time values.
The comments have some pretty good answers already. To try and summarize/repeat Tseng:
IOptionsSnapshot
is great for getting injected into an object that is scoped or transient. It will be consistent for the lifetime of that object and new values will come in as you get new objects.
However, if you need options that reload in a singleton, IOptionsMonitor
is what you should use, because your singleton will never change. A good example of such services are those inherited from IHostedService
, for long-running background services in ASP.NET Core.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With