
March 24, 2025 09:00 by
Peter
In modern .NET applications, effective configuration management is essential for ensuring flexibility and a clear separation of concerns. The IOptions<T> pattern is the preferred approach for injecting configuration settings into services. With .NET 9.0, records provide a concise and immutable way to represent configuration models. In this blog, we’ll explore how to utilize the IOptions<T> pattern efficiently with records.
Why Choose Records for Configuration?
Using records in C# for configuration settings offers several advantages:
- Immutability: Prevents unintentional modifications to configuration values.
- Value-based equality: Instances with identical values are treated as equal.
- Concise syntax: Reduces boilerplate code compared to traditional classes.
Configuring Settings in .NET 9.0
Step 1. Create the Configuration Record
Rather than using a class, define a record to represent your configuration settings.
public record AppSettings
{
public const string SectionName = "AppSettings";
public required string ApplicationName { get; init; }
public required int MaxRequests { get; init; }
public required LoggingSettings Logging { get; init; }
}
public record LoggingSettings
{
public required string LogLevel { get; init; }
}
}
Step 2. Configure Settings in appsettings.json
Specify your configuration values within the appsettings.json file:
{
"AllowedHosts": "*",
"AppSettings": {
"ApplicationName": "MyCoolApp",
"MaxRequests": 100,
"Logging": {
"LogLevel": "Information"
}
}
}
Step 3. Register Configuration in Program.cs
Use the Configure method to bind the configuration to the record.
builder.Services.Configure<AppSettings>(builder.Configuration.GetSection(AppSettings.SectionName));
Step 4. Inject Configuration with IOptions<T>
Inject IOptions<AppSettings> into services, controllers, or components.
public class RecordService
{
private readonly AppSettings _settings;
public RecordService(
IOptions<AppSettings> settings)
{
_settings = settings.Value;
}
public AppSettings GetAppSettingsAsync()
{
return _settings;
}
}
Step 5. Configure Service Registration
Register the service in Program.cs:
builder.Services.AddSingleton<RecordService>();
Step 6. Utilize the Service
Resolve the service and call its methods.
[Route("api/[controller]")]
[ApiController]
public class RecordsController : ControllerBase
{
private readonly RecordService _recordService;
public RecordsController(RecordService recordService)
{
_recordService = recordService;
}
[HttpGet]
[Route("settings")]
public IActionResult GetAppSettings()
{
return Ok(_recordService.GetAppSettingsAsync());
}
}
Execute the Code
Execute the code and see the result for yourself.

- Alternative: Using IOptionsSnapshot<T> and IOptionsMonitor<T>
- IOptionsSnapshot<T>: Provides a scoped instance of options, making it useful for refreshing values between requests in a web application.
- IOptionsMonitor<T>: Enables real-time configuration updates without requiring an application restart.
Conclusion
Leveraging records with the IOptions pattern in .NET 8.0 results in cleaner, immutable, and more efficient configuration management. Whether you use IOptions<T>, IOptionsSnapshot<T>, or IOptionsMonitor<T>, this approach fosters a well-organized and maintainable application.
Do you incorporate records for configuration in your .NET applications? Feel free to share your thoughts in the comments!