June 10 2024
Sponsored
• Discover the principles and best practices of API design with Postman's comprehensive guide. Learn how to create adaptable, testable, and well-documented APIs that support your business objectives. Dive into the full process and enhance your API design capabilities at Postman API Design.
Many thanks to the sponsors who make it possible for this newsletter to be free for readers. Become a sponsor.
The IOptions pattern is part of the Microsoft.Extensions.Options namespace and provides a way to define a configuration class and bind settings from various sources such as appsettings.json files, environment variables, or command-line arguments.
We already know how to use it. In the appsettings.json file, I added a new value which I need in my application - NewsletterSettings -> URL:
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "AllowedHosts": "*", "NewsletterSettings": { "URL": "testUrl" }}
Also, I created a configuration class to represent my settings. This class will contain properties for each setting you want to configure:
public class NewsletterSettings{ public string Url { get; set; }}
And lastly, I created a binding between those two, in the Program.cs class:
builder.Services.Configure<NewsletterSettings>( builder.Configuration.GetSection(nameof(NewsletterSettings)));
I created a simple controller to show the using of the NewsletterSettings within IOptions pattern:
[ApiController][Route("[controller]")]public class NewsletterController : ControllerBase{ private readonly IOptions<NewsletterSettings> _newsletterSettings; public NewsletterController(IOptions<NewsletterSettings> newsletterSettings) { _newsletterSettings = newsletterSettings; } [HttpGet(Name = "GetNewsletter")] public string Get() { return _newsletterSettings.Value.Url; }}
Perfect, but...
What if you want to change the value in the appsettings.json while the application running?
You can do that, but the old value will be still active in the application.
Why is this the case?
Because the IOptions interface is registered as a Singleton service at the start of the application. This means that it going to read the configuration section just once at startup and reuse it throughout the lifetime of the application.
If you want to see a new value, you need to restart an application.
How to achieve that you can change the values in the lifetime of the application?
While IOptions provides a read-only snapshot of the configuration settings during application startup, and IOptionsSnapshot reloads the settings on each access to pick up changes, IOptionsMonitor goes one step further by allowing you to register callbacks that are triggered whenever the configuration settings change. You just need to add it through dependency injection:
[ApiController][Route("[controller]")]public class NewsletterController : ControllerBase{ private readonly IOptionsMonitor<NewsletterSettings> _newsletterMonitor; public NewsletterController(IOptionsMonitor<NewsletterSettings> newsletterMonitor) { _newsletterMonitor = newsletterMonitor; } [HttpGet(Name = "GetNewsletter")] public string Get() { string ioptionsMonitor = _newsletterMonitor.CurrentValue.Url; return ioptionsMonitor; }}
But, as I said, it is possible to register a callback to react to changes in the configuration:
public NewsletterController(IOptionsMonitor<NewsletterSettings> newsletterMonitor){ _newsletterMonitor = newsletterMonitor; _newsletterMonitor.OnChange(settings => { Console.WriteLine($"Settings changed: {settings.Url}"); });}
IOptionsSnapshot provides dynamic access to configuration settings that can change during the application's execution, while IOptionsMonitor extends this by allowing you to register callbacks that get triggered whenever the configuration settings change, enabling real-time reactions to configuration updates.
Use IOptionsSnapshot when your configuration settings may change during the application's execution and you want those changes to take effect without restarting the application. It provides dynamic access to the configuration settings.
Use IOptionsMonitor when you not only need dynamic access to configuration settings but also want to be notified whenever the configuration changes, so you can react to those changes in real-time.
Check the source code here.
That's all from me today.
Stop arguing about code style. In this course you get a production-proven setup with analyzers, CI quality gates, and architecture tests — the exact system I use in real projects. Join here.
Not sure yet? Grab the free Starter Kit — a drop-in setup with the essentials from Module 01.
Design Patterns that Deliver — Solve real problems with 5 battle-tested patterns (Builder, Decorator, Strategy, Adapter, Mediator) using practical, real-world examples. Trusted by 650+ developers.
Just getting started? Design Patterns Simplified covers 10 essential patterns in a beginner-friendly, 30-page guide for just $9.95.
Every Monday morning, I share 1 actionable tip on C#, .NET & Architecture that you can use right away. Join here.
Join 20,000+ subscribers who mass-improve their .NET skills with actionable tips on C#, Architecture & Best Practices.
Subscribe to the TheCodeMan.net and be among the 20,000+ subscribers gaining practical tips and resources to enhance your .NET expertise.