One edit to the settings file,

three different answers.

appsettings.json "Greeting": "before" → "after"
IOptionsMonitor<T>
SINGLETON
arrives as the reload lands, with no callback registered
CurrentValue.Greeting
"after"
IOptionsSnapshot<T>
SCOPED
arrives at the start of the next scope, which in a web app is the next request
Value.Greeting, in a new scope
"after"
IOptions<T>
SINGLETON
bound on the first read of Value, and cached for the life of the process
Value.Greeting
"before"
was never going to move
the expensive mistake a singleton that asks for the scoped one fails at Build() in Development, where scope validation is on, and starts normally everywhere else — holding a value that will not change until the process restarts
.NET SDK 10.0.201 · runtime 10.0.5 · every value asserted by the demo's tests
gdhami.net