<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/understanding-ioptions-ioptionsmonitor-and-ioptionssnapshot-in-net-7-9cgnp87kc" -->

---
title: Understanding IOptions, IOptionsMonitor, and...
description: A walkthrough of three .NET configuration patterns - IOptions, IOptionsSnapshot, and IOptionsMonitor - explaining their DI lifetimes, whether they support live...
canonical: https://daily.dev/posts/understanding-ioptions-ioptionsmonitor-and-ioptionssnapshot-in-net-7-9cgnp87kc
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Understanding IOptions, IOptionsMonitor, and IOptionsSnapshot in .NET 7 | daily.dev
og:description: A walkthrough of three .NET configuration patterns - IOptions, IOptionsSnapshot, and IOptionsMonitor - explaining their DI lifetimes, whether they support live...
og:url: https://daily.dev/posts/understanding-ioptions-ioptionsmonitor-and-ioptionssnapshot-in-net-7-9cgnp87kc
og:image: https://api.daily.dev/og/posts/9CGnP87kC.png
og:image:alt: Understanding IOptions, IOptionsMonitor, and IOptionsSnapshot in .NET 7
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Understanding IOptions, IOptionsMonitor, and IOptionsSnapshot in .NET 7

**[Code4IT](https://daily.dev/sources/code4it)** · 9 min read · 0 upvotes · 0 comments

## Summary

A walkthrough of three .NET configuration patterns - IOptions, IOptionsSnapshot, and IOptionsMonitor - explaining their DI lifetimes, whether they support live config reloads, and how to unit test each. IOptions is a simple Singleton read once at startup with no reload support; IOptionsSnapshot is Scoped and recomputed per request, enabling live reload at a performance cost; IOptionsMonitor is a Singleton that supports live reload plus an OnChange callback, but requires disposing the returned IDisposable to avoid leaks. Includes code samples, a comparison table, and demo scenarios for each type.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://www.code4it.dev/blog/ioptions-ioptionsmonitor-ioptionssnapshot>

## Questions this post answers

### What's the difference between IOptions and IOptionsSnapshot in .NET?

IOptions is registered as a Singleton and reads configuration values once at application startup, so it never reflects changes made to appsettings.json while running. IOptionsSnapshot is registered with a Scoped lifetime and recomputes its value on every HTTP request, allowing configuration changes to be picked up live, at the cost of a slight performance overhead compared to IOptions.

_daily.dev surfaces practical comparisons like this for developers deciding how to structure .NET configuration._

### How do I unit test a class that depends on IOptions in .NET?

Use the static method Options.Create<T>, passing it an instance of the configuration POCO, then inject the returned IOptions<T> into the constructor of the class under test. This works because IOptions is a simple wrapper, unlike IOptionsSnapshot or IOptionsMonitor, which have no direct equivalent and require stubs or mocking libraries such as Moq or NSubstitute instead.

_developers wiring up .NET DI tests can find this kind of concrete pattern through daily.dev._

### Does IOptionsMonitor in .NET support a callback when configuration changes?

Yes, IOptionsMonitor exposes an OnChange(Action<TOptions, string?> listener) method that fires every time the configuration file is updated, and its current value is accessed via CurrentValue rather than Value. It is registered as a Singleton, but the object returned by OnChange implements IDisposable and must be disposed, otherwise the class holding it never gets disposed properly.

_daily.dev helps .NET developers track these kinds of configuration reload gotchas before they hit production._

## Similar posts on daily.dev

- [12 Rules for Dependency Injection in ASP.NET Core](https://daily.dev/posts/12-rules-for-dependency-injection-in-asp-net-core-nirfrs5ef) · We Are .NET · 3 upvotes · 1 comments
- [Configuring contextual options with Microsoft.Extensions.Options.Contextual](https://daily.dev/posts/configuring-contextual-options-with-microsoft-extensions-options-contextual-sbaz63pbd) · We Are .NET · 3 upvotes · 0 comments

---

Tags: [#testing](https://daily.dev/tags/testing), [#.net](https://daily.dev/tags/.net), [#c#](https://daily.dev/tags/c#), [#dependency-injection](https://daily.dev/tags/dependency-injection)

[View this post on daily.dev](https://daily.dev/posts/understanding-ioptions-ioptionsmonitor-and-ioptionssnapshot-in-net-7-9cgnp87kc)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Understanding IOptions, IOptionsMonitor, and IOptionsSnapshot in .NET 7","url":"https://daily.dev/posts/understanding-ioptions-ioptionsmonitor-and-ioptionssnapshot-in-net-7-9cgnp87kc","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/understanding-ioptions-ioptionsmonitor-and-ioptionssnapshot-in-net-7-9cgnp87kc"},"datePublished":"2026-10-04T13:06:41.741Z","dateModified":"2026-10-04T13:15:11.647Z","description":"A walkthrough of three .NET configuration patterns - IOptions, IOptionsSnapshot, and IOptionsMonitor - explaining their DI lifetimes, whether they support live...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/1f3fb78fbeffe0448b237224c905ad84?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/1f3fb78fbeffe0448b237224c905ad84?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Code4IT","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Code4IT","logo":"https://media.daily.dev/image/upload/s--OaaG4G10--/f_auto,q_auto/v1791119049/logos/code4it?_a=BAMAMicg0","url":"https://daily.dev/sources/code4it"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/understanding-ioptions-ioptionsmonitor-and-ioptionssnapshot-in-net-7-9cgnp87kc","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"testing,.net,c#,dependency-injection","timeRequired":"PT9M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Code4IT","item":"https://daily.dev/sources/code4it"},{"@type":"ListItem","position":3,"name":"Understanding IOptions, IOptionsMonitor, and IOptionsSnapshot in .NET 7"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/understanding-ioptions-ioptionsmonitor-and-ioptionssnapshot-in-net-7-9cgnp87kc#faq","mainEntity":[{"@type":"Question","name":"What's the difference between IOptions and IOptionsSnapshot in .NET?","acceptedAnswer":{"@type":"Answer","text":"IOptions is registered as a Singleton and reads configuration values once at application startup, so it never reflects changes made to appsettings.json while running. IOptionsSnapshot is registered with a Scoped lifetime and recomputes its value on every HTTP request, allowing configuration changes to be picked up live, at the cost of a slight performance overhead compared to IOptions. daily.dev surfaces practical comparisons like this for developers deciding how to structure .NET configuration."}},{"@type":"Question","name":"How do I unit test a class that depends on IOptions in .NET?","acceptedAnswer":{"@type":"Answer","text":"Use the static method Options.Create<T>, passing it an instance of the configuration POCO, then inject the returned IOptions<T> into the constructor of the class under test. This works because IOptions is a simple wrapper, unlike IOptionsSnapshot or IOptionsMonitor, which have no direct equivalent and require stubs or mocking libraries such as Moq or NSubstitute instead. developers wiring up .NET DI tests can find this kind of concrete pattern through daily.dev."}},{"@type":"Question","name":"Does IOptionsMonitor in .NET support a callback when configuration changes?","acceptedAnswer":{"@type":"Answer","text":"Yes, IOptionsMonitor exposes an OnChange(Action<TOptions, string?> listener) method that fires every time the configuration file is updated, and its current value is accessed via CurrentValue rather than Value. It is registered as a Singleton, but the object returned by OnChange implements IDisposable and must be disposed, otherwise the class holding it never gets disposed properly. daily.dev helps .NET developers track these kinds of configuration reload gotchas before they hit production."}}]}
```

