![]() |
VOOZH | about |
dotnet add package Unleash.Client --version 6.2.1
NuGet\Install-Package Unleash.Client -Version 6.2.1
<PackageReference Include="Unleash.Client" Version="6.2.1" />
<PackageVersion Include="Unleash.Client" Version="6.2.1" />Directory.Packages.props
<PackageReference Include="Unleash.Client" />Project file
paket add Unleash.Client --version 6.2.1
#r "nuget: Unleash.Client, 6.2.1"
#:package Unleash.Client@6.2.1
#addin nuget:?package=Unleash.Client&version=6.2.1Install as a Cake Addin
#tool nuget:?package=Unleash.Client&version=6.2.1Install as a Cake Tool
Migrating to v5
If you use bootstrapping, custom strategies, or a custom JSON serializer, read the complete before upgrading to v5.
Migrating to v6
If you use
- Custom scheduled task managers.
- Event listeners.
- The
UnleashClientFactoryclass.- The
Environmentproperty onUnleashSettings.read the complete before upgrading to v6.
Unleash is a private, secure, and scalable feature management platform built to reduce the risk of releasing new features and accelerate software development. This .Net SDK is designed to help you integrate with Unleash and evaluate feature flags inside your application.
You can use this client with Unleash Enterprise or Unleash Open Source.
The main motivation behind feature toggles is to decouple the process for deploying code to production and releasing new features. This helps reducing risk, and allow us to easily manage which features to enable.
Feature toggles decouple deployment of code from release of new features.
Take a look at the demonstration site at Unleash demo
Read more of the main project at github.com/unleash/unleash
Supported Frameworks (through binaries for net6.0 and netstandard2.0)
Extendable architecture
Install the latest version of Unleash.Client from nuget.org or use the dotnet cli:
dotnet add package unleash.client
⚠️ Important: In almost every case, you only want a single, shared instance of the Unleash client (a singleton) in your application . You would typically use a dependency injection framework to inject it where you need it. Having multiple instances of the client in your application could lead to inconsistencies and performance degradation.
If you create more than 10 instances, Unleash will attempt to log warnings about your usage.
To create a new instance of Unleash you need to create and pass in an UnleashSettings object.
When creating an instance of the Unleash client, you can choose to do it either synchronously or asynchronously. The SDK will synchronize with the Unleash API on initialization, so it can take a moment for the it to reach the correct state. With an asynchronous startup, this would happen in the background while the rest of your code keeps executing. In most cases, this isn't an issue. But if you want to wait until the SDK is fully synchronized, then you should use the configuration explained in the synchronous startup section. This is usually not an issue and Unleash will do this in the background as soon as you initialize it. However, if it's important that you do not continue execution until the SDK has synchronized, then you should use the configuration explained in the synchronous startup section.
using Unleash;
var settings = new UnleashSettings()
{
AppName = "dotnet-test",
UnleashApi = new Uri("<your-api-url>"),
CustomHttpHeaders = new Dictionary<string, string>()
{
{"Authorization","<your-api-token>" }
}
};
var unleash = new DefaultUnleash(settings);
// Add to Container as Singleton
// .NET Core 3/.NET 5/...
services.AddSingleton<IUnleash>(c => unleash);
When your application shuts down, remember to dispose the unleash instance.
unleash?.Dispose()
This unleash client does not throw any exceptions if the unleash server is unreachable. Also, fetching features will return the default value if the feature toggle cache has not yet been populated. In many situations it is perferable to throw an error than allow an application to startup with incorrect feature toggle values. For these cases, we provide a client factory with the option for synchronous initialization.
using Unleash;
using Unleash.ClientFactory;
var settings = new UnleashSettings()
{
AppName = "dotnet-test",
UnleashApi = new Uri("<your-api-url>"),
CustomHttpHeaders = new Dictionary<string, string>()
{
{"Authorization","<your-api-token>" }
}
};
var unleashFactory = new UnleashClientFactory();
IUnleash unleash = await unleashFactory.CreateClientAsync(settings, synchronousInitialization: true);
// this `unleash` has successfully fetched feature toggles and written them to its cache.
// if network errors or disk permissions prevented this from happening, the above await would have thrown an exception
var awesome = unleash.IsEnabled("SuperAwesomeFeature");
The CreateClientAsync method was introduced in version 1.5.0, making the previous Generate method obsolete. There's also a CreateClient method available if you don't prefer the async version.
If you're organizing your feature toggles in projects in Unleash Enterprise, you can scope your API tokens to include only the specific projects needed for your client. Then use that token when configuring the Unleash client:
var settings = new UnleashSettings()
{
AppName = "dotnet-test",
UnleashApi = new Uri("https://eu.app.unleash-hosted.com/demo/api/"),
CustomHttpHeaders = new Dictionary<string, string>()
{
{"Authorization","<your-project-scoped-api-token>" }
}
};
The IsEnabled method allows you to check whether a feature is enabled:
if(unleash.IsEnabled("SuperAwesomeFeature"))
{
//do some magic
}
else
{
//do old boring stuff
}
If the Unleash client can't find the feature you're trying to check, it will default to returning false. You can change this behavior on a per-invocation basis by providing a fallback value as a second argument.
For instance, unleash.IsEnabled("SuperAwesomeFeature") would return false if SuperAwesomeFeature doesn't exist. But if you'd rather it returned true, then you could pass that as the second argument:
unleash.IsEnabled("SuperAwesomeFeature", true)
You can also provide an Unleash context to the IsEnabled method:
var context = new UnleashContext
{
UserId = "61"
};
unleash.IsEnabled("someToggle", context);
Refer to the Unleash context section for more information about using the Unleash context in the .NET SDK.
Currently supported events:
var settings = new UnleashSettings()
{
// ...
};
var unleash = new DefaultUnleash(
settings,
callback:
cfg =>
{
// Set up handling of impression and error events
cfg.ImpressionEvent = evt => { Console.WriteLine($"{evt.FeatureName}: {evt.Enabled}"); };
cfg.ReadyEvent = evt => { Console.WriteLine($"Unleash ready"); };
cfg.ErrorEvent = evt => { /* Handling code here */ Console.WriteLine($"{evt.ErrorType} occured."); };
cfg.TogglesUpdatedEvent = evt => { /* Handling code here */ Console.WriteLine($"Toggles updated on: {evt.UpdatedOn}"); };
}
);
The .Net client comes with implementations for the built-in activation strategies provided by unleash.
Read more about the strategies in the activation strategy reference docs.
You can also specify and implement your own custom strategies. The specification must be registered in the Unleash UI and you must register the strategy implementation when you wire up unleash.
IStrategy s1 = new MyAwesomeStrategy();
IStrategy s2 = new MySuperAwesomeStrategy();
IUnleash unleash = new DefaultUnleash(config, s1, s2);
In order to use some of the common activation strategies you must provide an Unleash context.
If you have configured custom stickiness and want to use that with the FlexibleRolloutStrategy or Variants, add the custom stickiness parameters to the Properties dictionary on the Unleash Context:
HttpContext.Current.Items["UnleashContext"] = new UnleashContext
{
UserId = HttpContext.Current.User?.Identity?.Name,
SessionId = HttpContext.Current.Session?.SessionID,
RemoteAddress = HttpContext.Current.Request.UserHostAddress,
Properties = new Dictionary<string, string>
{
// Obtain "customField" and add it to the context properties
{ "customField", HttpContext.Current.Items["customField"].ToString() }
}
};
The provider typically binds the context to the same thread as the request. If you are using Asp.Net the UnleashContextProvider will typically be a 'request scoped' instance.
public class AspNetContextProvider : IUnleashContextProvider
{
public UnleashContext Context
{
get { return HttpContext.Current?.Items["UnleashContext"] as UnleashContext; }
}
}
protected void Application_BeginRequest(object sender, EventArgs e)
{
HttpContext.Current.Items["UnleashContext"] = new UnleashContext
{
UserId = HttpContext.Current.User?.Identity?.Name,
SessionId = HttpContext.Current.Session?.SessionID,
RemoteAddress = HttpContext.Current.Request.UserHostAddress,
Properties = new Dictionary<string, string>()
{
{"UserRoles", "A,B,C"}
}
};
}
var settings = new UnleashSettings()
{
AppName = "dotnet-test",
UnleashApi = new Uri("https://eu.app.unleash-hosted.com/demo/api/"),
UnleashContextProvider = new AspNetContextProvider(),
CustomHttpHeaders = new Dictionary<string, string>()
{
{"Authorization", "API token" }
}
};
If you want the client to send custom HTTP Headers with all requests to the Unleash api you can define that by setting them via the UnleashSettings.
var settings = new UnleashSettings()
{
AppName = "dotnet-test",
UnleashApi = new Uri("https://eu.app.unleash-hosted.com/demo/api/"),
UnleashContextProvider = new AspNetContextProvider(),
CustomHttpHeaders = new Dictionary<string, string>()
{
{"Authorization", "API token" }
}
};
If you need to specify HttpMessageHandlers or to control the instantiation of the HttpClient, you can create a custom HttpClientFactory that inherits from DefaultHttpClientFactory, and override the method CreateHttpClientInstance. Then configure UnleashSettings to use your custom HttpClientFactory.
internal class CustomHttpClientFactory : DefaultHttpClientFactory
{
protected override HttpClient CreateHttpClientInstance(Uri unleashApiUri)
{
var messageHandler = new CustomHttpMessageHandler();
var httpClient = new HttpClient(messageHandler)
{
BaseAddress = apiUri,
Timeout = TimeSpan.FromSeconds(5)
};
}
}
var settings = new UnleashSettings
{
AppName = "dotnet-test",
//...
HttpClientFactory = new CustomHttpClientFactory()
};
If you need custom http headers that change during the lifetime of the client, a provider can be defined via the UnleashSettings.
Public Class CustomHttpHeaderProvider
Implements IUnleashCustomHttpHeaderProvider
Public Function GetCustomHeaders() As Dictionary(Of String, String) Implements IUnleashCustomHttpHeaderProvider.GetCustomHeaders
Dim token = ' Acquire or refresh a token
Return New Dictionary(Of String, String) From
{{"Authorization", "Bearer " & token}}
End Function
End Class
' ...
Dim unleashSettings As New UnleashSettings()
unleashSettings.AppName = "dotnet-test"
unleashSettings.InstanceTag = "instance z"
' add the custom http header provider to the settings
unleashSettings.UnleashCustomHttpHeaderProvider = New CustomHttpHeaderProvider()
unleashSettings.UnleashApi = new Uri("https://eu.app.unleash-hosted.com/demo/api/")
unleashSettings.UnleashContextProvider = New AspNetContextProvider()
Dim unleash = New DefaultUnleash(unleashSettings)
By default Unleash-client uses LibLog to integrate with the currently configured logger for your application. The supported loggers are:
To plug in your own logger you can implement the ILogProvider interface, and register it with Unleash:
Unleash.Logging.LogProvider.SetCurrentLogProvider(new CustomLogProvider());
var settings = new UnleashSettings()
//...
The GetLogger method is responsible for returning a delegate to be used for logging, and your logging integration should be placed inside that delegate:
using System;
using Unleash.Logging;
namespace Unleash.Demo.CustomLogging
{
public class CustomLogProvider : ILogProvider
{
public Logger GetLogger(string name)
{
return (logLevel, messageFunc, exception, formatParameters) =>
{
// Plug in your logging code here
return true;
};
}
public IDisposable OpenMappedContext(string key, object value, bool destructure = false)
{
return new EmptyIDisposable();
}
public IDisposable OpenNestedContext(string message)
{
return new EmptyIDisposable();
}
}
public class EmptyIDisposable : IDisposable
{
public void Dispose()
{
}
}
}
By default unleash-client fetches the feature toggles from unleash-server every 20s, and stores the result in temporary .json file which is located in System.IO.Path.GetTempPath() directory. This means that if the unleash-server becomes unavailable, the unleash-client will still be able to toggle the features based on the values stored in .json file. As a result of this, the second argument of IsEnabled will be returned in two cases:
The backup file name will follow this pattern: unleash.toggles-{settings.AppName}-{settings.SdkVersion}.json.
You can configure InstanceTag like this:
var settings = new UnleashSettings()
{
AppName = "dotnet-test",
UnleashApi = new Uri("https://eu.app.unleash-hosted.com/demo/api/"),
// Set an instance tag for consistent backup file naming
InstanceTag = "CustomInstanceTag",
UnleashContextProvider = new AspNetContextProvider(),
CustomHttpHeaders = new Dictionary<string, string>()
{
{"Authorization", "API token" }
}
};
IToggleBootstrapProvider interface's single method ToggleCollection Read().
This should return a String that represents the API response from {unleash_url}/api/client/featuresUnleashSettings.ToggleOverride property to falseConfiguring with the UnleashSettings:
var settings = new UnleashSettings()
{
AppName = "dotnet-test",
UnleashApi = new Uri("https://eu.app.unleash-hosted.com/demo/api/"),
CustomHttpHeaders = new Dictionary<string, string>()
{
{"Authorization","API token" }
},
ToggleOverride = false, // Defaults to true
ToggleBootstrapProvider = new MyToggleBootstrapProvider() // A toggle bootstrap provider implementing IToggleBootstrapProvider here
};
Unleash.Utilities:ToggleBootstrapFileProvider which implements the IToggleBootstrapProvider interface.UnleashSettings helper method:settings.UseBootstrapFileProvider("./path/to/file.json");
Unleash also comes with a ToggleBootstrapUrlProvider which implements the IToggleBootstrapProvider interface.
Fetches JSON from a webaddress using HttpMethod.Get
Configure with UnleashSettings helper method:
var shouldThrowOnError = true; // Throws for 500, 404, etc
var customHeaders = new Dictionary<string, string>()
{
{ "Authorization", "Bearer ABCdefg123" } // Or whichever set of headers would be required to GET this file
}; // Defaults to null
settings.UseBootstrapUrlProvider("://domain.top/path/to/file.json", shouldThrowOnError, customHeaders);
The Unleash team have made a separate project which runs unleash server inside docker. Please see unleash-docker for more details.
You may want to mock the IUnleash interface in your unit tests. The SDK comes with a FakeUnleash implementation that you can use for this purpose.
Example usage:
var fakeUnleash = new FakeUnleash(); // Toggles and variants will be disabled by default
fakeUnleash.EnableAllToggles(); // All toggles will be enabled
fakeUnleash.DisableAllToggles(); // All toggles will be disabled
fakeUnleash.SetToggle("MyFeature", true); // Set a specific toggle to enabled
fakeUnleash.SetVariant("MyVariantFeature", new Variant("MyVariantFeature", new Payload("string", "valueA"), true, true)); // Set a specific variant
Visual Studio Community / VS Code / JetBrains Rider Microsoft C# Dev Kit extension for VS Code .NET 8 (For tests)
Code lives in ./src/Unleash
Tests live in ./tests/Unleash.Tests
dotnet builddotnet test - This also executes spec testsWe enforce formatting with dotnet format. This can be installed using the following command:
dotnet tool install -g dotnet-format.
main4.1.9 without v)create new tag <x.x.x> on publishRelease titleGenerate release notes should give a summary of new commits and contributorsset as the latest releasePublish release.
This starts the release workflow which builds the new release and pushes the artifacts to NuGet| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 net5.0 was computed. net5.0-windows net5.0-windows was computed. net6.0 net6.0 is compatible. net6.0-android net6.0-android was computed. net6.0-ios net6.0-ios was computed. net6.0-maccatalyst net6.0-maccatalyst was computed. net6.0-macos net6.0-macos was computed. net6.0-tvos net6.0-tvos was computed. net6.0-windows net6.0-windows was computed. net7.0 net7.0 was computed. net7.0-android net7.0-android was computed. net7.0-ios net7.0-ios was computed. net7.0-maccatalyst net7.0-maccatalyst was computed. net7.0-macos net7.0-macos was computed. net7.0-tvos net7.0-tvos was computed. net7.0-windows net7.0-windows was computed. net8.0 net8.0 was computed. net8.0-android net8.0-android was computed. net8.0-browser net8.0-browser was computed. net8.0-ios net8.0-ios was computed. net8.0-maccatalyst net8.0-maccatalyst was computed. net8.0-macos net8.0-macos was computed. net8.0-tvos net8.0-tvos was computed. net8.0-windows net8.0-windows was computed. net9.0 net9.0 was computed. net9.0-android net9.0-android was computed. net9.0-browser net9.0-browser was computed. net9.0-ios net9.0-ios was computed. net9.0-maccatalyst net9.0-maccatalyst was computed. net9.0-macos net9.0-macos was computed. net9.0-tvos net9.0-tvos was computed. net9.0-windows net9.0-windows was computed. net10.0 net10.0 was computed. net10.0-android net10.0-android was computed. net10.0-browser net10.0-browser was computed. net10.0-ios net10.0-ios was computed. net10.0-maccatalyst net10.0-maccatalyst was computed. net10.0-macos net10.0-macos was computed. net10.0-tvos net10.0-tvos was computed. net10.0-windows net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 netcoreapp2.0 was computed. netcoreapp2.1 netcoreapp2.1 was computed. netcoreapp2.2 netcoreapp2.2 was computed. netcoreapp3.0 netcoreapp3.0 was computed. netcoreapp3.1 netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 netstandard2.0 is compatible. netstandard2.1 netstandard2.1 was computed. |
| .NET Framework | net461 net461 was computed. net462 net462 was computed. net463 net463 was computed. net47 net47 was computed. net471 net471 was computed. net472 net472 was computed. net48 net48 was computed. net481 net481 was computed. |
| MonoAndroid | monoandroid monoandroid was computed. |
| MonoMac | monomac monomac was computed. |
| MonoTouch | monotouch monotouch was computed. |
| Tizen | tizen40 tizen40 was computed. tizen60 tizen60 was computed. |
| Xamarin.iOS | xamarinios xamarinios was computed. |
| Xamarin.Mac | xamarinmac xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos xamarinwatchos was computed. |
Showing the top 5 NuGet packages that depend on Unleash.Client:
| Package | Downloads |
|---|---|
|
Dosaic.Plugins.Management.Unleash
A plugin-first dotnet framework for rapidly building anything hosted in the web. |
|
|
Arbeidstilsynet.Common.FeatureFlags
Package Description |
|
|
PiBox.Plugins.Management.Unleash
PiBox is a `service hosting framework` that allows `.net devs` to `decorate their services with behaviours or functionality (think of plugins) while only using minimal configuration`. |
|
|
Gems.FeatureToggle
Package Description |
|
|
Alaman.Utils
Вспомогательные библиотеки |
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 6.2.1 | 38,561 | 5/19/2026 |
| 6.2.0 | 42,267 | 4/30/2026 |
| 6.1.0 | 184,973 | 3/2/2026 |
| 6.1.0-beta.0 | 83 | 2/23/2026 |
| 6.0.1 | 196,306 | 2/12/2026 |
| 6.0.0 | 49,553 | 2/4/2026 |
| 5.6.2 | 78,263 | 2/3/2026 |
| 5.6.1 | 151,143 | 1/14/2026 |
| 5.6.0 | 87,462 | 12/10/2025 |
| 5.6.0-beta.0 | 363 | 11/13/2025 |
| 5.5.3 | 197,556 | 11/3/2025 |
| 5.5.2 | 37,709 | 10/23/2025 |
| 5.5.1 | 82,041 | 10/8/2025 |
| 5.5.0 | 96,454 | 9/12/2025 |
| 5.4.0 | 1,782,070 | 8/28/2025 |
| 5.4.0-beta.1 | 232 | 8/28/2025 |
| 5.4.0-beta.0 | 230 | 8/27/2025 |
| 4.1.18 | 784,962 | 10/23/2025 |
| 4.1.17 | 204,424 | 8/7/2025 |
| 4.1.16 | 54,456 | 7/30/2025 |