ExistForAll.SimpleSettings
2.0.0
dotnet add package ExistForAll.SimpleSettings --version 2.0.0
NuGet\Install-Package ExistForAll.SimpleSettings -Version 2.0.0
<PackageReference Include="ExistForAll.SimpleSettings" Version="2.0.0" />
<PackageVersion Include="ExistForAll.SimpleSettings" Version="2.0.0" />
<PackageReference Include="ExistForAll.SimpleSettings" />
paket add ExistForAll.SimpleSettings --version 2.0.0
#r "nuget: ExistForAll.SimpleSettings, 2.0.0"
#:package ExistForAll.SimpleSettings@2.0.0
#addin nuget:?package=ExistForAll.SimpleSettings&version=2.0.0
#tool nuget:?package=ExistForAll.SimpleSettings&version=2.0.0
<img src="https://raw.githubusercontent.com/existall/SimpleSettings/master/icon.png" alt="ExistForAll.SimpleSettings">
ExistForAll.SimpleSettings
Strongly-typed application settings for .NET. Declare a plain public interface, decorate it with defaults, and SimpleSettings binds your configuration into a runtime implementation you can inject anywhere — no concrete option classes, no per-type services.Configure<> wiring.
Installation
dotnet add package ExistForAll.SimpleSettings
dotnet add package ExistForAll.SimpleSettings.Binders
dotnet add package ExistForAll.SimpleSettings.Extensions.GenericHost
ExistForAll.SimpleSettings— the core binding engine and the directSettingsBuilderAPI.ExistForAll.SimpleSettings.Binders— additional binders (in-memory, command-line, and more).ExistForAll.SimpleSettings.Extensions.GenericHost— dependency-injection integration (AddSimpleSettings).
Table of Content
- Getting started
- Building the collection
- Building config interfaces
- Default Values
- Build section binders
- Extending SimpleSettings
- Security & Behavior
Why SimpleSettings
.NET ships IOptions<>, but it couples your application to a framework abstraction, forces every settings shape to be a concrete class rather than an interface, and requires a manual services.Configure<> call per type. SimpleSettings keeps the positioning of IOptions<> — configuration bound into typed objects — while letting you depend on a plain interface, discovered and bound automatically, and portable across DI containers. You inject the interface; SimpleSettings supplies the implementation.
Quickstart
Declare a settings interface and bind it with the direct API:
[SettingsSection]
public interface IEmailSenderSettings
{
[SettingsProperty(DefaultValue = "https://smtp.example.com")]
string ServiceUrl { get; set; }
[SettingsProperty(DefaultValue = 3)]
int Retries { get; set; }
}
var settings = SettingsBuilder.CreateBuilder()
.GetSettings<IEmailSenderSettings>();
Every settings interface must be public — SimpleSettings emits a runtime implementation of the interface and cannot implement a non-public one.
Feature overview
- Bind configuration into
publicsettings interfaces — no concrete option classes. - Discover settings via
[SettingsSection], theISettingsSectionmarker base, or aSettingsname suffix. - Per-property defaults, key overrides, custom converters, and required-value enforcement via
[SettingsProperty(...)]. - Object-level and per-property validation through
ISettingValidation<T>. - First-class dependency-injection integration for the .NET Generic Host.
- Value-free exceptions on bind and conversion failures — bound values never surface in error messages (see Security & Behavior).
Dependency injection
Register SimpleSettings with the Generic Host and let it discover every settings interface in the supplied assemblies:
services.AddSimpleSettings(o =>
{
o.AddAssemblies(new[] { typeof(IEmailSenderSettings).Assembly });
});
// after building the provider — opt-in, deferred DI validation:
serviceProvider.ValidateSimpleSettings();
ValidateSimpleSettings() extends IServiceProvider and must be called after BuildServiceProvider(); attribute and ValidatorType validators run inline during binding and need no such call. See Security & Behavior for the full validation model.
Security notes
Every exception SimpleSettings throws on a bind or conversion failure is value-free: it carries only type and property metadata and never chains an inner exception that saw the bound value, so a secret you bound cannot surface in the error's ToString() chain. This is a structural guarantee, not a convention.
There are two carve-outs the guard does not reach, and you own them: author-supplied ValidationError message text (it is emitted verbatim), and DI-resolved validator constructors (they run outside the value-free bind guard). Never echo a bound value into a validation message and never log a secret in a validator constructor. See Security & Behavior for the full treatment.
Breaking changes / migration (v1 → v2)
The v1 → v2 release batched four breaking changes:
SettingsHolder/ISettingsHolderare now internal — use the publicSettingsBuilder/ISettingsCollection/ISettingsProvidersurface instead.- The
Core.AspNetpackage was dropped — it exposed no public type; remove any reference to it. - The
Microsoft.Extensions.*dependency floor is now per-TFM —8.0.xonnet8.0, current onnet10.0. - A public
abstract SimpleSettingsExceptionbase was introduced and boundary exceptions were made public and structured; the old bare-Exceptionthrow for a non-interface settings type is nowSettingsTypeNotInterfaceException.
See the full migration guide in docs/Security.md.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. 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 is compatible. 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. |
-
net10.0
- No dependencies.
-
net8.0
- No dependencies.
NuGet packages (4)
Showing the top 4 NuGet packages that depend on ExistForAll.SimpleSettings:
| Package | Downloads |
|---|---|
|
ExistForAll.SimpleSettings.Extensions.GenericHost
SimpleSettings allow applications to use configurations values from any data store in the type of interfaces, thus decouples the frameworks from your application and allowing application to inject interfaces and nothing else. This framework should be used instead of .Net Core IOptions<T>. |
|
|
ExistForAll.SimpleSettings.Binders
SimpleSettings allow applications to use configurations values from any data store in the type of interfaces, thus decouples the frameworks from your application and allowing application to inject interfaces and nothing else. This framework should be used instead of .Net Core IOptions<T>. |
|
|
ExistForAll.SimpleSettings.Core.AspNet
SimpleSettings allow applications to use configurations values from any data store in the type of interfaces, thus decouples the frameworks from your appliaction and allowing application to inject interfaces and nothing else. This framework should be used instead of .Net Core IOptions<T>. |
|
|
ExistForAll.SimpleSettings.DotNet.Frameworks
SimpleSettings allow applications to use configurations values from any data store in the type of interfaces, thus decouples the frameworks from your appliaction and allowing application to inject interfaces and nothing else. This framework should be used instead of .Net Core IOptions<T>. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2.0.0 | 149 | 7/20/2026 |
| 2.0.0-alpha.0.140 | 67 | 7/20/2026 |
| 2.0.0-alpha.0.139 | 66 | 7/19/2026 |
| 2.0.0-alpha.0.138 | 68 | 7/15/2026 |
| 2.0.0-alpha.0.137 | 70 | 7/15/2026 |
| 2.0.0-alpha.0.136 | 61 | 7/14/2026 |
| 2.0.0-alpha.0.135 | 66 | 7/14/2026 |
| 2.0.0-alpha.0.134 | 74 | 7/14/2026 |
| 2.0.0-alpha.0.133 | 64 | 7/14/2026 |
| 2.0.0-alpha.0.132 | 84 | 7/14/2026 |
| 2.0.0-alpha.0.131 | 77 | 7/14/2026 |
| 2.0.0-alpha.0.130 | 74 | 7/13/2026 |
| 2.0.0-alpha.0.129 | 69 | 7/13/2026 |
| 2.0.0-alpha.0.128 | 68 | 7/13/2026 |
| 2.0.0-alpha.0.127 | 71 | 7/13/2026 |
| 2.0.0-alpha.0.126 | 68 | 7/13/2026 |
| 2.0.0-alpha.0.125 | 68 | 7/12/2026 |
| 2.0.0-alpha.0.124 | 66 | 7/12/2026 |
| 2.0.0-alpha.0.123 | 68 | 7/12/2026 |
| 2.0.0-alpha.0.122 | 69 | 7/12/2026 |