Skip to content

feat: Make IFeatureClient interface public. #102

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jan 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 129 additions & 1 deletion src/OpenFeature/IFeatureClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,152 @@

namespace OpenFeature
{
internal interface IFeatureClient
/// <summary>
/// Interface used to resolve flags of varying types.
/// </summary>
public interface IFeatureClient
{
/// <summary>
/// Appends hooks to client
/// <para>
/// The appending operation will be atomic.
/// </para>
/// </summary>
/// <param name="hooks">A list of Hooks that implement the <see cref="Hook"/> interface</param>
void AddHooks(IEnumerable<Hook> hooks);

/// <summary>
/// Enumerates the global hooks.
/// <para>
/// The items enumerated will reflect the registered hooks
/// at the start of enumeration. Hooks added during enumeration
/// will not be included.
/// </para>
/// </summary>
/// <returns>Enumeration of <see cref="Hook"/></returns>
IEnumerable<Hook> GetHooks();

/// <summary>
/// Gets the <see cref="EvaluationContext"/> of this client
/// <para>
/// The evaluation context may be set from multiple threads, when accessing the client evaluation context
/// it should be accessed once for an operation, and then that reference should be used for all dependent
/// operations.
/// </para>
/// </summary>
/// <returns><see cref="EvaluationContext"/>of this client</returns>
EvaluationContext GetContext();

/// <summary>
/// Sets the <see cref="EvaluationContext"/> of the client
/// </summary>
/// <param name="context">The <see cref="EvaluationContext"/> to set</param>
void SetContext(EvaluationContext context);

/// <summary>
/// Gets client metadata
/// </summary>
/// <returns>Client metadata <see cref="ClientMetadata"/></returns>
ClientMetadata GetMetadata();

/// <summary>
/// Resolves a boolean feature flag
/// </summary>
/// <param name="flagKey">Feature flag key</param>
/// <param name="defaultValue">Default value</param>
/// <param name="context"><see cref="EvaluationContext">Evaluation Context</see></param>
/// <param name="config"><see cref="EvaluationContext">Flag Evaluation Options</see></param>
/// <returns>Resolved flag value.</returns>
Task<bool> GetBooleanValue(string flagKey, bool defaultValue, EvaluationContext context = null, FlagEvaluationOptions config = null);

/// <summary>
/// Resolves a boolean feature flag
/// </summary>
/// <param name="flagKey">Feature flag key</param>
/// <param name="defaultValue">Default value</param>
/// <param name="context"><see cref="EvaluationContext">Evaluation Context</see></param>
/// <param name="config"><see cref="EvaluationContext">Flag Evaluation Options</see></param>
/// <returns>Resolved flag details <see cref="FlagEvaluationDetails{T}"/></returns>
Task<FlagEvaluationDetails<bool>> GetBooleanDetails(string flagKey, bool defaultValue, EvaluationContext context = null, FlagEvaluationOptions config = null);

/// <summary>
/// Resolves a string feature flag
/// </summary>
/// <param name="flagKey">Feature flag key</param>
/// <param name="defaultValue">Default value</param>
/// <param name="context"><see cref="EvaluationContext">Evaluation Context</see></param>
/// <param name="config"><see cref="EvaluationContext">Flag Evaluation Options</see></param>
/// <returns>Resolved flag value.</returns>
Task<string> GetStringValue(string flagKey, string defaultValue, EvaluationContext context = null, FlagEvaluationOptions config = null);

/// <summary>
/// Resolves a string feature flag
/// </summary>
/// <param name="flagKey">Feature flag key</param>
/// <param name="defaultValue">Default value</param>
/// <param name="context"><see cref="EvaluationContext">Evaluation Context</see></param>
/// <param name="config"><see cref="EvaluationContext">Flag Evaluation Options</see></param>
/// <returns>Resolved flag details <see cref="FlagEvaluationDetails{T}"/></returns>
Task<FlagEvaluationDetails<string>> GetStringDetails(string flagKey, string defaultValue, EvaluationContext context = null, FlagEvaluationOptions config = null);

/// <summary>
/// Resolves a integer feature flag
/// </summary>
/// <param name="flagKey">Feature flag key</param>
/// <param name="defaultValue">Default value</param>
/// <param name="context"><see cref="EvaluationContext">Evaluation Context</see></param>
/// <param name="config"><see cref="EvaluationContext">Flag Evaluation Options</see></param>
/// <returns>Resolved flag value.</returns>
Task<int> GetIntegerValue(string flagKey, int defaultValue, EvaluationContext context = null, FlagEvaluationOptions config = null);

/// <summary>
/// Resolves a integer feature flag
/// </summary>
/// <param name="flagKey">Feature flag key</param>
/// <param name="defaultValue">Default value</param>
/// <param name="context"><see cref="EvaluationContext">Evaluation Context</see></param>
/// <param name="config"><see cref="EvaluationContext">Flag Evaluation Options</see></param>
/// <returns>Resolved flag details <see cref="FlagEvaluationDetails{T}"/></returns>
Task<FlagEvaluationDetails<int>> GetIntegerDetails(string flagKey, int defaultValue, EvaluationContext context = null, FlagEvaluationOptions config = null);

/// <summary>
/// Resolves a double feature flag
/// </summary>
/// <param name="flagKey">Feature flag key</param>
/// <param name="defaultValue">Default value</param>
/// <param name="context"><see cref="EvaluationContext">Evaluation Context</see></param>
/// <param name="config"><see cref="EvaluationContext">Flag Evaluation Options</see></param>
/// <returns>Resolved flag value.</returns>
Task<double> GetDoubleValue(string flagKey, double defaultValue, EvaluationContext context = null, FlagEvaluationOptions config = null);

/// <summary>
/// Resolves a double feature flag
/// </summary>
/// <param name="flagKey">Feature flag key</param>
/// <param name="defaultValue">Default value</param>
/// <param name="context"><see cref="EvaluationContext">Evaluation Context</see></param>
/// <param name="config"><see cref="EvaluationContext">Flag Evaluation Options</see></param>
/// <returns>Resolved flag details <see cref="FlagEvaluationDetails{T}"/></returns>
Task<FlagEvaluationDetails<double>> GetDoubleDetails(string flagKey, double defaultValue, EvaluationContext context = null, FlagEvaluationOptions config = null);

/// <summary>
/// Resolves a structure object feature flag
/// </summary>
/// <param name="flagKey">Feature flag key</param>
/// <param name="defaultValue">Default value</param>
/// <param name="context"><see cref="EvaluationContext">Evaluation Context</see></param>
/// <param name="config"><see cref="EvaluationContext">Flag Evaluation Options</see></param>
/// <returns>Resolved flag value.</returns>
Task<Value> GetObjectValue(string flagKey, Value defaultValue, EvaluationContext context = null, FlagEvaluationOptions config = null);

/// <summary>
/// Resolves a structure object feature flag
/// </summary>
/// <param name="flagKey">Feature flag key</param>
/// <param name="defaultValue">Default value</param>
/// <param name="context"><see cref="EvaluationContext">Evaluation Context</see></param>
/// <param name="config"><see cref="EvaluationContext">Flag Evaluation Options</see></param>
/// <returns>Resolved flag details <see cref="FlagEvaluationDetails{T}"/></returns>
Task<FlagEvaluationDetails<Value>> GetObjectDetails(string flagKey, Value defaultValue, EvaluationContext context = null, FlagEvaluationOptions config = null);
}
}
128 changes: 15 additions & 113 deletions src/OpenFeature/OpenFeatureClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,7 @@ public sealed class FeatureClient : IFeatureClient
return (method(provider), provider);
}

/// <summary>
/// Gets the EvaluationContext of this client<see cref="EvaluationContext"/>
/// <para>
/// The evaluation context may be set from multiple threads, when accessing the client evaluation context
/// it should be accessed once for an operation, and then that reference should be used for all dependent
/// operations.
/// </para>
/// </summary>
/// <returns><see cref="EvaluationContext"/>of this client</returns>
/// <inheritdoc />
public EvaluationContext GetContext()
{
lock (this._evaluationContextLock)
Expand All @@ -70,10 +62,7 @@ public EvaluationContext GetContext()
}
}

/// <summary>
/// Sets the EvaluationContext of the client<see cref="EvaluationContext"/>
/// </summary>
/// <param name="context">The <see cref="EvaluationContext"/> to set</param>
/// <inheritdoc />
public void SetContext(EvaluationContext context)
{
lock (this._evaluationContextLock)
Expand All @@ -97,10 +86,7 @@ public FeatureClient(string name, string version, ILogger logger = null, Evaluat
this._evaluationContext = context ?? EvaluationContext.Empty;
}

/// <summary>
/// Gets client metadata
/// </summary>
/// <returns>Client metadata <see cref="ClientMetadata"/></returns>
/// <inheritdoc />
public ClientMetadata GetMetadata() => this._metadata;

/// <summary>
Expand All @@ -113,156 +99,72 @@ public FeatureClient(string name, string version, ILogger logger = null, Evaluat
/// <param name="hook">Hook that implements the <see cref="Hook"/> interface</param>
public void AddHooks(Hook hook) => this._hooks.Push(hook);

/// <summary>
/// Appends hooks to client
/// <para>
/// The appending operation will be atomic.
/// </para>
/// </summary>
/// <param name="hooks">A list of Hooks that implement the <see cref="Hook"/> interface</param>
/// <inheritdoc />
public void AddHooks(IEnumerable<Hook> hooks) => this._hooks.PushRange(hooks.ToArray());

/// <summary>
/// Enumerates the global hooks.
/// <para>
/// The items enumerated will reflect the registered hooks
/// at the start of enumeration. Hooks added during enumeration
/// will not be included.
/// </para>
/// </summary>
/// <returns>Enumeration of <see cref="Hook"/></returns>
/// <inheritdoc />
public IEnumerable<Hook> GetHooks() => this._hooks.Reverse();

/// <summary>
/// Removes all hooks from the client
/// </summary>
public void ClearHooks() => this._hooks.Clear();

/// <summary>
/// Resolves a boolean feature flag
/// </summary>
/// <param name="flagKey">Feature flag key</param>
/// <param name="defaultValue">Default value</param>
/// <param name="context"><see cref="EvaluationContext">Evaluation Context</see></param>
/// <param name="config"><see cref="EvaluationContext">Flag Evaluation Options</see></param>
/// <returns>Resolved flag details <see cref="FlagEvaluationDetails{T}"/></returns>
/// <inheritdoc />
public async Task<bool> GetBooleanValue(string flagKey, bool defaultValue, EvaluationContext context = null,
FlagEvaluationOptions config = null) =>
(await this.GetBooleanDetails(flagKey, defaultValue, context, config)).Value;

/// <summary>
/// Resolves a boolean feature flag
/// </summary>
/// <param name="flagKey">Feature flag key</param>
/// <param name="defaultValue">Default value</param>
/// <param name="context"><see cref="EvaluationContext">Evaluation Context</see></param>
/// <param name="config"><see cref="EvaluationContext">Flag Evaluation Options</see></param>
/// <returns>Resolved flag details <see cref="FlagEvaluationDetails{T}"/></returns>
/// <inheritdoc />
public async Task<FlagEvaluationDetails<bool>> GetBooleanDetails(string flagKey, bool defaultValue,
EvaluationContext context = null, FlagEvaluationOptions config = null) =>
await this.EvaluateFlag(this.ExtractProvider<bool>(provider => provider.ResolveBooleanValue),
FlagValueType.Boolean, flagKey,
defaultValue, context, config);

/// <summary>
/// Resolves a string feature flag
/// </summary>
/// <param name="flagKey">Feature flag key</param>
/// <param name="defaultValue">Default value</param>
/// <param name="context"><see cref="EvaluationContext">Evaluation Context</see></param>
/// <param name="config"><see cref="EvaluationContext">Flag Evaluation Options</see></param>
/// <returns>Resolved flag details <see cref="FlagEvaluationDetails{T}"/></returns>
/// <inheritdoc />
public async Task<string> GetStringValue(string flagKey, string defaultValue, EvaluationContext context = null,
FlagEvaluationOptions config = null) =>
(await this.GetStringDetails(flagKey, defaultValue, context, config)).Value;

/// <summary>
/// Resolves a string feature flag
/// </summary>
/// <param name="flagKey">Feature flag key</param>
/// <param name="defaultValue">Default value</param>
/// <param name="context"><see cref="EvaluationContext">Evaluation Context</see></param>
/// <param name="config"><see cref="EvaluationContext">Flag Evaluation Options</see></param>
/// <returns>Resolved flag details <see cref="FlagEvaluationDetails{T}"/></returns>
/// <inheritdoc />
public async Task<FlagEvaluationDetails<string>> GetStringDetails(string flagKey, string defaultValue,
EvaluationContext context = null, FlagEvaluationOptions config = null) =>
await this.EvaluateFlag(this.ExtractProvider<string>(provider => provider.ResolveStringValue),
FlagValueType.String, flagKey,
defaultValue, context, config);

/// <summary>
/// Resolves a integer feature flag
/// </summary>
/// <param name="flagKey">Feature flag key</param>
/// <param name="defaultValue">Default value</param>
/// <param name="context"><see cref="EvaluationContext">Evaluation Context</see></param>
/// <param name="config"><see cref="EvaluationContext">Flag Evaluation Options</see></param>
/// <returns>Resolved flag details <see cref="FlagEvaluationDetails{T}"/></returns>
/// <inheritdoc />
public async Task<int> GetIntegerValue(string flagKey, int defaultValue, EvaluationContext context = null,
FlagEvaluationOptions config = null) =>
(await this.GetIntegerDetails(flagKey, defaultValue, context, config)).Value;

/// <summary>
/// Resolves a integer feature flag
/// </summary>
/// <param name="flagKey">Feature flag key</param>
/// <param name="defaultValue">Default value</param>
/// <param name="context"><see cref="EvaluationContext">Evaluation Context</see></param>
/// <param name="config"><see cref="EvaluationContext">Flag Evaluation Options</see></param>
/// <returns>Resolved flag details <see cref="FlagEvaluationDetails{T}"/></returns>
/// <inheritdoc />
public async Task<FlagEvaluationDetails<int>> GetIntegerDetails(string flagKey, int defaultValue,
EvaluationContext context = null, FlagEvaluationOptions config = null) =>
await this.EvaluateFlag(this.ExtractProvider<int>(provider => provider.ResolveIntegerValue),
FlagValueType.Number, flagKey,
defaultValue, context, config);

/// <summary>
/// Resolves a double feature flag
/// </summary>
/// <param name="flagKey">Feature flag key</param>
/// <param name="defaultValue">Default value</param>
/// <param name="context"><see cref="EvaluationContext">Evaluation Context</see></param>
/// <param name="config"><see cref="EvaluationContext">Flag Evaluation Options</see></param>
/// <returns>Resolved flag details <see cref="FlagEvaluationDetails{T}"/></returns>
/// <inheritdoc />
public async Task<double> GetDoubleValue(string flagKey, double defaultValue,
EvaluationContext context = null,
FlagEvaluationOptions config = null) =>
(await this.GetDoubleDetails(flagKey, defaultValue, context, config)).Value;

/// <summary>
/// Resolves a double feature flag
/// </summary>
/// <param name="flagKey">Feature flag key</param>
/// <param name="defaultValue">Default value</param>
/// <param name="context"><see cref="EvaluationContext">Evaluation Context</see></param>
/// <param name="config"><see cref="EvaluationContext">Flag Evaluation Options</see></param>
/// <returns>Resolved flag details <see cref="FlagEvaluationDetails{T}"/></returns>
/// <inheritdoc />
public async Task<FlagEvaluationDetails<double>> GetDoubleDetails(string flagKey, double defaultValue,
EvaluationContext context = null, FlagEvaluationOptions config = null) =>
await this.EvaluateFlag(this.ExtractProvider<double>(provider => provider.ResolveDoubleValue),
FlagValueType.Number, flagKey,
defaultValue, context, config);

/// <summary>
/// Resolves a structure object feature flag
/// </summary>
/// <param name="flagKey">Feature flag key</param>
/// <param name="defaultValue">Default value</param>
/// <param name="context"><see cref="EvaluationContext">Evaluation Context</see></param>
/// <param name="config"><see cref="EvaluationContext">Flag Evaluation Options</see></param>
/// <returns>Resolved flag details <see cref="FlagEvaluationDetails{T}"/></returns>
/// <inheritdoc />
public async Task<Value> GetObjectValue(string flagKey, Value defaultValue, EvaluationContext context = null,
FlagEvaluationOptions config = null) =>
(await this.GetObjectDetails(flagKey, defaultValue, context, config)).Value;

/// <summary>
/// Resolves a structure object feature flag
/// </summary>
/// <param name="flagKey">Feature flag key</param>
/// <param name="defaultValue">Default value</param>
/// <param name="context"><see cref="EvaluationContext">Evaluation Context</see></param>
/// <param name="config"><see cref="EvaluationContext">Flag Evaluation Options</see></param>
/// <returns>Resolved flag details <see cref="FlagEvaluationDetails{T}"/></returns>
/// <inheritdoc />
public async Task<FlagEvaluationDetails<Value>> GetObjectDetails(string flagKey, Value defaultValue,
EvaluationContext context = null, FlagEvaluationOptions config = null) =>
await this.EvaluateFlag(this.ExtractProvider<Value>(provider => provider.ResolveStructureValue),
Expand Down