ASP.NET Core integration
This guide targets ASP.NET Core on .NET 8 or later (Minimal API or MVC). The Avsb.SDK NuGet package provides an IServiceCollection.AddAvsb() extension, ASP.NET Core middleware for per-request context scoping, and an IAvsbClient interface for clean dependency injection. By the end you will be reading flags in controllers, Razor Pages, and Blazor components, and tracking events through the same typed client.
Install
1dotnet add package Avsb.SDKObtain your SDK key
Open your A vs B project, go to Settings → Environments, and copy the Server SDK key. Store it in appsettings.json (non-secret environments) or in User Secrets / Azure Key Vault for production.
1dotnet user-secrets set "Avsb:SdkKey" "sdk_production_..."Register the SDK in Program.cs
1using Avsb.AspNetCore;2
3var builder = WebApplication.CreateBuilder(args);4
5builder.Services.AddAvsb(opts =>6{7 opts.SdkKey = builder.Configuration["Avsb:SdkKey"]!;8
9 // Optional: build the EvalContext from each HttpContext.10 opts.ContextFrom = ctx =>11 {12 var userId = ctx.User.FindFirst("sub")?.Value ?? "anon";13 var plan = ctx.User.FindFirst("plan")?.Value ?? "free";14 return new EvalContext15 {16 Kind = "user",17 Key = userId,18 Attributes = new Dictionary<string, object> { ["plan"] = plan },19 };20 };21});22
23var app = builder.Build();24
25app.UseAvsb(); // registers per-request context middleware26app.MapControllers();27
28await app.RunAsync();AddAvsb registers IAvsbClient and IAvsbServer as singletons. The SDK fetches the datafile during application startup (before the first request) so flags are immediately available with no async wait in your handlers.Inject IAvsbClient into a controller
1using Avsb;2using Microsoft.AspNetCore.Mvc;3
4[ApiController]5[Route("[controller]")]6public class CheckoutController : ControllerBase7{8 private readonly IAvsbClient _avsb;9
10 public CheckoutController(IAvsbClient avsb) => _avsb = avsb;11
12 [HttpGet]13 public IActionResult Get()14 {15 var showNew = _avsb.GetBoolFlag("checkout-v2", false);16 var theme = _avsb.GetStringFlag("ui-theme", "default");17
18 return Ok(new { showNewCheckout = showNew.Value, theme = theme.Value });19 }20}Read a flag
Every typed method returns a Flag<T>. The generic type is inferred from the default value.
1// Boolean flag2var checkout = _avsb.GetBoolFlag("checkout-v2", false);3if (checkout.Value) { /* serve new experience */ }4
5// String flag6var theme = _avsb.GetStringFlag("ui-theme", "default");7
8// JSON flag (deserialised to a target type)9var config = _avsb.GetJsonFlag<PricingConfig>("pricing-config", PricingConfig.Default);10
11// Access metadata12Console.WriteLine($"Source: {checkout.Source}, Variation: {checkout.VariationKey}");Track an event
1_avsb.Track("purchase", new TrackPayload2{3 Value = 149.99m,4 Properties = new Dictionary<string, object> { ["currency"] = "usd" },5});Identify a user
The middleware scopes IAvsbClient to the context built by yourContextFrom delegate. To evaluate against a different identity mid-request, inject IAvsbServer and call ForUser:
1// Constructor: private readonly IAvsbServer _server;2var scoped = _server.ForUser(new EvalContext3{4 Kind = "user",5 Key = user.Id.ToString(),6 Attributes = new Dictionary<string, object>7 {8 ["plan"] = user.Plan,9 ["orgId"] = user.OrgId.ToString(),10 },11});12var flag = scoped.GetBoolFlag("checkout-v2", false);Using flags in Blazor
Inject IAvsbClient into Blazor Server components. For Blazor WebAssembly, use the browser-side @avsbhq/react or @avsbhq/browser packages instead.
1@inject IAvsbClient Avsb2
3@if (Avsb.GetBoolFlag("checkout-v2", false).Value)4{5 <NewCheckoutComponent />6}7else8{9 <LegacyCheckoutComponent />10}Graceful shutdown
app.UseAvsb() registers the SDK as a hosted service that implementsIAsyncDisposable. ASP.NET Core's shutdown sequence calls DisposeAsync automatically — pending events are flushed and the polling background service is stopped cleanly with no extra configuration.
Testing
1using Avsb.Testing;2using Microsoft.AspNetCore.Mvc.Testing;3using Xunit;4
5public class CheckoutControllerTests : IClassFixture<WebApplicationFactory<Program>>6{7 private readonly WebApplicationFactory<Program> _factory;8
9 public CheckoutControllerTests(WebApplicationFactory<Program> factory)10 => _factory = factory;11
12 [Fact]13 public async Task ReturnsNewCheckout_WhenFlagIsOn()14 {15 var factory = _factory.WithWebHostBuilder(builder =>16 builder.ConfigureServices(services =>17 services.AddAvsbMock(mock =>18 mock.FlagOn("checkout-v2"))));19
20 var client = factory.CreateClient();21 var resp = await client.GetAsync("/checkout");22
23 resp.EnsureSuccessStatusCode();24 var body = await resp.Content.ReadFromJsonAsync<dynamic>();25 Assert.True((bool)body!.showNewCheckout);26 }27}What's next
- .NET SDK reference — full
IAvsbServerandIAvsbClientAPI. - Spring Boot integration — the same pattern for Java.
- Multi-context targeting — combine user and organisation contexts in one evaluation.