FtrIO 1.1.2
dotnet add package FtrIO --version 1.1.2
NuGet\Install-Package FtrIO -Version 1.1.2
<PackageReference Include="FtrIO" Version="1.1.2" />
<PackageVersion Include="FtrIO" Version="1.1.2" />
<PackageReference Include="FtrIO" />
paket add FtrIO --version 1.1.2
#r "nuget: FtrIO, 1.1.2"
#:package FtrIO@1.1.2
#addin nuget:?package=FtrIO&version=1.1.2
#tool nuget:?package=FtrIO&version=1.1.2
FtrIO
FtrIO == Feature On/Off
Gate method execution from config — no if statements, no wrapper classes. Decorate a method with [Toggle] and it becomes automatically gated by its own name.
Why FtrIO?
- Zero call-site noise.
[Toggle]is the only thing at every call site — all strategy wiring lives in one startup block, not spread across your codebase. A toggled method looks and calls exactly like a normal method — noif (featureFlags.IsEnabled(...)), no injected service, no wrapper at every call site. Remove the attribute and the method is back to normal. - appsettings.json as a read-through cache. Other libraries make your app depend on an external flag service being online. FtrIO flips this: providers run in the background and write their state into
appsettings.json;ToggleParseralways reads from the file. If the remote source goes offline, the last known state is served automatically from disk — no fallback code, no circuit breaker, no stale-cache TTL to configure. - Escape hatch built in. The same
appsettings.jsonyou already deploy works as a fully functional toggle store without any provider. Swap from a static file to Azure App Config (or back) without touching a single call site.
The FtrIO ecosystem
- FtrIO — the core library. Weaves
[Toggle]into your IL at compile time, reads state fromappsettings.jsonat runtime, and optionally syncs from remote sources via the provider pipeline. - FtrIO.Toaster — a lightweight web UI for managing toggles live. Writes values through
ToggleProviderBufferso changes flush toappsettings.jsonand are picked up instantly viaReloadOnChange— no file editing, no restart. Available on Docker Hub — deploy with a singlecompose.yml, no clone required. - FtrIO.onetwo — a .NET CLI audit tool. Scans your source tree for every toggle reference, cross-references against
appsettings.json, and reports each toggle's state (ON / OFF / 20% / BLUE / MISSING) with file and line number. - export-manifest-action — GitHub Action that scans source for
[Toggle]usage and uploads a manifest of required toggle keys as a build artifact. - release-check-action — GitHub Action that downloads the manifest and validates it against a target
appsettings.jsonbefore deploying. Blocks the deploy if any keys are missing.
┌─────────────────────────────────────────────────────┐
│ Your code │
│ [Toggle] public void SendWelcomeEmail() { ... } │
└───────────────────┬─────────────────────────────────┘
│ compile-time weaving
▼
┌─────────────────────────────────────────────────────┐
│ FtrIO core │
│ gates method execution at runtime │
└───────────────────┬─────────────────────────────────┘
│ reads
▼
┌─────────────────────────────────────────────────────┐
│ appsettings.json — source of truth │
└──────────┬──────────────────────────┬───────────────┘
│ writes live │ reads & audits
▼ ▼
FtrIO.Toaster FtrIO.onetwo
(web UI — manage toggles) (CLI — audit state)
How it compares
| FtrIO | LaunchDarkly | Microsoft.FeatureManagement | Flagsmith | |
|---|---|---|---|---|
| Call-site syntax | [Toggle] attribute, zero noise |
SDK call at every site | if (await _fm.IsEnabledAsync(...)) |
SDK call at every site |
| Works offline | ✅ always (file-backed) | ❌ needs SDK fallback config | ✅ | ❌ needs SDK fallback config |
| Compile-time validation | ✅ Roslyn analyzer | ❌ | ❌ | ❌ |
| Codebase audit / drift detection | ✅ FtrIO.onetwo CLI | ❌ | ❌ | ❌ |
| CI/CD deploy gate | ✅ blocks deploy if toggle keys missing from target config | ❌ | ❌ | ❌ |
| Per-user targeting | ✅ UserTargetingStrategy |
✅ | ✅ | ✅ |
| Attribute-based rules | ✅ AttributeRuleStrategy |
✅ | ✅ | ✅ |
| A/B test assignment | ✅ ABTestStrategy (deterministic) |
✅ | ⚠️ via Percentage filter | ✅ |
| Management UI | ✅ Toaster, self-hosted | ✅ SaaS dashboard | ❌ | ✅ SaaS dashboard |
| Percentage rollout | ✅ | ✅ | ✅ | ✅ |
| Self-hosted / no vendor | ✅ | ❌ paid SaaS | ✅ | ✅ (or SaaS) |
| Cost | Free, OSS | Paid SaaS | Free, OSS | Free tier / paid SaaS |
Quick start
dotnet add package FtrIO
{
"FtrIO": { "ReloadOnChange": true },
"Toggles": {
"SendWelcomeEmail": true,
"NewCheckoutFlow": false
}
}
using FtrIO;
[Toggle]
public void SendWelcomeEmail() { ... }
SendWelcomeEmail(); // runs only if "SendWelcomeEmail": true
Any project that decorates its own methods needs an AspectInjector reference — weaving is per-compilation:
<PackageReference Include="AspectInjector" Version="2.9.0" />
Dynamic providers
Providers let toggle state be driven by external sources at runtime while appsettings.json remains the single source of truth for all reads.
flowchart LR
subgraph providers ["Providers (write-only, background)"]
http["HttpToggleParser"]
azure["AzureAppConfigToggleParser"]
env["EnvironmentVariableToggleParser"]
end
buffer(["ToggleProviderBuffer\nflush every N seconds"])
file[/"appsettings.json\n— source of truth —"\]
subgraph read ["Read path (every toggle check)"]
parser["ToggleParser"]
toggle["[Toggle] / [ToggleAsync]\nExecuteMethodIfToggleOn"]
end
http -->|Stage| buffer
azure -->|Stage| buffer
env -->|Stage| buffer
buffer -->|"atomic write\n(tmp → replace)"| file
file -.->|"ReloadOnChange\nfile watcher"| parser
parser --> toggle
style file fill:#2d1f3d,stroke:#ff69b4,color:#ff69b4,font-weight:bold
style buffer fill:#1f2937,stroke:#8b949e,color:#e6edf3
Providers push updates into ToggleProviderBuffer; the buffer flushes to appsettings.json on a configurable interval; ToggleParser reads from the file as normal. If a provider goes offline, the last flushed state persists automatically.
ReloadOnChange: trueis mandatory when using providers — without itToggleParserreads the file once at startup and never sees buffer flushes.
Don't need automated sync? FtrIO.Toaster lets you change toggle values on demand via a UI — no provider pipeline required. It writes directly through
ToggleProviderBufferand your app picks up the change live.
Full provider docs → — HTTP, Azure App Config, env vars, buffer config, CompositeToggleParser
Strategy-based decisions
StrategyToggleParser routes raw config values through a chain of IToggleDecisionStrategy implementations — percentage rollouts, blue-green slots, or custom logic:
ToggleParserProvider.Configure(new StrategyToggleParser(
new PercentageRolloutStrategy(),
new BlueGreenStrategy() // reads slot from FtrIO:BlueGreen in appsettings.json
));
{
"FtrIO": { "BlueGreen": { "CurrentSlot": "blue", "KnownSlots": "blue,green" } },
"Toggles": { "NewCheckout": "20%", "PaymentV2": "blue" }
}
Full strategy docs → — percentage rollout, blue-green, per-user targeting, attribute-based rules, A/B test assignment, per-user overrides, custom
IToggleDecisionStrategy
Multi-environment support
Each server needs only its own appsettings.json — prod, staging, and dev are fully independent with no FtrIO configuration required. For single-machine overlays (appsettings.{env}.json) or remote config sources, see the docs.
Reference
| Topic | Docs |
|---|---|
Async — [ToggleAsync], ExecuteMethodIfToggleOnAsync |
docs/#async |
Hot-reload — ReloadOnChange |
docs/#hotreload |
| Multi-environment — overlays, remote sources | docs/#environments |
| Dynamic providers — HTTP, Azure, env vars | docs/#providers |
| Strategy decisions — percentage, blue-green, user targeting, attribute rules, A/B testing, overrides | docs/#strategies |
Compile-time validation — FTRIO001 |
docs/#analyzer |
Exceptions — ToggleDoesNotExistException etc. |
docs/#exceptions |
| Custom parser / Dependency Injection | docs/#di |
Manual control — ExecuteMethodIfToggleOn |
docs |
| Companion tooling — FtrIO.onetwo | github.com/FtrOnOff/FtrIO.onetwo |
| Companion UI — FtrIO.Toaster | github.com/FtrOnOff/FtrIO.Toaster |
| CI/CD — export-manifest-action | github.com/FtrOnOff/export-manifest-action |
| CI/CD — release-check-action | github.com/FtrOnOff/release-check-action |
| CI/CD — full pipeline docs | docs/#cicd |
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 is compatible. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- AspectInjector (>= 2.9.0)
- Microsoft.Extensions.Configuration (>= 10.0.8)
- Microsoft.Extensions.Configuration.Json (>= 10.0.8)
-
net6.0
- AspectInjector (>= 2.9.0)
- Microsoft.Extensions.Configuration (>= 9.0.0)
- Microsoft.Extensions.Configuration.Json (>= 9.0.0)
-
net7.0
- AspectInjector (>= 2.9.0)
- Microsoft.Extensions.Configuration (>= 9.0.0)
- Microsoft.Extensions.Configuration.Json (>= 9.0.0)
-
net8.0
- AspectInjector (>= 2.9.0)
- Microsoft.Extensions.Configuration (>= 10.0.8)
- Microsoft.Extensions.Configuration.Json (>= 10.0.8)
-
net9.0
- AspectInjector (>= 2.9.0)
- Microsoft.Extensions.Configuration (>= 10.0.8)
- Microsoft.Extensions.Configuration.Json (>= 10.0.8)
NuGet packages (2)
Showing the top 2 NuGet packages that depend on FtrIO:
| Package | Downloads |
|---|---|
|
FtrIO.Providers.AzureAppConfig
Azure App Configuration provider for FtrIO. Reads toggle state from Azure App Config with TTL-based caching and fail-safe fallback. |
|
|
FtrIO.Providers.Http
HTTP toggle provider for FtrIO. Polls a remote JSON endpoint for toggle state with TTL-based caching and fail-safe fallback. |
GitHub repositories
This package is not used by any popular GitHub repositories.