Aspnetcore.docs: What's the differences between IOptionsMonitor and IOptionsSnapshot? When to use one over another?

Created on 23 Apr 2019  ·  14Comments  ·  Source: dotnet/AspNetCore.Docs

Both can reload configuration, both can get named options. The only differences I can see is that the IOptionsMonitor is singleton while IOptionsSnapshot is scoped.
Any other differences? And when should I use one over another?


Document Details

Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

P1 Source - Docs.ms doc-enhancement

Most helpful comment

yeah poke's answer is quite good

All 14 comments

Hello @stg609 ... Yes, that's my understanding. One difference that you didn't list: IOptionsMonitor allows you to register a callback for when options change.

I'll mark your question for engineering to take a look at on the next engineering doc sweep.

I'm curious to know if the phrase "with minimal processing overhead" means that IOptionsSnapshot is faster. I didn't think to ask when we last worked on the topic, but we'll find out on the next doc sweep if that's the case.

@stg609 , sorry,it is not clear, did you close the issue because the documentation has been enhanced( is any PR reference?) or because the answer exists somewhere outside of MS Docs site?

The doc hasn't been changed.

@HaoK, do you agree/disagree with the remarks in @poke's SO answer at https://stackoverflow.com/questions/46569270/asp-net-core-configuration-reloadonchange-with-ioptionssnapshot-still-not-respon/46570073#46570073?

I'll take a look at this for doc improvements after I hear back. Leave this issue open, as it will auto-close when a PR merges or it's decided not to make changes.

yeah poke's answer is quite good

Then there is also the IOptions interface. How does it fit into all of this?

The documentation states:

You may continue to use IOptions in existing frameworks and libraries that already use the IOptions interface and don't require the scenarios provided by IOptionsMonitor.

Does this mean that IOptions is to be considered deprecated, and that IOptionsMonitor and IOptionsSnapshot is preferred?

The documentation also states:

IOptionsMonitor is a singleton service that retrieves current option values at any time, which is especially useful in singleton dependencies.

Then it goes on to show an example of IOptionsMonitor used in a "PageModel" and how to inject it into a view, neither which are singletons.

Which interface is the recommended one to use for a controller?

@vanillajonathan No, IOptions<T> is kind of the _default_ to use unless you have special requirements. I usually have the following thinking process in this order:

  • Use IOptions<T> by default
  • Use IOptionsSnapshot<T> if you need the configuration to update
  • Use IOptionsMonitor<T> if you need to consume _named_ options, or if you are consuming options from a singleton _and_ need to refresh the configuration or even need to be notified of updates

So usually, you will be totally fine with IOptions<T> or IOptionsSnapshot<T>. The situations in which you need a monitor are actually somewhat rare. But it’s a very powerful tool if you need it.

@guardrex I would agree that the docs are currently focusing a bit too much on prioritizing the monitor over the other interfaces, even in all those code examples. Is that an intended change, if so, what’s the reason for that? I would prefer if we could focus a bit more on the simpler interfaces and communicated the monitor for power users instead of making it the default approach.

Hello ...

@vanillajonathan ... btw -- best to just open a new issue using the This Page feedback button+form at the bottom of the topic when something is closed here (issue or PR) ... and cross-link the issue/PR in the new issue. No worries tho as I'm about to explain ... I think we'll leave this for the time being.

... and in regard to your, @poke, question on focus here ... what you see in the topic is exactly what engineering asked for.

_... and it came right from the TOP ... King Damian of Coredom!_ :smile:

https://github.com/aspnet/AspNetCore.Docs/issues/9662#issue-383243895

... it's like the Swiss Army Knife of Options.

Let's do this ... _NOTHING!_ :smile: lol ... partially because Damian and Hao instructed this coverage approach but also because we're totally swamped with issues. 🏃😅 If anyone wants to open an issue, describe changes that they would like to make, we can ping for review of the suggestions. If approved, then they can put in a PR to improve the topic. It would be welcome on that happy path, but we're 😵 crazy busy 😵 right now, and the 🎁 holidays are here ⛄️, so everyone is taking off for several weeks (including ME! Woot!). It might be best to open such an issue for discussion in 2020.

On the specific points @vanillajonathan ...

IOptions is to be considered deprecated

Not unless they say so, and they haven't made that indication. It's cool if you want to use it. Even if they did decide to 💀 it, I'm sure you'll get plenty of warning (i.e., an Announcement well in advance). Also, 3.1 is an LTS release, so it's going to be there for a long, long time.

Which interface is the recommended one to use for a controller?

Don't base your decision on the registration, per se. Go by your scenario ... what do you need? Generally, they like the focus on IOptionsMonitor and IOptonsSnapshot, and the topic is leading devs right there with the text and examples (e.g., the sample app, where those are the two in use ... see the code file for the Index page). I can't speak to perf or resource demands tho ... that's an interesting question, and it's probably one of those you-just-have-to-test-in-your-scenario things if you had _a lot_ of Options all over the place.

@guardrex

what you see in the topic is exactly what engineering asked for.
... and it came right from the TOP ... King Damian of Coredom! 😄

Okay, thanks for that link. I wasn’t aware of that issue. The reasoning _“since its effectively everything IOptions is but more”_ is really bad though since that’s effectively what the I in SOLID would advise against. But I’ll follow up on that elsewhere. Thanks for pointing it out though!

but we're 😵 crazy busy 😵 right now

(like always 😁)

everyone is taking off for several weeks (including ME! Woot!)

Yay! Go you! 😊 Happy holidays! 🎄

My 2c, I believe the intent/idea is to simplify things by just guiding developers to one single interface, which is the IOptionsMonitor since its a superset of IOptions. Even if they don't need to use any of the more advanced features, it makes things appear more simple over all as they don't need to ask questions like which one do I need to use (IOptions/IOptionsSnapshot/IOptionsMonitor). In an ideal world we would have removed IOptions in 2.0 but too many things were relying on it so it wasn't really an option (pun intended).

I put this up for reevaluation over here: aspnet/Extensions#2777. So follow along if you are interested and voice your opinion if you have one :)

@guardrex

Which interface is the recommended one to use for a controller?

Don't base your decision on the registration, per se. Go by your scenario ... what do you need? Generally, they like the focus on IOptionsMonitor and IOptonsSnapshot, and the topic is leading devs right there with the text and examples (e.g., the sample app, where those are the two in use ... see the code file for the Index page). I can't speak to perf or resource demands tho ... that's an interesting question, and it's probably one of those you-just-have-to-test-in-your-scenario things if you had _a lot_ of Options all over the place.

But a controller just lives for the lifetime of the client request (connection), hence I don't think a controller would ever subscribe to events and hence not use IOptionsMonitor. To me it seems that IOptions is the most suitable for web applications and classes that have a service lifetime that is declared as Transient or Scoped, i.e. controllers and its services, where as IOptionsMonitorand IOptionsSnapshot would be more useful for other type of applications that are not web applications or are registered with the service lifetime Singleton.

So an example of where you might want to use IOptionsSnapshot in the controller is if the options do change every so often, and you wanted the controller to use the current options every request, IOptions never changes until you restart your app, since its computed once and will never change since its lifetime is static.

I noticed IOptionsSnapshot (which is implemented by OptionsManager and registered as scoped) uses it's own private cache for options instances, compared to IOptionsMonitor which uses the singleton IOptionsMonitorCache. This can lead to inconsistencies if not careful when consuming both in different places during a request. For example, invaldating an option value in IOptionsMonitorCache will still leave the stale options value in OptionsManager which will be returned by IOptionsSnapshot.

Was this page helpful?
0 / 5 - 0 ratings