docs: README + CLAUDE.md; verify 0.1.0 pack
ZB.MOM.WW.Configuration — README with purpose, what's-in-the-box, three usage snippets (validator subclass, DI wiring, ConfigPreflight), build/test/pack instructions, and dependency note. CLAUDE.md with one-screen orientation: package table, commands, source layout, and component-normalization status note. 27 tests pass; dotnet pack produces exactly one nupkg (0.1.0).
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
# ZB.MOM.WW.Configuration
|
||||
|
||||
Startup configuration-validation library for the **ZB.MOM.WW SCADA family** (OtOpcUa, MxAccessGateway, ScadaBridge). These are **libraries, not a service** — the package is linked directly into the consuming application at build time. There is no central validation process; all validation runs in-process at startup.
|
||||
|
||||
The library normalizes the three-project configuration-validation surface: a failure-accumulating `IValidateOptions` base, reusable rule primitives, a bind+validate+`ValidateOnStart` DI extension, and a pre-host `ConfigPreflight` aggregator for raw `IConfiguration` — so the plumbing is written once and domain rules stay per-project.
|
||||
|
||||
**Built at 0.1.0. Not yet adopted by OtOpcUa, MxAccessGateway, or ScadaBridge.** Adoption tracked in `~/Desktop/scadaproj/components/configuration/GAPS.md`.
|
||||
|
||||
---
|
||||
|
||||
## Package
|
||||
|
||||
| Package | Responsibilities | Key Dependencies |
|
||||
|---|---|---|
|
||||
| `ZB.MOM.WW.Configuration` | `OptionsValidatorBase<TOptions>` (abstract `IValidateOptions` base, failure-accumulating), `ValidationBuilder` (rule primitives: `Required`, `Port`, `HostPort`, `PositiveTimeSpan`, `OneOf`, `MinCount`, `RequireThat`, `Add`), `ServiceCollectionExtensions.AddValidatedOptions` (bind + validator + `ValidateOnStart` in one call), `ConfigPreflight` (fluent pre-host raw-`IConfiguration` checker). | `Microsoft.Extensions.Options`, `Microsoft.Extensions.Options.ConfigurationExtensions`, `Microsoft.Extensions.Configuration.Abstractions`, `Microsoft.Extensions.DependencyInjection.Abstractions` |
|
||||
|
||||
Single package; no ASP.NET Core framework reference.
|
||||
|
||||
---
|
||||
|
||||
## Build, test, and pack commands
|
||||
|
||||
```bash
|
||||
# From ZB.MOM.WW.Configuration/
|
||||
|
||||
# Build
|
||||
dotnet build ZB.MOM.WW.Configuration.slnx
|
||||
|
||||
# Test (no external dependencies required)
|
||||
dotnet test ZB.MOM.WW.Configuration.slnx
|
||||
|
||||
# Pack (one .nupkg lands in artifacts/)
|
||||
dotnet pack ZB.MOM.WW.Configuration.slnx -c Release -o ./artifacts
|
||||
```
|
||||
|
||||
Test breakdown:
|
||||
|
||||
| Assembly | Tests |
|
||||
|---|---|
|
||||
| `ZB.MOM.WW.Configuration.Tests` | 27 |
|
||||
| **Total** | **27** |
|
||||
|
||||
`GeneratePackageOnBuild` is off — pack explicitly with the command above.
|
||||
|
||||
---
|
||||
|
||||
## Source layout
|
||||
|
||||
```
|
||||
ZB.MOM.WW.Configuration/
|
||||
├── Directory.Build.props # version (0.1.0), TFM (net10.0), central package mgmt
|
||||
├── Directory.Packages.props # pinned package versions
|
||||
├── ZB.MOM.WW.Configuration.slnx # solution file
|
||||
├── src/
|
||||
│ └── ZB.MOM.WW.Configuration/ # library project
|
||||
│ ├── OptionsValidatorBase.cs
|
||||
│ ├── ValidationBuilder.cs
|
||||
│ ├── ServiceCollectionExtensions.cs
|
||||
│ └── ConfigPreflight.cs
|
||||
└── tests/
|
||||
└── ZB.MOM.WW.Configuration.Tests/ # xUnit test project (27 tests)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Status
|
||||
|
||||
Part of the **scadaproj component-normalization family** — this is the configuration + validation component. Built at **0.1.0**. **Not yet adopted by OtOpcUa, MxAccessGateway, or ScadaBridge** — follow-on adoption is tracked in:
|
||||
|
||||
- `~/Desktop/scadaproj/components/configuration/GAPS.md`
|
||||
|
||||
Design documentation:
|
||||
|
||||
- `~/Desktop/scadaproj/components/configuration/spec/SPEC.md` — normalized validation target
|
||||
- `~/Desktop/scadaproj/components/configuration/shared-contract/ZB.MOM.WW.Configuration.md` — proposed shared-library API
|
||||
- `~/Desktop/scadaproj/components/configuration/current-state/` — per-project current state (code-verified)
|
||||
@@ -0,0 +1,112 @@
|
||||
# ZB.MOM.WW.Configuration
|
||||
|
||||
Startup configuration-validation library for the **ZB.MOM.WW SCADA family** (OtOpcUa, MxAccessGateway, ScadaBridge). This is a **library, not a service** — the package is linked directly into the consuming application at build time. It extracts the `IValidateOptions` plumbing the three apps share — failure accumulation, rule primitives, bind+validate DI wiring, and pre-host preflight — so that domain-specific validation rules stay per-project and the boilerplate does not drift.
|
||||
|
||||
---
|
||||
|
||||
## What's in the box
|
||||
|
||||
| Type | Description |
|
||||
|---|---|
|
||||
| `OptionsValidatorBase<TOptions>` | Abstract `IValidateOptions<TOptions>`. Override `protected void Validate(ValidationBuilder v, TOptions o)` to declare failures; the base aggregates all failures and returns a single `ValidateOptionsResult`. |
|
||||
| `ValidationBuilder` | Failure accumulator. Primitives: `Required`, `Port`, `HostPort`, `PositiveTimeSpan`, `OneOf`, `MinCount`, `RequireThat(bool, msg)`, `Add(msg)`. Properties: `Failures` (read), `IsValid`. |
|
||||
| `ServiceCollectionExtensions` | `AddValidatedOptions<TOptions, TValidator>(IConfiguration config, string sectionPath)` — binds the section, registers the validator, and calls `ValidateOnStart()` in a single extension method. Returns `OptionsBuilder<TOptions>`. |
|
||||
| `ConfigPreflight` | Pre-host raw-`IConfiguration` checker. Fluent API: `For(config)`, `.Require(key, predicate, reason)`, `.RequireValue(key)`, `.RequirePort(key)`, `.When(cond, block)`, `.ThrowIfInvalid()`. |
|
||||
|
||||
---
|
||||
|
||||
## Usage
|
||||
|
||||
### 1. Validator subclass
|
||||
|
||||
```csharp
|
||||
public sealed class ClusterOptionsValidator : OptionsValidatorBase<ClusterOptions>
|
||||
{
|
||||
protected override void Validate(ValidationBuilder v, ClusterOptions o)
|
||||
{
|
||||
v.MinCount(o.SeedNodes, 2, "Cluster:SeedNodes");
|
||||
v.OneOf(o.Strategy, new[] { "keep-oldest" }, "Cluster:Strategy");
|
||||
v.PositiveTimeSpan(o.StableAfter, "Cluster:StableAfter");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. DI wiring
|
||||
|
||||
```csharp
|
||||
builder.Services.AddValidatedOptions<ClusterOptions, ClusterOptionsValidator>(
|
||||
builder.Configuration, "ScadaBridge:Cluster");
|
||||
```
|
||||
|
||||
This binds `ScadaBridge:Cluster`, registers `ClusterOptionsValidator`, and enables `ValidateOnStart` — the app refuses to start if the section fails validation.
|
||||
|
||||
### 3. Pre-host preflight
|
||||
|
||||
```csharp
|
||||
ConfigPreflight.For(configuration)
|
||||
.Require("Node:Role", v => v is "Central" or "Site", "must be 'Central' or 'Site'")
|
||||
.RequirePort("Node:RemotingPort")
|
||||
.When(role == "Site", p => p.RequireValue("Node:SiteId"))
|
||||
.ThrowIfInvalid();
|
||||
```
|
||||
|
||||
Use `ConfigPreflight` before `WebApplication.CreateBuilder` for critical keys (node role, remoting port, site ID) that must be present and valid before the DI container is even constructed.
|
||||
|
||||
---
|
||||
|
||||
## Building and testing
|
||||
|
||||
```bash
|
||||
# from ZB.MOM.WW.Configuration/
|
||||
dotnet test ZB.MOM.WW.Configuration.slnx
|
||||
```
|
||||
|
||||
All tests run with no external dependencies:
|
||||
|
||||
| Assembly | Tests |
|
||||
|---|---|
|
||||
| `ZB.MOM.WW.Configuration.Tests` | 27 |
|
||||
| **Total** | **27** |
|
||||
|
||||
---
|
||||
|
||||
## Packing
|
||||
|
||||
```bash
|
||||
dotnet pack ZB.MOM.WW.Configuration.slnx -c Release -o ./artifacts
|
||||
```
|
||||
|
||||
Produces one `.nupkg` file in `artifacts/`:
|
||||
|
||||
```
|
||||
ZB.MOM.WW.Configuration.0.1.0.nupkg
|
||||
```
|
||||
|
||||
`GeneratePackageOnBuild` is off — pack explicitly as above. Version is set in `Directory.Build.props`.
|
||||
|
||||
---
|
||||
|
||||
## Dependencies
|
||||
|
||||
The package has a minimal closure — only `Microsoft.Extensions.*` abstractions:
|
||||
|
||||
- `Microsoft.Extensions.Options`
|
||||
- `Microsoft.Extensions.Options.ConfigurationExtensions`
|
||||
- `Microsoft.Extensions.Configuration.Abstractions`
|
||||
- `Microsoft.Extensions.DependencyInjection.Abstractions`
|
||||
|
||||
No third-party packages; no ASP.NET Core framework reference.
|
||||
|
||||
---
|
||||
|
||||
## Status
|
||||
|
||||
**Built at 0.1.0. Not yet adopted by the three apps.** Adoption is tracked in the component backlog:
|
||||
|
||||
- `~/Desktop/scadaproj/components/configuration/GAPS.md`
|
||||
|
||||
Design documentation lives alongside that backlog:
|
||||
|
||||
- `~/Desktop/scadaproj/components/configuration/spec/SPEC.md` — normalized validation target
|
||||
- `~/Desktop/scadaproj/components/configuration/shared-contract/ZB.MOM.WW.Configuration.md` — proposed API
|
||||
- `~/Desktop/scadaproj/components/configuration/current-state/` — per-project current state (code-verified)
|
||||
Reference in New Issue
Block a user