HTTP polling provider for Cocoar.Configuration enabling remote configuration sources with configurable polling intervals, automatic retries, and failure sentinel values for resilient distributed configuration management.
$ dotnet add package Cocoar.Configuration.HttpPolling
Lightweight, strongly-typed, deterministic multi-source configuration layering for .NET (Current target framework: net9.0).
Deterministic, strongly-typed, rule-driven configuration layering that complements Microsoft.Extensions.Configuration.
IOptions<T> ceremony).IConfigurationSource via the Microsoft Adapter package.Supported TFM: net9.0 (multi-targeting planned).
<ItemGroup>
<PackageReference Include="Cocoar.Configuration" />
<!-- Optional extensions -->
<PackageReference Include="Cocoar.Configuration.DI" />
<PackageReference Include="Cocoar.Configuration.AspNetCore" />
<PackageReference Include="Cocoar.Configuration.HttpPolling" />
<PackageReference Include="Cocoar.Configuration.MicrosoftAdapter" />
</ItemGroup>CLI:
dotnet add package Cocoar.Configuration
dotnet add package Cocoar.Configuration.DI
dotnet add package Cocoar.Configuration.AspNetCore
dotnet add package Cocoar.Configuration.HttpPolling
dotnet add package Cocoar.Configuration.MicrosoftAdapterAdd rules; everything (concrete types + manager) is available immediately.
services.AddCocoarConfiguration([rules]);➡ Full runnable: Examples/BasicUsage
Add interface mappings (optional, works with or without DI):
services.AddCocoarConfiguration([rules], [
Bind.Type<DatabaseConfig>().To<IDatabaseConfig>()
]);➡ Full runnable: Examples/BindingExample
Override lifetimes, disable or extend auto-registration, add keyed services:
services.AddCocoarConfiguration([rules], [bindings], opts => {
opts.DefaultRegistrationLifetime(ServiceLifetime.Singleton);
opts.Register.Add<IPaymentConfig>(ServiceLifetime.Scoped, "backup");
});➡ Full runnable: Examples/ServiceLifetimes
These two concerns are independent and intentionally separated:
| Concern | What You Define | Purpose | Where |
|---|---|---|---|
| Binding | Bind.Type<PaymentConfig>().To<IPaymentConfig>() | Map concrete config types to one or more interfaces for clean consumption | Core (works without DI) |
| DI Registration | options.Register.Add<IPaymentConfig>(ServiceLifetime.Scoped, "backup") | Control lifetimes, add/remove, keyed registrations in the host container | DI Package (Cocoar.Configuration.DI) |
Key points:
ConfigManager interface lookups).options.DefaultRegistrationLifetime(null) and take full manual control via options.Register.Minimal patterns:
services.AddCocoarConfiguration([rules]); // Concrete only
services.AddCocoarConfiguration([rules], [bindings]); // + Interfaces
services.AddCocoarConfiguration([rules], [bindings], opts => { /* control */ });Built-in and extension providers:
| Provider | Package | Change Signal | Notes |
|---|---|---|---|
| Static | Core | ❌ | Seed defaults, compose values |
| File (JSON) | Core | ✅ Filesystem watcher | Deterministic layering |
| Environment | Core | ❌ | Prefix filter; __ & : nesting |
| HTTP Polling | Extension | ✅ | Interval polling, payload diffing |
| Microsoft Adapter | Extension | Depends | Any IConfigurationSource |
👉 See Providers Overview for full details.
Cocoar.Configuration.DI packageBind.Type<T>().To<Interface>() mappingsRule.From.Provider<>() for full controlIConfigurationSource👉 Details in Advanced Features
Multi-project solution under src/Examples/ with runnable demos:
Core Examples:
DI Integration:
Advanced Patterns:
Provider Extensions:
IConfigurationSourceFor more in-depth documentation, see:
.As<T>() API to Binding + DI optionsUseWhen to toggle)This project invests heavily in correctness-first incremental recompute. Optimisations (prefix reuse, cancellation, selection‑hash gating, debounce) are all guarded by strong differential and stress tests so performance never compromises determinism.
Core test suites (see src/tests/):
| Suite | Focus | Guarantee |
|---|---|---|
DifferentialCorrectnessFuzzTests | Random multi-provider mutation waves | Final published snapshot bit-for-bit equals a naive full merge |
PartialRecomputeTests | Prefix reuse / earliest-index accuracy | Unchanged prefix providers are never refetched |
OverlappingRecomputeCorrectnessTests | Cancellation under descending storms | No lost updates; latest versions survive heavy overlap |
CancellationTests | Mid-pass abort & restart | Earlier changes preempt wasted later work |
SnapshotChangeDeletionTests | Deletion propagation | Removed keys do not resurrect spuriously |
RecomputeStressTests | Burst & jitter durability | Bounded passes; stable end-state |
Provider suites (Providers/*Tests) | Integration of file/env/http/adapter | Source-specific semantics remain correct |
Why call this out? Incremental configuration layering is deceptively complex once you introduce cancellation and reuse. Many libraries silently drop updates or leak stale keys; these suites explicitly prevent that class of regression.
Packages are published under the NuGet organization cocoar.
Issues and PRs are welcome 🎉 Keep provider abstractions stable & deterministic. Examples and docs are validated in CI.
(This README reflects the current state – future optimizations & multi-targeting will be documented in docs/.)