26ff8d9b4f
Set up repository with legacy .NET Framework 4.8 source (OLD/), new .NET 10 Blazor solution (NEW/), OpenSpec specifications, documentation, and project configuration.
4.5 KiB
4.5 KiB
infrastructure Specification
Purpose
TBD - created by archiving change setup-solution-foundation. Update Purpose after archive.
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