26ff8d9b4f
Set up repository with legacy .NET Framework 4.8 source (OLD/), new .NET 10 Blazor solution (NEW/), OpenSpec specifications, documentation, and project configuration.
5.1 KiB
5.1 KiB
Infrastructure Specification
Purpose
Define dependency injection registration patterns and configuration binding patterns for the .NET 10 solution infrastructure.
ADDED Requirements
Requirement: Service registration pattern
The system SHALL use extension methods on IServiceCollection to register module-specific services.
Inputs
- IServiceCollection services
- IConfiguration configuration
Outputs
- IServiceCollection (fluent return for chaining)
Business Rules
- Each module SHALL have one extension method (AddDataAccess, AddDataSync, AddAuth, AddExcelExport, AddSearchProcessing)
- Extension methods SHALL bind their module's Options class from configuration
- Extension methods SHALL register services with appropriate lifetimes:
- Scoped: Database connections, repositories, unit-of-work
- Singleton: Configuration options, HTTP clients, caching services
- Transient: Stateless processors, validators
- Extension methods SHALL return IServiceCollection for fluent chaining
Scenario: Module service registration
- WHEN Program.cs calls builder.Services.AddDataAccess(configuration)
- THEN DataAccessOptions is bound from the "DataAccess" configuration section
- AND ILotFinderRepository is registered with Scoped lifetime
- AND the method returns IServiceCollection for further chaining
Scenario: Service lifetime correctness
- WHEN a Scoped service is requested multiple times within the same HTTP request
- THEN the same instance is returned each time
- AND a new instance is created for the next HTTP request
Scenario: Chained registration
- WHEN Program.cs chains multiple extension methods
- THEN all modules are registered in the order called
- AND the final IServiceCollection contains all registered services
Requirement: Configuration binding pattern
The system SHALL use IOptions pattern to bind strongly-typed configuration from appsettings.json.
Inputs
- appsettings.json with named sections
- Options class with matching property names
Outputs
- IOptions resolved from DI with bound values
Business Rules
- Each Options class SHALL define a static SectionName constant matching the JSON section
- Options classes SHALL use C# naming conventions (PascalCase properties)
- Configuration sections SHALL use matching PascalCase names
- Default values SHALL be defined in Options class properties
- Options classes SHALL be registered using services.Configure(section)
Scenario: Configuration binding at startup
- WHEN the application starts with valid appsettings.json
- THEN IOptions resolves with values from the DataAccess section
- AND properties not specified in JSON use their default values
Scenario: Missing configuration section
- WHEN the application starts without a required configuration section
- THEN IOptions resolves with all default property values
- AND no exception is thrown at startup
Scenario: Development override
- WHEN the application runs in Development environment
- THEN appsettings.Development.json values override appsettings.json values
- AND IOptions.Value.EnableDetailedLogging is true
Requirement: Extension method organization
The system SHALL organize extension methods in the JdeScoping.Core project under an Extensions namespace.
Business Rules
- Extension methods SHALL be in namespace JdeScoping.Core.Extensions
- Each module SHALL have a dedicated static class: {Module}ServiceExtensions
- Extension method SHALL be named Add{Module}
- Files SHALL be located at: JdeScoping.Core/Extensions/{Module}ServiceExtensions.cs
Scenario: Extension method discovery
- WHEN a developer adds using JdeScoping.Core.Extensions
- THEN all AddXxx extension methods are available on IServiceCollection
- AND IntelliSense shows method documentation
Requirement: Options class organization
The system SHALL organize Options classes in the JdeScoping.Core project under an Options namespace.
Business Rules
- Options classes SHALL be in namespace JdeScoping.Core.Options
- Class names SHALL follow pattern: {Module}Options
- SectionName constant SHALL match the JSON section name exactly
- Files SHALL be located at: JdeScoping.Core/Options/{Module}Options.cs
Scenario: Options class consistency
- WHEN DataAccessOptions is defined with SectionName = "DataAccess"
- THEN configuration.GetSection("DataAccess") returns the matching section
- AND services.Configure(section) binds all properties
Migration Notes
| Legacy Pattern | New Pattern | Rationale |
|---|---|---|
| Static Config class | IOptions injection | Testable, supports hot reload |
| Hardcoded values | appsettings.json | Environment-specific configuration |
| Constructor instantiation | DI container registration | Loose coupling, lifetime management |
| Web.config | appsettings.json + environment files | .NET Core standard |