-
Notifications
You must be signed in to change notification settings - Fork 0
feat: scaffold OpenFeature feature-flag support #263
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
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,84 @@ | ||
| using OpenFeature; | ||
| using OpenFeature.Providers.Memory; | ||
|
|
||
| namespace Example; | ||
|
|
||
| /// <summary> | ||
| /// Feature-flag scaffolding for the template. New features land <em>behind a flag, | ||
| /// default-off</em>, are tested in both states, and are switched on only after | ||
| /// validation (see <c>AGENTS.md</c> § Feature flags). Call sites use the portable, | ||
| /// vendor-neutral <see href="https://openfeature.dev/">OpenFeature</see> API, so the | ||
| /// backing provider can change without touching them. The scaffold ships OpenFeature's | ||
| /// built-in in-memory provider so the example evaluates with no external backend — | ||
| /// replace it with a real provider (flagd for GitOps, a hosted service, …) when you | ||
| /// adopt the template. | ||
| /// </summary> | ||
| public static class FeatureFlags | ||
| { | ||
| /// <summary> | ||
| /// Key of the example feature flag. It is registered <em>default-off</em> and gates | ||
| /// <see cref="DescribeAsync(IFeatureClient)"/>; replace it with your own flags. | ||
| /// </summary> | ||
| public const string ExampleFeature = "example-feature"; | ||
|
|
||
| /// <summary>Variant key the in-memory provider resolves to <see langword="true"/> (flag on).</summary> | ||
| public const string EnabledVariant = "on"; | ||
|
|
||
| /// <summary>Variant key the in-memory provider resolves to <see langword="false"/> (flag off).</summary> | ||
| public const string DisabledVariant = "off"; | ||
|
|
||
| /// <summary> | ||
| /// Builds an OpenFeature in-memory provider seeding <see cref="ExampleFeature"/> | ||
| /// default-off, so the scaffold evaluates flags with no external backend. Swap it for | ||
| /// a real provider (flagd, …) without changing any call site. | ||
| /// </summary> | ||
| /// <returns>An in-memory provider with the example flag registered default-off.</returns> | ||
| public static FeatureProvider CreateInMemoryProvider() | ||
| { | ||
| return new InMemoryProvider(new Dictionary<string, Flag>(StringComparer.Ordinal) | ||
| { | ||
| [ExampleFeature] = new Flag<bool>( | ||
| new Dictionary<string, bool>(StringComparer.Ordinal) | ||
| { | ||
| [EnabledVariant] = true, | ||
| [DisabledVariant] = false, | ||
| }, | ||
| DisabledVariant), | ||
| }); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Registers <paramref name="provider"/> as the OpenFeature provider and returns a | ||
| /// client that call sites evaluate flags against. | ||
| /// </summary> | ||
| /// <param name="provider">The provider to register (e.g. from <see cref="CreateInMemoryProvider"/>).</param> | ||
| /// <returns>An OpenFeature client bound to the registered provider.</returns> | ||
| /// <remarks> | ||
| /// Call this once during application startup: it re-registers OpenFeature's process-wide | ||
| /// default provider, and because clients resolve the <em>current</em> provider dynamically, | ||
| /// a later call silently redirects clients obtained earlier. If you need several independent | ||
| /// registrations, reach for OpenFeature's domain/named-client API instead of repeated calls. | ||
| /// </remarks> | ||
| public static async Task<IFeatureClient> CreateClientAsync(FeatureProvider provider) | ||
| { | ||
| ArgumentNullException.ThrowIfNull(provider); | ||
| await Api.Instance.SetProviderAsync(provider).ConfigureAwait(false); | ||
| return Api.Instance.GetClient(); | ||
| } | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
|
|
||
| /// <summary> | ||
| /// Example of gating behaviour on <see cref="ExampleFeature"/>: returns the enhanced | ||
| /// message when the flag resolves on, and the default message when it is off or unset. | ||
| /// Replace it with your own flag-gated code path. | ||
| /// </summary> | ||
| /// <param name="featureClient">The OpenFeature client to evaluate the flag with.</param> | ||
| /// <returns>The flag-gated message.</returns> | ||
| public static async Task<string> DescribeAsync(IFeatureClient featureClient) | ||
| { | ||
| ArgumentNullException.ThrowIfNull(featureClient); | ||
| bool enabled = await featureClient | ||
| .GetBooleanValueAsync(ExampleFeature, false) | ||
| .ConfigureAwait(false); | ||
| return enabled ? "Example feature is on." : "Example feature is off."; | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.