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
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="GovBuilt.FeatureFlags.Tenants" Version="1.0.10" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="GovBuilt.FeatureFlags.Tenants" Version="1.0.10" />
                    
Directory.Packages.props
<PackageReference Include="GovBuilt.FeatureFlags.Tenants" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add GovBuilt.FeatureFlags.Tenants --version 1.0.10
                    
#r "nuget: GovBuilt.FeatureFlags.Tenants, 1.0.10"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package GovBuilt.FeatureFlags.Tenants@1.0.10
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=GovBuilt.FeatureFlags.Tenants&version=1.0.10
                    
Install as a Cake Addin
#tool nuget:?package=GovBuilt.FeatureFlags.Tenants&version=1.0.10
                    
Install as a Cake Tool

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.FeatureFlags on 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 ManageTenantFeatureFlags permission (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.FeatureFlags module present in the host (peer dependency — owns per-tenant storage)
  • GovBuilt.FeatureFlags.Abstraction (transitive — provides FeatureFlagSetting)

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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.10 323 5/28/2026
1.0.9 100 5/28/2026
1.0.8 90 5/27/2026
1.0.7 93 5/27/2026
1.0.6 112 5/26/2026
1.0.5 127 5/22/2026
1.0.4 100 5/20/2026
1.0.3 99 5/18/2026
1.0.2 101 5/15/2026
1.0.1 95 5/13/2026
1.0.0 89 5/13/2026