TomRR.SettingsBinder
0.1.0
dotnet add package TomRR.SettingsBinder --version 0.1.0
NuGet\Install-Package TomRR.SettingsBinder -Version 0.1.0
<PackageReference Include="TomRR.SettingsBinder" Version="0.1.0" />
<PackageVersion Include="TomRR.SettingsBinder" Version="0.1.0" />
<PackageReference Include="TomRR.SettingsBinder" />
paket add TomRR.SettingsBinder --version 0.1.0
#r "nuget: TomRR.SettingsBinder, 0.1.0"
#:package TomRR.SettingsBinder@0.1.0
#addin nuget:?package=TomRR.SettingsBinder&version=0.1.0
#tool nuget:?package=TomRR.SettingsBinder&version=0.1.0
⚙️ SettingsBinder
A lightweight, zero-boilerplate Roslyn Source Generator that binds [Settings]-annotated classes and structs directly to the .NET Options pattern.
Quick Links
- Sample API guide:
SettingsBinder.SampleApi/README.md - Run the sample:
dotnet run --project SettingsBinder.SampleApi/SettingsBinder.SampleApi.csproj
Table of Contents
- Features
- Installation
- Quick Start
- Consuming Settings via IOptions<T>
- Advanced Configuration Pipeline
- Customize Section Names
- Struct Settings
- DataAnnotation Validation
- Non-Web Scenarios
- What Gets Generated?
- Performance
- SettingsBinder.SampleApi
- Package Info
- License
- Changelog
✨ Features
- ✅ Automatic binding of settings from
appsettings.json - ✅ Strongly-typed settings via
[Settings]attribute - ✅ Supports classes and structs
- ✅ Supports
IOptions<T>, validation, and DI - ✅ Source-generated
SectionNameand registration logic - ✅ Modular and customizable configuration pipelines
- ✅ Zero reflection, minimal runtime overhead
- ✅ XML Documentation
� Installation
dotnet add package TomRR.SettingsBinder
Or in your project file:
<PackageReference Include="TomRR.SettingsBinder" Version="X.X.X" />
🚀 Quick Start
1. Define a Settings Class
using TomRR.SettingsBinder;
[Settings]
public sealed partial class LoggingSettings
{
public string? Level { get; init; }
public string? Format { get; init; }
}
2. Add a Matching Section to appsettings.json
{
"LoggingSettings": {
"Level": "Information",
"Format": "Json"
}
}
3. Wire Up in Program.cs
var builder = WebApplication.CreateBuilder(args);
// Optional: add default config sources (base path, JSON, user secrets, env vars)
builder.Configuration.AddDefaultConfigurationSources<Program>();
// Registers all [Settings] classes automatically
builder.AddSettingsOptions();
var app = builder.Build();
✅ You're done!
💉 Consuming Settings via IOptions<T>
After calling AddSettingsOptions(), inject settings into your services or endpoints:
app.MapGet("/logging", (IOptions<LoggingSettings> options) => options.Value);
Or in a class via constructor injection:
public class MyService(IOptions<LoggingSettings> options)
{
private readonly LoggingSettings _settings = options.Value;
}
🧩 Advanced Configuration Pipeline
If you prefer fine-grained control over configuration sources:
using TomRR.SettingsBinder.Advanced;
builder.Configuration
.WithBasePath()
.WithJsonFile()
.WithEnvironmentJsonFile()
.WithSecrets<Program>()
.WithEnvironmentVariables();
You can mix & match based on your project needs.
🎛️ Customize Section Names
Override the section name using the attribute constructor:
[Settings("MyCustomSection")]
public sealed partial class AdvancedSettings
{
public string? Mode { get; init; }
public bool Enabled { get; init; }
}
This generates SectionName => "MyCustomSection" and binds to:
{
"MyCustomSection": {
"Mode": "Debug",
"Enabled": true
}
}
Use this when the config section does not match the class name.
🧱 Struct Settings
You can also annotate structs with [Settings]:
[Settings]
public partial struct CacheSettings
{
public bool Enabled { get; set; }
public int DurationSeconds { get; set; }
}
This generates ISettings and SectionName just like for classes.
Note:
IOptions<T>requiresT : class, so structs are excluded from automatic DI registration viaAddSettingsOptions(). Bind them manually:var cache = builder.Configuration .GetSection(CacheSettings.SectionName) .Get<CacheSettings>();
✅ DataAnnotation Validation
Settings classes support System.ComponentModel.DataAnnotations. The generated binding calls ValidateDataAnnotations() and ValidateOnStart(), so invalid configuration fails at startup:
using System.ComponentModel.DataAnnotations;
[Settings]
public sealed partial class DatabaseSettings
{
[Required]
public string ConnectionString { get; set; } = string.Empty;
[Range(1, 65535)]
public int Port { get; set; } = 5432;
}
If ConnectionString is missing from appsettings.json, the application will throw an OptionsValidationException at startup.
🖥️ Non-Web Scenarios (Console / Worker Service)
For console apps or worker services that don't have a WebApplicationBuilder, use the IServiceCollection overload:
var config = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.Build();
var services = new ServiceCollection();
services.AddSettingsOptions(config);
✅ What Gets Generated?
Interface
public interface ISettings
{
static abstract string SectionName { get; }
}
Partial Implementation with SectionName
// For classes:
public sealed partial class LoggingSettings : ISettings
{
public static string SectionName => "LoggingSettings";
}
// For structs:
public partial struct CacheSettings : ISettings
{
public static string SectionName => "CacheSettings";
}
Default Configuration Sourcing
public static IConfigurationBuilder AddDefaultConfigurationSources<T>(
this IConfigurationBuilder builder) where T : class
=> builder
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile("appsettings.Development.json", optional: true, reloadOnChange: true)
.AddUserSecrets<T>()
.AddEnvironmentVariables();
Automatic Binding with Validation
builder.Services
.AddOptions<LoggingSettings>()
.Bind(builder.Configuration.GetSection(LoggingSettings.SectionName))
.ValidateDataAnnotations()
.ValidateOnStart();
� Performance
- ✅ Zero reflection at runtime (everything is compile-time generated).
- ✅ No ActivatorUtilities, no extra runtime DI overhead.
- ✅ Source generation ensures optimal performance with minimal allocations.
SettingsBinder.SampleApi
This repository includes SettingsBinder.SampleApi, a runnable reference API.
It is designed to:
- exercise all main API features (classes, structs, custom sections, validation, DI)
- expose bound settings via endpoints so you can verify binding works
- provide a runnable walkthrough for users exploring the library
Run it with:
dotnet run --project SettingsBinder.SampleApi/SettingsBinder.SampleApi.csproj
For a detailed coverage map, see SettingsBinder.SampleApi/README.md.
📦 Package Info
| Name | Description |
|---|---|
| Package ID | TomRR.SettingsBinder |
| License | Apache 2.0 |
| Author | Tom-Robert Resing |
| Repo | GitHub |
| NuGet | NuGet |
📄 License
Licensed under the Apache License 2.0.
📋 Changelog
See CHANGELOG.md for release history.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Microsoft.CodeAnalysis.CSharp (>= 4.3.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.1.0 | 94 | 4/12/2026 |
See release notes at https://github.com/TomRR/SettingsBinder.Nuget/blob/main/CHANGELOG.md