diff --git a/CHANGELOG.md b/CHANGELOG.md
index 20d1ccd..3f426a0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+## [1.0.7]
+
+- Added async versions of EvalFeature/GetFeatureValue and a flag on the originals for backwards compatibility.
+
## [1.0.6]
- Set hash version with rule
diff --git a/GrowthBook/GrowthBook.cs b/GrowthBook/GrowthBook.cs
index cc794c9..68db10b 100644
--- a/GrowthBook/GrowthBook.cs
+++ b/GrowthBook/GrowthBook.cs
@@ -166,9 +166,24 @@ public bool IsOff(string key)
}
///
- public T GetFeatureValue(string key, T fallback)
+ public T GetFeatureValue(string key, T fallback, bool alwaysLoadFeatures = false)
{
- var value = EvalFeature(key).Value;
+ if (alwaysLoadFeatures)
+ {
+ LoadFeatures().Wait();
+ }
+
+ var result = EvaluateFeature(key);
+ var value = result.Value;
+
+ return value.IsNull() ? fallback : value.ToObject();
+ }
+
+ ///
+ public async Task GetFeatureValueAsync(string key, T fallback, CancellationToken? cancellationToken = null)
+ {
+ var result = await EvalFeatureAsync(key, cancellationToken);
+ var value = result.Value;
return value.IsNull() ? fallback : value.ToObject();
}
@@ -187,8 +202,25 @@ public Action Subscribe(Action callback)
}
///
- public FeatureResult EvalFeature(string featureId)
+ public FeatureResult EvalFeature(string featureId, bool alwaysLoadFeatures = false)
{
+ if (alwaysLoadFeatures)
+ {
+ LoadFeatures().Wait();
+ }
+
+ return EvaluateFeature(featureId);
+ }
+
+ public async Task EvalFeatureAsync(string featureId, CancellationToken? cancellationToken = null)
+ {
+ await LoadFeatures(cancellationToken: cancellationToken);
+
+ return EvaluateFeature(featureId);
+ }
+
+ private FeatureResult EvaluateFeature(string featureId)
+ {
try
{
if (!Features.TryGetValue(featureId, out Feature feature))
@@ -288,7 +320,7 @@ public ExperimentResult Run(Experiment experiment)
return result;
}
- catch(Exception ex)
+ catch (Exception ex)
{
_logger.LogError(ex, $"Encountered an unhandled exception while executing '{nameof(Run)}'");
diff --git a/GrowthBook/GrowthBook.csproj b/GrowthBook/GrowthBook.csproj
index 5fee0f3..7768c33 100644
--- a/GrowthBook/GrowthBook.csproj
+++ b/GrowthBook/GrowthBook.csproj
@@ -11,7 +11,7 @@
https://github.com/growthbook/growthbook-csharp.git
git
GrowthBook,A/B test,feature toggle,flag
- 1.0.6
+ 1.0.7
GrowthBook C# SDK
https://www.growthbook.io/
README.md
diff --git a/GrowthBook/IGrowthBook.cs b/GrowthBook/IGrowthBook.cs
index 90ad0f5..c7bda61 100644
--- a/GrowthBook/IGrowthBook.cs
+++ b/GrowthBook/IGrowthBook.cs
@@ -25,13 +25,28 @@ public interface IGrowthBook : IDisposable
bool IsOff(string key);
///
- /// Gets the value of a feature cast to the specified type.
+ /// Gets the value of a feature cast to the specified type. This is a blocking operation and should not be used from a UI thread.
///
///
/// The feature key.
/// Fallback value to return if the feature is not on.
+ ///
+ /// Loads all features from the repository/cache prior to executing.
+ /// This is included for backwards compatibility and, when set to true, becomes a blocking operation and should not be used from a UI thread.
+ /// If possible, please use the async version of this method:
+ ///
/// Value of a feature cast to the specified type.
- T GetFeatureValue(string key, T fallback);
+ T GetFeatureValue(string key, T fallback, bool alwaysLoadFeatures = false);
+
+ ///
+ /// Asynchronously gets the value of a feature cast to the specified type.
+ ///
+ ///
+ /// The feature key.
+ /// Fallback value to return if the feature is not on.
+ /// The cancellation token for this operation.
+ /// Value of a feature cast to the specified type.
+ Task GetFeatureValueAsync(string key, T fallback, CancellationToken? cancellationToken = null);
///
/// Returns a map of the latest results indexed by experiment key.
@@ -51,8 +66,21 @@ public interface IGrowthBook : IDisposable
/// Evaluates a feature and returns a feature result.
///
/// The feature key.
+ ///
+ /// Loads all features from the feature repository/cache prior to executing.
+ /// This is included for backwards compatibility and, when set to true, becomes a blocking operation and should not be used from a UI thread.
+ /// If possible, please use the async version of this method:
+ ///
+ /// The feature result.
+ FeatureResult EvalFeature(string key, bool alwaysLoadFeatures = false);
+
+ ///
+ /// Asynchronously loads and evaluates a feature and returns a feature result.
+ ///
+ /// The feature ID.
+ /// The cancellation token for the operation.
/// The feature result.
- FeatureResult EvalFeature(string key);
+ Task EvalFeatureAsync(string featureId, CancellationToken? cancellationToken = null);
///
/// Evaluates an experiment and returns an experiment result.