Enigma.Configuration
1.0.0
dotnet add package Enigma.Configuration --version 1.0.0
NuGet\Install-Package Enigma.Configuration -Version 1.0.0
<PackageReference Include="Enigma.Configuration" Version="1.0.0" />
<PackageVersion Include="Enigma.Configuration" Version="1.0.0" />
<PackageReference Include="Enigma.Configuration" />
paket add Enigma.Configuration --version 1.0.0
#r "nuget: Enigma.Configuration, 1.0.0"
#:package Enigma.Configuration@1.0.0
#addin nuget:?package=Enigma.Configuration&version=1.0.0
#tool nuget:?package=Enigma.Configuration&version=1.0.0
Enigma.Configuration
Enigma.Configuration is typed, read/write JSON configuration for .NET — the writable alternative
to Microsoft.Extensions.Configuration. The whole library follows one idiom: one JSON file ⇄ one
settings class ⇄ one IConfig<T>. You write a plain settings class, bind it to a file, inject
IConfig<T>, read through Value, mutate that same object, and persist it back to the very file it
came from with WriteAsync. Grouping is expressed with nested C# properties, so there are no
"Section:Key" strings anywhere. The library ships its own configuration model: it never touches
IConfiguration, and the only Microsoft.Extensions.* package it depends on is
Microsoft.Extensions.DependencyInjection.Abstractions.
What's new in 1.0 — the first release: typed binding, atomic writes, aggregated validation and DI registration with an optional start-up warm-up. See RELEASENOTES.md.
Features
- Typed binding & registration — bind a JSON file to a settings class with
AddEnigmaConfiguration(builder => builder.AddJsonFile<T>(path)), or without any container at all throughEnigmaConfig.FromFile<T>(path).optionaldecides what a missing or empty file means,strictturns an unmapped JSON key into an error, andConfigPathsbuilds per-user writable paths under the application-data folders. Registration opens no file — the path is recorded, not read. - Reading — the file is read lazily on the first access to
Valueand never again until you ask. Property matching is case-insensitive, comments and trailing commas are accepted, a UTF-8 BOM is skipped, and enums bind from their name or their number. - Writing —
WriteAsyncreplaces the file's content from the settings object, which is the source of truth. The write is atomic: content is staged in a temporary file next to the destination and only then put in its place, so a failed or cancelled write never leaves a corrupt file. Output is indented UTF-8 without a BOM, PascalCase as the class declares it, enums by name, and non-ASCII text unescaped so the file stays hand-editable. - Validation —
System.ComponentModel.DataAnnotationsattributes are always evaluated, and the walk is recursive: nested objects, list elements and dictionary entries each report the path they failed at (Smtp.Credentials.User,Servers[1].Url,Endpoints[primary].Retries). A fluentConfigValidator<T>adds the rest —NotNull,NotEmpty,InRange,MinLength/MaxLength,Matches,Must(including cross-property conditions), each with an optionalWithMessage. Failures from both halves aggregate into oneConfigurationValidationExceptionlisting every error, never just the first. - Dependency injection & warm-up — one
IConfig<T>singleton per file, registered without touching the disk, so building a container needs no test double. The optionalInitializeEnigmaConfigurationAsyncloads and validates every registered file at start-up and reports all failing files at once instead of the first one.
Validated before every write
Validation runs after a load, after a reload, and before every write — so the mutation that broke the rules is caught at the point it would have been persisted, and the file on disk is left untouched. An invalid object never reaches the disk.
Installation
dotnet add package Enigma.Configuration
Targets .NET Standard 2.0, .NET 8.0, and .NET 10.0; built on
Microsoft.Extensions.DependencyInjection.Abstractions 10.0.10 — the DI extension ships inside
this package, so there is no separate .DependencyInjection package. That is the only runtime
dependency on .NET 8.0 and .NET 10.0; on .NET Standard 2.0, where the framework does not provide
them, System.Text.Json and System.ComponentModel.Annotations come along as well.
Quick start
Register a file, read a value, change it, and persist it back to the same file:
using System;
using System.ComponentModel.DataAnnotations;
using Enigma.Configuration;
using Microsoft.Extensions.DependencyInjection;
ServiceCollection services = new ServiceCollection();
services.AddEnigmaConfiguration(builder =>
builder.AddJsonFile<AppSettings>("appsettings.json", optional: true));
IServiceProvider provider = services.BuildServiceProvider();
IConfig<AppSettings> config = provider.GetRequiredService<IConfig<AppSettings>>();
Console.WriteLine(config.Value.Smtp.Port); // first access reads and validates the file
config.Value.Smtp.Port = 587; // mutate the object you were handed …
await config.WriteAsync(); // … and persist it back, atomically
public sealed class AppSettings
{
public string ApplicationName { get; set; } = "MyApp";
public SmtpSettings Smtp { get; set; } = new SmtpSettings(); // grouping is a nested property
}
public sealed class SmtpSettings
{
[Required]
public string Host { get; set; } = "localhost";
[Range(1, 65535)]
public int Port { get; set; } = 25;
}
Documentation
Per-category guides — each with the supported operations, the key types, and copy-pasteable C#
samples verified against the public API — live under docs/guides/ in the repository, indexed by
docs/guides/README.md. They cover getting started (installing, writing a settings class,
registering through DI or the container-free factory, the optional and strict flags, path
resolution and ConfigPaths), reading and writing (IConfig<T> in depth, lazy loading, the
supported type matrix, WriteAsync and ReloadAsync semantics), validation (the DataAnnotations
half and its recursive walk, the fluent ConfigValidator<T> and every built-in rule, the aggregated
exception), and dependency injection (singleton semantics, generic-host wiring, composing
registrations, start-up warm-up, and substituting IConfig<T> in tests).
License
Enigma.Configuration is released under the MIT License.
| 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 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. |
| .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.Extensions.DependencyInjection.Abstractions (>= 10.0.10)
- System.ComponentModel.Annotations (>= 5.0.0)
- System.Text.Json (>= 10.0.10)
-
net10.0
-
net8.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 |
|---|---|---|
| 1.0.0 | 38 | 8/27/2026 |
First public release. Typed, read/write JSON configuration following one idiom: one JSON file bound to one settings class, exposed as a singleton IConfig<T> whose Value is read, mutated and persisted back to the same file — grouping is nested C# properties, so there are no "Section:Key" strings and IConfiguration is never touched. Lazy thread-safe loading with a forgiving reader (case-insensitive keys, comments, trailing commas, BOM, enums by name or number), atomic writes that never leave a corrupt file, explicit ReloadAsync (no hot reload in v1), always-on recursive DataAnnotations validation plus a fluent ConfigValidator<T> aggregated into a single exception and always run before a write, DI registration that opens no file, and an optional start-up warm-up reporting every failing file at once. Targets netstandard2.0, net8.0 and net10.0. See RELEASENOTES.md for the full details.