Roslyn incremental source generator that:
- Reads
appsettings.jsonfromAdditionalFiles - Parses JSON into a tree with
System.Text.Json - Infers C# types from JSON values
- Generates settings classes + DI registration extension method
All generated code is AOT-compatible (no reflection).
JsonParser → TypeInference → ClassModel → CodeEmitter → SourceGenerator → DI Registration
SettingsNode— tree model representing a JSON sectionJsonParser— parse JSON string intoSettingsNodetree- Type inference: string, int, long, double, bool, array, nested object
- Naming: convert camelCase/snake_case keys → PascalCase property names
CodeEmitter— renders aSettingsNodetree into C# source text- Each top-level JSON object →
{Name}Settingsclass - Nested objects → nested or separate classes
- Properties use
{ get; init; }for immutability - Arrays →
List<T>orT[] - Proper
#nullable enable, namespace wrapping
- Generate
AddAppSettings(this IServiceCollection, IConfiguration)extension - Bind each section:
services.Configure<DatabaseSettings>(config.GetSection("Database")) - Static, no reflection — AOT safe
AppSettingsGenerator : IIncrementalGenerator- Register
AdditionalFilesprovider filtered toappsettings.json - Incremental: only re-run when file content changes
- Combine parsing + emitting into generated source output
[SettingsType]marker attribute (generated) to customize type inference- Optional
[Required]and[Range]attribute generation
- Empty JSON / missing file handling
- Diagnostic reporting for parse errors
- Handle duplicate keys, reserved C# keywords as property names
For consumers:
// In .csproj — just add the package, mark appsettings.json as AdditionalFiles
<AdditionalFiles Include="appsettings.json" />
// Generated code auto-available:
builder.Services.AddAppSettings(builder.Configuration);
// Use via DI:
public MyService(IOptions<DatabaseSettings> db) { ... }Generated types:
{SectionName}Settingsclass per top-level JSON sectionServiceCollectionExtensions.AddAppSettings()extension method
| Decision | Rationale |
|---|---|
| netstandard2.0 target | Required by Roslyn analyzer/generator hosting |
| System.Text.Json (manual parsing) | Available in netstandard2.0 via package; lightweight |
init properties |
Immutable settings pattern, modern C# |
| Flat class per section | Simpler than deeply nested; matches IOptions pattern |
| No reflection | AOT requirement from spec |
- Unit tests:
JsonParser, type inference,CodeEmitterindividually - Integration tests: full generator driver → verify generated source compiles
- Real-world JSON samples: complex nested configs, arrays, mixed types