Support contextual variant service provider and feature status fallback - #611
Open
zhiyuanliang-ms wants to merge 1 commit into
Open
Support contextual variant service provider and feature status fallback#611zhiyuanliang-ms wants to merge 1 commit into
zhiyuanliang-ms wants to merge 1 commit into
Conversation
|
|
||
| ServiceProvider serviceProvider = services.BuildServiceProvider(); | ||
|
|
||
| IVariantFeatureManager featureManager = serviceProvider.GetRequiredService<IVariantFeatureManager>(); |
Member
There was a problem hiding this comment.
featureManager can be removed
Comment on lines
+105
to
+112
| if (useContext) | ||
| { | ||
| enabled = await _featureManager.IsEnabledAsync(_featureName, context, cancellationToken); | ||
| } | ||
| else | ||
| { | ||
| enabled = await _featureManager.IsEnabledAsync(_featureName, cancellationToken); | ||
| } |
There was a problem hiding this comment.
Pull request overview
This PR expands the variant-service injection capabilities in the Feature Management .NET SDK by introducing a contextual variant service provider API and adding an optional “feature enabled/disabled” fallback path when no variant-based service can be resolved.
Changes:
- Introduces
IContextualVariantServiceProvider<TService>and updates the internalVariantServiceProvider<TService>to support context-aware evaluation. - Adds
WithVariantService<TService, TEnabled, TDisabled>(featureName)to allow falling back to an enabled/disabled implementation when variant resolution fails. - Refactors and extends tests into a dedicated
VariantServiceProviderTestsuite, including new coverage for contextual behavior and feature-status fallback.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/Tests.FeatureManagement/VariantServices.cs | Adds alias-based test implementations used by new variant/fallback tests. |
| tests/Tests.FeatureManagement/VariantServiceProviderTest.cs | New test suite covering variant DI, keyed service resolution, contextual provider behavior, and status fallback. |
| tests/Tests.FeatureManagement/FeatureManagementTest.cs | Removes variant service provider tests that were moved to the new dedicated test file. |
| tests/Tests.FeatureManagement/AppContext.cs | Adds an additional context type for tests (currently unused). |
| src/Microsoft.FeatureManagement/VariantServiceProvider.cs | Implements contextual service retrieval and optional feature-status fallback. |
| src/Microsoft.FeatureManagement/IContextualVariantServiceProvider.cs | New public interface for contextual variant service providers. |
| src/Microsoft.FeatureManagement/FeatureManagementBuilderExtensions.cs | Adds new DI builder overload enabling feature-status fallback and registers contextual provider interface. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+101
to
+104
| // | ||
| // No implementation resolved from a variant. Fall back to the feature status. | ||
| bool enabled; | ||
|
|
Comment on lines
+54
to
+58
| /// <summary> | ||
| /// Adds a <see cref="VariantServiceProvider{TService}"/> to the feature management system that falls back to the feature status when no variant is assigned. | ||
| /// </summary> | ||
| /// <param name="builder">The <see cref="IFeatureManagementBuilder"/> used to customize feature management functionality.</param> | ||
| /// <param name="featureName">The feature flag that should be used to determine which implementation of the service should be used. The <see cref="VariantServiceProvider{TService}"/> will return the implementation matching the assigned variant, or, when no variant is assigned, <typeparamref name="TEnabled"/> if the feature is enabled and <typeparamref name="TDisabled"/> if it is disabled.</param> |
Comment on lines
+14
to
+20
| /// <summary> | ||
| /// Gets an implementation variant of TService, using the provided context to evaluate contextual feature filters when determining the assigned variant. | ||
| /// </summary> | ||
| /// <typeparam name="TContext">The type of the context.</typeparam> | ||
| /// <param name="context">A context that provides information used to evaluate contextual feature filters and to determine which variant will be assigned.</param> | ||
| /// <param name="cancellationToken">The cancellation token to cancel the operation.</param> | ||
| /// <returns>An implementation of TService.</returns> |
Comment on lines
+18
to
+21
| class AccountContext : IAccountContext | ||
| { | ||
| public string AccountId { get; set; } | ||
| } |
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Why this PR?
#604 #608
IVariantServiceProvider<TService>.GetServiceAsynccurrently does not accept a context, which limits it to scenarios that rely on ambient context.This creates a capability gap between
VariantServiceProviderandIVariantFeatureManager, because bothIVariantFeatureManager.IsEnabledAsyncandIVariantFeatureManager.GetVariantAsyncprovide overloads that accept an explicit context.How to fix
This PR introduces
IContextualVariantServiceProvider<TService>with methodGetServiceAsync<TContext>(TContext context, CancellationToken cancellationToken)The PR also adds
WithVariantService<TService, TEnabled, TDisabled>(featureName)which supports falling back to a service based on the feature’s enabled or disabled status.Service resolution behavior
Service resolution follows these steps:
GetVariantAsync.GetVariantAsynconly acceptsITargetingContext, so a non-targeting context is not used during variant resolution.TEnabled.TDisabled.Because
IsEnabledAsyncaccepts an arbitraryTContext, the feature-status fallback honors the supplied context even when it does not implementITargetingContext.