100 lines
3.1 KiB
C#
100 lines
3.1 KiB
C#
namespace StellaOps.FeatureFlags;
|
|
|
|
/// <summary>
|
|
/// Provider that supplies feature flag values from a specific source.
|
|
/// Providers are ordered by priority in the composite service.
|
|
/// </summary>
|
|
public interface IFeatureFlagProvider
|
|
{
|
|
/// <summary>
|
|
/// Unique name identifying this provider.
|
|
/// </summary>
|
|
string Name { get; }
|
|
|
|
/// <summary>
|
|
/// Priority order (lower = higher priority, checked first).
|
|
/// </summary>
|
|
int Priority { get; }
|
|
|
|
/// <summary>
|
|
/// Whether this provider supports watching for changes.
|
|
/// </summary>
|
|
bool SupportsWatch { get; }
|
|
|
|
/// <summary>
|
|
/// Tries to get the value of a feature flag.
|
|
/// </summary>
|
|
/// <param name="flagKey">The feature flag key.</param>
|
|
/// <param name="context">Evaluation context for targeting.</param>
|
|
/// <param name="ct">Cancellation token.</param>
|
|
/// <returns>The flag result, or null if this provider doesn't have the flag.</returns>
|
|
Task<FeatureFlagResult?> TryGetFlagAsync(
|
|
string flagKey,
|
|
FeatureFlagEvaluationContext context,
|
|
CancellationToken ct = default);
|
|
|
|
/// <summary>
|
|
/// Lists all feature flags known to this provider.
|
|
/// </summary>
|
|
/// <param name="ct">Cancellation token.</param>
|
|
/// <returns>All flag definitions from this provider.</returns>
|
|
Task<IReadOnlyList<FeatureFlagDefinition>> ListFlagsAsync(CancellationToken ct = default);
|
|
|
|
/// <summary>
|
|
/// Watches for changes to feature flags.
|
|
/// Only called if SupportsWatch is true.
|
|
/// </summary>
|
|
/// <param name="ct">Cancellation token.</param>
|
|
/// <returns>Stream of change events.</returns>
|
|
IAsyncEnumerable<FeatureFlagChangedEvent> WatchAsync(CancellationToken ct = default);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Base class for feature flag providers with common functionality.
|
|
/// </summary>
|
|
public abstract class FeatureFlagProviderBase : IFeatureFlagProvider
|
|
{
|
|
/// <inheritdoc />
|
|
public abstract string Name { get; }
|
|
|
|
/// <inheritdoc />
|
|
public virtual int Priority => 100;
|
|
|
|
/// <inheritdoc />
|
|
public virtual bool SupportsWatch => false;
|
|
|
|
/// <inheritdoc />
|
|
public abstract Task<FeatureFlagResult?> TryGetFlagAsync(
|
|
string flagKey,
|
|
FeatureFlagEvaluationContext context,
|
|
CancellationToken ct = default);
|
|
|
|
/// <inheritdoc />
|
|
public virtual Task<IReadOnlyList<FeatureFlagDefinition>> ListFlagsAsync(
|
|
CancellationToken ct = default)
|
|
{
|
|
return Task.FromResult<IReadOnlyList<FeatureFlagDefinition>>([]);
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public virtual async IAsyncEnumerable<FeatureFlagChangedEvent> WatchAsync(
|
|
[System.Runtime.CompilerServices.EnumeratorCancellation] CancellationToken ct = default)
|
|
{
|
|
// Default implementation does nothing
|
|
await Task.CompletedTask;
|
|
yield break;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a successful flag result.
|
|
/// </summary>
|
|
protected FeatureFlagResult CreateResult(
|
|
string key,
|
|
bool enabled,
|
|
object? variant = null,
|
|
string? reason = null)
|
|
{
|
|
return new FeatureFlagResult(key, enabled, variant, reason, Name);
|
|
}
|
|
}
|