OpenFeature .NET SDK 2.0 Release
Today we're announcing the release of the OpenFeature SDK for .NET, v2.0! This release contains several ergonomic improvements to the SDK, which .NET developers will appreciate. It also includes some performance optimizations brought to you by the latest .NET primitives.
Notable Improvements
Support for Cancellation Tokens, Idiomatic Method Names
Methods on some key interfaces (such as provider resolvers) have been updated to indicate that they work asynchronously, by appending the Async
suffix in accordance with .NET conventions:
await Api.Instance.SetProvider(myProviderInstance);
await Api.Instance.SetProviderAsync(myProviderInstance);
Additionally, optional cancellation tokens can now be passed to applicable asynchronous methods. This allows for the cancellation of async tasks, and is consistent with .NET norms:
await client.GetBooleanValue("my-flag", false, context, options);
await client.GetBooleanValueAsync("my-flag", false, context, options, cancellationToken);
ValueTasks for Hooks
The return types for stages within hooks have been updated to take advantage of the performance benefit provided by ValueTasks.
The vast majority of hook stages run synchronously, and they are awaited internally by the SDK; so we can avoid the additional allocations associated with Tasks
by using ValueTasks
:
public class MyBeforeHook : Hook
{
public Task<EvaluationContext> Before<T>(HookContext<T> context,
IReadOnlyDictionary<string, object> hints = null)
{
// code to run before flag evaluation
}
public ValueTask<EvaluationContext> BeforeAsync<T>(HookContext<T> context,
IReadOnlyDictionary<string, object> hints = null, CancellationToken cancellationToken = default)
{
// code to run before flag evaluation
}
}
Migration Steps
Application Authors
Async suffixes and Cancellation Tokens
Generally, application authors won't have to make many changes.
As mentioned above, some async methods have been changed to conform to .NET conventions. Evaluation methods now have the "Async" suffix, and accept an optional cancellationToken:
await client.GetBooleanValue("my-flag", false, context, options);
await client.GetBooleanValueAsync("my-flag", false, context, options, cancellationToken);
The method for setting a provider has been updated similarly:
await Api.Instance.SetProvider(myProviderInstance);
await Api.Instance.SetProviderAsync(myProviderInstance);
"Client Name" has Changed to "Domain"
Parameters previously named "client name" are now named "domain". "Domains" are a more powerful concept than "named clients", but in instances where named clients were previously used, function identically. No changes to consuming code are necessary these cases.
Provider Authors
Provider Method Name Changes
Provider authors must change their implementations in accordance with new methods names on the provider interface. Optionally, you can make use of the new cancellation token:
public override Task<ResolutionDetails<bool>> ResolveBooleanValue(
string flagKey,
bool defaultValue,
EvaluationContext? context = null)
{
// return boolean flag details
}
public override Task<ResolutionDetails<bool>> ResolveBooleanValueAsync(
string flagKey,
bool defaultValue,
EvaluationContext? context = null,
CancellationToken cancellationToken = default)
{
// return boolean flag details
}
No Need for Provider Status
It's no longer necessary to define, update or expose provider status.
If your provider requires initialization, simply define the optional InitializeAsync
method:
public class MyProvider : FeatureProvider
{
private ProviderStatus _status = ProviderStatus.NotReady;
public override ProviderStatus GetStatus()
{
return _status;
}
public override Task Initialize(EvaluationContext context)
public override Task InitializeAsync(EvaluationContext context, CancellationToken cancellationToken = default)
{
// some async initialization
}
}
For more details about this change, see our previous blog post.
Hook Authors
Hooks Must Return ValueTask
Hooks must now return ValueTask
instead of Task
:
public class MyBeforeHook : Hook
{
public Task<EvaluationContext> Before<T>(HookContext<T> context,
IReadOnlyDictionary<string, object> hints = null)
{
// code to run before flag evaluation
}
public ValueTask<EvaluationContext> BeforeAsync<T>(HookContext<T> context,
IReadOnlyDictionary<string, object> hints = null, CancellationToken cancellationToken = default)
{
// code to run before flag evaluation
}
}
Full Changelog
See here for the full changelog.
Thanks!
Thanks to all our users, and a special thanks to everyone who contributed to the .NET SDK: