IPSAG.AbTesting 1.0.0-preview27.1

Prefix Reserved
This is a prerelease version of IPSAG.AbTesting.
There is a newer prerelease version of this package available.
See the version list below for details.
dotnet add package IPSAG.AbTesting --version 1.0.0-preview27.1                
NuGet\Install-Package IPSAG.AbTesting -Version 1.0.0-preview27.1                
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="IPSAG.AbTesting" Version="1.0.0-preview27.1" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add IPSAG.AbTesting --version 1.0.0-preview27.1                
#r "nuget: IPSAG.AbTesting, 1.0.0-preview27.1"                
#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.
// Install IPSAG.AbTesting as a Cake Addin
#addin nuget:?package=IPSAG.AbTesting&version=1.0.0-preview27.1&prerelease

// Install IPSAG.AbTesting as a Cake Tool
#tool nuget:?package=IPSAG.AbTesting&version=1.0.0-preview27.1&prerelease                

IPSAG.AbTesting library for .NET

Introduction

The A/B Testing Nuget is a .NET-based library designed to facilitate A/B testing experiments in a controlled environment. It should be included together with an npm package to complete the integration, see example in the playground.

playground Source code
IPSAG.AbTesting Source code
@ips-ag/abtesting Source code

Getting Started

Install the package

Install the Azure Storage Blobs client library for .NET with NuGet:

dotnet add package IPSAG.AbTesting

Prerequisites

You need an Azure subscription and a App Configuration to use this package. The App Insight is not mandatory.

To create a new App Configuration, you can use the Azure Portal, or the Azure CLI. Here's an example using the Azure CLI:

az appconfig create --name MyAppConfig --resource-group MyResourceGroup --location westus

Before you can use the IPSAG.AbTesting, ensure you have the following prerequisites installed on your system:

With these prerequisites in place, you're ready to start using the A/B Testing libraries to conduct your A/B testing experiments.

How to use

In order to interact with the A/B Testing service, you'll need to configure connection to Azure App Configuration.

// Create Host builder
var builder = WebApplication.CreateBuilder(args);
// Sample connection strings
var (appConfigCs, appInsightsCs) = ("<AppConfigConnectionString>", "<AppInsightsConnectionString>");
// Configure A/B Testing by providing connection to App Configuration & App Insights
// By options
builder.AddAbTesting<TargetingContextService>(options =>
{
    options.AppConfigConnectionString = appConfigCs;
    options.AppInsightsConnectionString = appInsightsCs;
    options.UseDefaultControllers = true; // default value
});
// By options & configuration
builder.AddAbTesting<TargetingContextService>((options, configuration) =>
{
    options.AppConfigConnectionString = configuration.GetConnectionString("AppConfig");
    options.AppInsightsConnectionString = configuration.GetConnectionString("AppInsights");
    options.UseDefaultControllers = true; // default value
});
// OR by parameters
builder.AddAbTesting<TargetingContextService>(appConfigCs!,
                                              appInsightsCs);
// Configure A/B Testing by providing connection to App Configuration only
//By options
builder.AddAbTesting<TargetingContextService>(options =>
{
    options.AppConfigConnectionString = appConfigCs;
    options.UseDefaultControllers = true; // default value
});
// By options & configuration
builder.AddAbTesting<TargetingContextService>((options, configuration) =>
{
    options.AppConfigConnectionString = configuration.GetConnectionString("AppConfig");
    options.UseDefaultControllers = true; // default value
});
// OR by parameters
builder.AddAbTesting<TargetingContextService>(appConfigCs!);
var app = builder.Build();
// If you are using Authorization information to build the TargetingContext,
// please ensure that app.UseAbTesting() was placed after app.UseAuthentication(); & app.UseAuthorization();
app.UseAbTesting();
//

The TargetingContextService is an implementation from the interface IPSAG.AbTesting.Services.ITargetingContextService which is required to use A/B Testing package.

There, you could define your own logic to create the TargetingContext which can reflect to App Configuration

// Example
public class TargetingContextService(IHttpContextAccessor contextAccessor) : ITargetingContextService
{
    public async Task<TargetingContext> GetTargetingContextAsync(CancellationToken ct = default)
    {
        HttpContext httpContext = contextAccessor.HttpContext!;
        var user = httpContext.User;
        if (user.Identity == null || !user.Identity.IsAuthenticated)
        {
            return new()
            {
                UserId = "anonymous",
                Groups = []
            };
        }

        var distributionGroup = user.Claims.SingleOrDefault(c => c.Type == ClaimTypes.GroupSid)?.Value;
        return new()
        {
            UserId = user.Identity.Name,
            Groups = string.IsNullOrEmpty(distributionGroup) ? [] : [distributionGroup]
        };
    }
}

By default, a default AbTestingController would be injected to your application

[Route("api/ab-testing")]
public class AbTestingController(IConfigurationService abTestingConfigService) : BaseApiController
{
    [HttpGet("feature-flags")]
    [ProducesResponseType(typeof(FeatureFlag[]), StatusCodes.Status200OK)]
    public async Task<IActionResult> GetAllAsync(CancellationToken ct = default)
    {
        var featureFlags = await abTestingConfigService.ReadFeatureFlagsAsync(ct).ConfigureAwait(false);
        return featureFlags.Match(Ok, ServerError);
    }
}

Request sample

curl -X 'GET' \
  'http://localhost:5103/api/ab-testing/feature-flags' \
  -H 'accept: application/json'

Response body

[
  {
    "name": "ShopFilter",
    "value": "False",
    "isVariant": true
  },
  {
    "name": "ShopFilterEarlyAccess",
    "value": "False",
    "isVariant": false
  },
  {
    "name": "ShopFilterVersion",
    "value": "0.0.1",
    "isVariant": true
  }
]

But you could also use your own controllers by removing the default controllers and defining your controllers and injecting IConfigurationService

// Remove default controllers
builder.AddAbTesting<TargetingContextService>(options =>
{
    options.AppConfigConnectionString = appConfigCs;
    options.AppInsightsConnectionString = appInsightsCs;
    options.UseDefaultControllers = false; // <-- set to false
});
....
// Create new controller
[Route("api/my-route")]
public class MyController(IConfigurationService abTestingConfigService)
{
    // Implementation
}

License

Feedback

We value your feedback! If you have any suggestions, bug reports, or feature requests, please open an issue on our GitHub repository.

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. 
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.0-preview35.1 66 7/16/2024
1.0.0-preview34.1 66 7/11/2024
1.0.0-preview33.1 58 7/11/2024
1.0.0-preview32.1 44 7/11/2024
1.0.0-preview31.1 50 7/11/2024
1.0.0-preview30.1 46 7/11/2024
1.0.0-preview29.1 43 7/11/2024
1.0.0-preview28.1 56 7/11/2024
1.0.0-preview27.1 46 7/11/2024
1.0.0-preview25.1 38 7/11/2024
1.0.0-preview24.1 57 7/11/2024
1.0.0-preview23.1 57 7/9/2024
1.0.0-preview22.1 51 7/9/2024
1.0.0-preview21.1 51 7/9/2024
1.0.0-preview20.1 56 7/9/2024
1.0.0-preview19.1 50 7/4/2024
1.0.0-preview18.1 55 7/4/2024
1.0.0-preview17.1 85 7/4/2024
1.0.0-preview16.1 55 7/4/2024
1.0.0-preview15.1 68 7/4/2024
1.0.0-preview14.1 56 7/3/2024
1.0.0-preview13.1 70 7/2/2024