Skip to content

Latest commit

 

History

History
87 lines (66 loc) · 3.09 KB

File metadata and controls

87 lines (66 loc) · 3.09 KB

AppSettingsGen — Implementation Plan

Architecture Overview

Roslyn incremental source generator that:

  1. Reads appsettings.json from AdditionalFiles
  2. Parses JSON into a tree with System.Text.Json
  3. Infers C# types from JSON values
  4. Generates settings classes + DI registration extension method

All generated code is AOT-compatible (no reflection).

Critical Path

JsonParser → TypeInference → ClassModel → CodeEmitter → SourceGenerator → DI Registration

Implementation Tasks (ordered)

Task 1: JSON Parsing & Type Model

  • SettingsNode — tree model representing a JSON section
  • JsonParser — parse JSON string into SettingsNode tree
  • Type inference: string, int, long, double, bool, array, nested object
  • Naming: convert camelCase/snake_case keys → PascalCase property names

Task 2: Code Emitter

  • CodeEmitter — renders a SettingsNode tree into C# source text
  • Each top-level JSON object → {Name}Settings class
  • Nested objects → nested or separate classes
  • Properties use { get; init; } for immutability
  • Arrays → List<T> or T[]
  • Proper #nullable enable, namespace wrapping

Task 3: DI Registration Emitter

  • Generate AddAppSettings(this IServiceCollection, IConfiguration) extension
  • Bind each section: services.Configure<DatabaseSettings>(config.GetSection("Database"))
  • Static, no reflection — AOT safe

Task 4: Source Generator Wiring

  • AppSettingsGenerator : IIncrementalGenerator
  • Register AdditionalFiles provider filtered to appsettings.json
  • Incremental: only re-run when file content changes
  • Combine parsing + emitting into generated source output

Task 5: Attribute Support

  • [SettingsType] marker attribute (generated) to customize type inference
  • Optional [Required] and [Range] attribute generation

Task 6: Edge Cases & Polish

  • Empty JSON / missing file handling
  • Diagnostic reporting for parse errors
  • Handle duplicate keys, reserved C# keywords as property names

API Surface

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}Settings class per top-level JSON section
  • ServiceCollectionExtensions.AddAppSettings() extension method

Architectural Decisions

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

Test Strategy

  • Unit tests: JsonParser, type inference, CodeEmitter individually
  • Integration tests: full generator driver → verify generated source compiles
  • Real-world JSON samples: complex nested configs, arrays, mixed types