Skip to content

Commit

Permalink
feat: Make IFeatureClient interface public. (#102)
Browse files Browse the repository at this point in the history
Signed-off-by: Chris Donnelly <chris.donnelly@coxautoinc.com>
  • Loading branch information
cdonnellytx committed Jan 17, 2023
1 parent 9cf4154 commit 5a09c4f
Show file tree
Hide file tree
Showing 2 changed files with 144 additions and 114 deletions.
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

0 comments on commit 5a09c4f

Please sign in to comment.