announcements

Introducing the Zenmanage C# / .NET SDK

The Zenmanage .NET SDK brings feature flags to ASP.NET Core services with an async/await API, request-scoped dependency injection, and middleware that builds targeting context from the authenticated user automatically.

The Zenmanage .NET SDK is on NuGet. It ships with a fully async client, deterministic percentage rollouts, and a Zenmanage.AspNetCore package that registers a request-scoped IFlagManager through dependency injection and builds targeting context from middleware.

.NET is the fourth server-side SDK we have shipped this quarter, following Python, JavaScript, and Go. If your team has been proxying flag checks through the REST API from an ASP.NET Core service, or holding off until there was a native client, this is it.

Why .NET

A lot of .NET shops are enterprise teams: internal platforms, line-of-business apps, and services with real change-management requirements sitting behind ASP.NET Core. Those teams need feature flags for the same reasons everyone does — safer rollouts, kill switches, targeted betas — but they also need the flag client to behave like the rest of the framework. Register it once with AddZenmanage, inject IFlagManager wherever you need it, and let request-scoped middleware handle building context per request instead of threading a client through by hand.

Key features

Async/await throughout

Every evaluation call — SingleAsync, defaults collections, context-based targeting — returns a Task. There is no synchronous-over-asynchronous wrapper to work around and nothing that blocks a thread pool thread waiting on a rules fetch.

Fast local evaluation

Rules are fetched and cached in memory or on the filesystem, so evaluation runs against local state rather than a network call on every request. Deterministic bucketing means a context lands in the same rollout bucket every time, so ramping a percentage rollout does not reshuffle who is already in it.

ASP.NET Core middleware and dependency injection

The Zenmanage.AspNetCore package adds AddZenmanage for DI registration and UseZenmanage for request-scoped middleware. Add the middleware after authentication and it builds a Context from HttpContext.User on every request — controllers and minimal API endpoints just inject IFlagManager and call SingleAsync.

Defensive by default

Pass an inline default to any evaluation call and a missing flag or a failed rules fetch resolves to that value instead of throwing. If you would rather handle it explicitly, EvaluationException and FetchRulesException are typed, so you can catch a missing flag separately from a network failure.

Getting started

Install from NuGet:

dotnet add package Zenmanage

Configure a client and evaluate a flag:

using Zenmanage;

var zenmanage = new Zenmanage.Zenmanage(
    ConfigBuilder.Create()
        .WithEnvironmentToken("srv_your_server_key_here")
        .Build());

var flag = await zenmanage.Flags().SingleAsync("new-dashboard");

if (flag.IsEnabled())
{
    Console.WriteLine("Render the new dashboard");
}

For an ASP.NET Core service, add the Zenmanage.AspNetCore package and register it with the DI container:

using Zenmanage;
using Zenmanage.AspNetCore;
using Zenmanage.Contexting;

builder.Services.AddZenmanage(options =>
    options
        .WithEnvironmentToken(builder.Configuration["Zenmanage:EnvironmentToken"])
        .WithCacheBackend(CacheBackend.Memory));

var app = builder.Build();

// Add after authentication so HttpContext.User is populated.
app.UseZenmanage(ctx => Context.Single("user", ctx.User.Identity?.Name ?? "anonymous"));

app.MapGet("/feature-check", async (IFlagManager flags) =>
{
    var flag = await flags.SingleAsync("new-checkout-flow");
    return Results.Ok(new { isEnabled = flag.IsEnabled() });
});

UseZenmanage takes a context factory, so you can enrich it with claims, request headers, or anything else on HttpContext before it reaches your handlers — the middleware example above pulls the user's identity name; a role check or tenant ID is just another attribute on the same context.

What's next

The .NET SDK is a server-side client — it requires a server token (prefixed srv_) by default, the same key requirement as the other server SDKs, and supports client keys explicitly via WithRuntimeEnvironment(RuntimeEnvironment.Client) for the runtimes that need it. More language releases are coming this quarter. The .NET SDK is available on NuGet now, source lives on GitHub, and the .NET quickstart has the full setup, including the ASP.NET Core integration and error-handling patterns.

Enjoyed this article?

Share it with your network.