26ff8d9b4f
Set up repository with legacy .NET Framework 4.8 source (OLD/), new .NET 10 Blazor solution (NEW/), OpenSpec specifications, documentation, and project configuration.
121 lines
4.5 KiB
Markdown
121 lines
4.5 KiB
Markdown
# 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<T> pattern to bind strongly-typed configuration from appsettings.json.
|
|
|
|
#### Inputs
|
|
|
|
- appsettings.json with named sections
|
|
- Options class with matching property names
|
|
|
|
#### Outputs
|
|
|
|
- IOptions<T> 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<T>(section)
|
|
|
|
#### Scenario: Configuration binding at startup
|
|
|
|
- **WHEN** the application starts with valid appsettings.json
|
|
- **THEN** IOptions<DataAccessOptions> 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<T> 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<DataAccessOptions>.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<DataAccessOptions>(section) binds all properties
|
|
|