GovBuilt.FeatureFlags.Tenants
1.0.10
dotnet add package GovBuilt.FeatureFlags.Tenants --version 1.0.10
NuGet\Install-Package GovBuilt.FeatureFlags.Tenants -Version 1.0.10
<PackageReference Include="GovBuilt.FeatureFlags.Tenants" Version="1.0.10" />
<PackageVersion Include="GovBuilt.FeatureFlags.Tenants" Version="1.0.10" />
<PackageReference Include="GovBuilt.FeatureFlags.Tenants" />
paket add GovBuilt.FeatureFlags.Tenants --version 1.0.10
#r "nuget: GovBuilt.FeatureFlags.Tenants, 1.0.10"
#:package GovBuilt.FeatureFlags.Tenants@1.0.10
#addin nuget:?package=GovBuilt.FeatureFlags.Tenants&version=1.0.10
#tool nuget:?package=GovBuilt.FeatureFlags.Tenants&version=1.0.10
GovBuilt.FeatureFlags.Tenants
Private package — GovBuiltFeed only. Do not publish to nuget.org.
An Orchard Core module that provides a cross-tenant admin UI for managing feature flags across all running tenants from a single page.
Without this module, an administrator must log in to each tenant separately to toggle flags.
With this module, the host admin can view and update every tenant's flags in one grid view, and the GovBuilt.FeatureFlags module is automatically enabled on any tenant where a flag is turned on.
What this module does
- Renders a Feature Flags Tenant grid at Admin → Configuration → Settings → Feature Flags Tenant
- Loads feature flag settings for all running tenants in parallel (capped concurrency to protect DB connection pools)
- Saves changes to multiple tenants simultaneously in a single Save action
- Auto-enables
GovBuilt.FeatureFlagson any tenant where at least one flag is turned on - Surfaces a warning banner for any tenant whose settings could not be loaded (DB error, misconfiguration), without crashing the page
- Protects the page with a dedicated
ManageTenantFeatureFlagspermission (Administrators only by default)
What this module does NOT
- Replace per-tenant flag management — each tenant still manages its own flags via
GovBuilt.FeatureFlags - Share flag state across tenants — each tenant's settings remain isolated
- Require database migrations
- Expose any API endpoints
Prerequisites
- .NET 8
- Orchard Core multi-tenant host
GovBuilt.FeatureFlagsmodule present in the host (peer dependency — owns per-tenant storage)GovBuilt.FeatureFlags.Abstraction(transitive — providesFeatureFlagSetting)
Installation
Step 1: Add the package to the host project
<PackageReference Include="GovBuilt.FeatureFlags.Tenants" Version="1.0.10" />
No Startup wiring required in the host — the module is discovered automatically by Orchard Core.
Step 2: Enable the feature
In the Orchard Core Admin → Features, search for GovBuilt.FeatureFlags.Tenants and enable it.
Admin UI
Feature Flags by Tenant page
The page renders a card grid where each card represents one flag × tenant combination.
Filter bar — three multi-select dropdowns at the top:
| Dropdown | Purpose |
|---|---|
| Tenant | Show cards for selected tenants only |
| Type | Filter by flag category (e.g. Features, License, UI/Layout) |
| Feature Flag | Filter by specific flag name. Automatically narrows to flags belonging to the selected Types |
Card grid — each card shows:
- Toggle switch (click the switch or the flag title to toggle)
- Flag title and tenant name
- Type badge
- Help text (2-line clamp)
Pagination — 100 cards per page, navigated with Previous / Next / page number buttons.
Sticky Save bar — always visible at the bottom. Saves all changed toggles across all visible tenants in one request.
Architecture
File structure
GovBuilt.FeatureFlags.Tenants/
├── Controllers/
│ └── FeatureFlagTenantsController.cs ← thin: auth + delegate to helper
├── Helpers/
│ ├── IFeatureFlagTenantHelper.cs ← interface
│ └── FeatureFlagTenantHelper.cs ← parallel load/save logic
├── ViewModels/
│ └── FeatureFlagTenantsViewModel.cs
├── Views/FeatureFlagTenants/
│ └── Index.cshtml
├── wwwroot/
│ ├── css/
│ │ ├── feature-flag-tenants.css
│ │ └── bootstrap-multiselect.css
│ └── js/
│ ├── feature-flag-tenants.js
│ └── bootstrap-multiselect.js
├── AdminMenu.cs
├── Permissions.cs
├── Startup.cs
└── Manifest.cs
Key types
| Type | Role |
|---|---|
IFeatureFlagTenantHelper |
Interface for load/save operations — injected into the controller |
FeatureFlagTenantHelper |
Implementation: parallel reads/writes with SemaphoreSlim(10), per-tenant error isolation, auto-enable logic |
FeatureFlagTenantsViewModel |
Carries Tenants, TenantFlags, and FailedTenants to the view |
Permissions.ManageTenantFeatureFlags |
Guards both Index and Save actions |
Performance design for large tenant counts
The helper is built to handle 400+ tenants and 200+ flags without degrading:
| Concern | Solution |
|---|---|
| Sequential DB calls (one per tenant) | Task.WhenAll — all tenants load/save in parallel |
| DB connection pool exhaustion | SemaphoreSlim(10) — max 10 simultaneous connections |
| Reflection boxing on hot read path | Compiled Expression.Lambda getters — zero boxing at 400×200 reads |
| One bad tenant crashing the page | Per-tenant try/catch; failures listed in a warning banner |
Repeated GetAllSettings() calls |
Called once per request; result stored as a local list |
| O(n²) tenant lookup in Save | runningShells.ToDictionary() — O(1) lookup per submitted tenant |
| Unnecessary shell reloads on Save | GetEnabledFeaturesAsync() guard before calling EnableFeaturesAsync |
| Request cancellation | HttpContext.RequestAborted token passed through to all async calls |
Permissions
| Permission | Default role | Description |
|---|---|---|
ManageTenantFeatureFlags |
Administrator | View and save the Feature Flags by Tenant page |
Auto-enable behaviour
When a flag is turned on for a tenant and saved, the module automatically enables GovBuilt.FeatureFlags on that tenant if it is not already enabled. This ensures consuming modules on that tenant can immediately read flag values via IFeatureFlagHelper without requiring manual feature activation.
force: true is passed to EnableFeaturesAsync so any declared dependencies of GovBuilt.FeatureFlags are also enabled automatically.
Publishing
dotnet pack src/GovBuilt.Core/GovBuilt.FeatureFlags.Tenants/GovBuilt.FeatureFlags.Tenants.csproj -c Release -o ./artifacts
dotnet nuget push ./artifacts/GovBuilt.FeatureFlags.Tenants.*.nupkg --source GovBuiltFeed --api-key az
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | 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 was computed. 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 was computed. 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. |
-
net8.0
- GovBuilt.FeatureFlags.Abstraction (>= 1.0.4)
- OrchardCore.Admin.Abstractions (>= 2.2.0)
- OrchardCore.ContentFields (>= 2.2.0)
- OrchardCore.DisplayManagement (>= 2.2.0)
- OrchardCore.Module.Targets (>= 2.2.0)
- OrchardCore.Navigation.Core (>= 2.2.0)
- OrchardCore.ResourceManagement.Abstractions (>= 2.2.0)
- OrchardCore.Security (>= 2.2.0)
- OrchardCore.Settings (>= 2.2.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.