> ## Documentation Index
> Fetch the complete documentation index at: https://docs.westyx.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# .NET SDK - Feature management

> Serve Nexus feature flags to Microsoft.FeatureManagement and IFeatureManager, with no network call per evaluation.

*Package: `WestyxNexus.FeatureManagement` (v0.11.0+)*

Serves Nexus feature flags to `Microsoft.FeatureManagement`, so `IFeatureManager` and the `[FeatureGate]` attribute work against flags managed in the Nexus console.

```sh theme={null}
dotnet add package WestyxNexus.FeatureManagement
```

```csharp theme={null}
builder.Services.AddWestyxNexus(o =>
{
    o.BaseUrl = builder.Configuration["Nexus:BaseUrl"]!;
    o.ApiKey  = builder.Configuration["Nexus:ApiKey"];
});
builder.Services.AddWestyxNexusFeatureManagement();
```

```csharp theme={null}
public sealed class CheckoutController(IFeatureManager features)
{
    public async Task<IActionResult> Index()
    {
        if (await features.IsEnabledAsync("new.checkout"))
            return View("NewCheckout");

        return View("Checkout");
    }
}
```

Or declaratively:

```csharp theme={null}
[FeatureGate("new.checkout")]
public IActionResult NewCheckout() => View();
```

## No network call per evaluation

Every read comes from the SDK's in-memory cache. `IsEnabledAsync` does not make an HTTP request - it looks up a dictionary.

The cache is kept current by the SDK's own TTL polling and SSE stream, so a flag flipped in the Nexus console takes effect without a restart and without any FeatureManagement-side reconfiguration.

## How a Nexus flag maps

| Nexus flag         | `FeatureDefinition`                               |
| ------------------ | ------------------------------------------------- |
| `is_active: true`  | `EnabledFor` = a single `AlwaysOn` filter         |
| `is_active: false` | `EnabledFor` empty                                |
| not defined        | `null` - the feature is *undefined*, not disabled |

This is exactly how Microsoft's own configuration provider represents `"MyFeature": true` and `false`, so Nexus flags behave identically to configuration-defined ones.

`is_active` is computed server-side from `is_enabled` plus the flag's schedule window, so a scheduled flag turns itself on and off with no client involvement.

## Scope: boolean state only

A Nexus flag also supports **percentage rollout** and **cohort targeting**, both evaluated server-side against a supplied user context. Those are **not** routed through `IFeatureManager`.

<Note>
  This is deliberate rather than unfinished. A targeting-aware flag exposed through a boolean-only bridge would silently evaluate as its untargeted default - a rollout you believe is at 10% would read as fully on or fully off, with nothing to indicate it. Being unsupported is safer than being quietly wrong.
</Note>

For percentage rollout and targeting today, call the client directly:

```csharp theme={null}
var results = await nexus.EvaluateABAsync(
    new[] { "new.checkout" },
    userId: currentUser.Id,
    attributes: new Dictionary<string, object> { ["plan"] = "pro" });
```

Per-user targeting through the FeatureManagement and OpenFeature bridges is planned across all providers as one coordinated change.

## Registration order

The provider is registered with `TryAddSingleton` before `AddFeatureManagement()` runs, so it wins over the configuration-backed provider that `AddFeatureManagement()` would otherwise install. If you need both sources, register your own composite `IFeatureDefinitionProvider` instead of calling `AddWestyxNexusFeatureManagement()`.

## Next

* [Dependency injection](/sdks/dotnet/dependency-injection)
* [OpenFeature integration](/sdks/dotnet/openfeature) - the vendor-neutral alternative
* [Design decisions](/sdks/dotnet/design-decisions)
