Skip to content

FeatureServiceProvider #604

Closed
Closed

Description

@Stepami

Currently there is IVariantServiceProvider that provides feature-based injection. But it relies on using complicated variants and allocation concepts which might not be needed. So it would be great to have simpler solution compatible with .NET feature management schema.

I see this as some IFeatureServiceProvider with similar API to IVariantServiceProvider where method GetServiceAsync works by simpler algorithm:

  • evaluate feature state
  • if disabled return default
  • if enabled return new

While DI could be configured with new method WithFeatureService:

services.AddFeatureManagement().WithFeatureService<IService, DefaultImpl, NewImpl>("Feature");

Activity

  1. zhiyuanliang-ms commented on May 14, 2026

    @zhiyuanliang-ms
    Member

    Hey, Степан (@Stepami) Thanks for reaching out.

    But it relies on using complicated variants and allocation concepts which might not be needed.

    I can understand that. But if you use Azure App Configuration to create variant feature flags, we offers a wizard UI to create variant feature for you. You won't need to worry about the complicated configurations for variants and allcoations.

    But your feature request seems to be valid, I will bring it to my team.

  2. Stepami commented on May 14, 2026

    @Stepami
    Author

    Zhiyuan Liang (@zhiyuanliang-ms) Thanks for the feedback! I use FM without Azure 😅 so main points are:

    The main blocker i see here is lazy feature service instantiation. After that the implementation of FeatureServiceProvider class will be really trivial.

  3. zhiyuanliang-ms commented on May 26, 2026

    @zhiyuanliang-ms
    Member

    Hey, Степан (@Stepami)

    I'd like to clarify the underlying scenario.
    Feature-based DI only makes sense when the enabled/disabled state of the flag can change at runtime. If the flag's state is fixed at startup, you don't need a service provider abstraction at all. The whole point of IVariantServiceProvider<TService> is to re-evaluate on each resolution so that toggling the flag (or its targeting/filters) takes effect without restarting the app.

    I think instead of having a new API WithFeatureService, we can achieve this through default_when_disabled and default_when_enabled variant allocation with the existing WithVariantService API.

    {
          "id": "variantFeatureA",
          "enabled" : true,
          "variants": [
            { "name": "DefaultImpl" },
            { "name": "NewImpl" }
          ],
          "allocation": {
            "default_when_disabled": "DefaultImpl",
            "default_when_enabled": "NewImpl"
          }
        }

    Besides, we want to promote variant feature flag usage, so we don't intentd to introduce a new WithFeatureService that is driven only by feature flag status.

  4. Stepami commented on May 26, 2026

    @Stepami
    Author

    Hey, Zhiyuan Liang (@zhiyuanliang-ms)

    The underlying scenario is correct. It's about being able to change the state of the flag at runtime.

    But with addition of .NET feature management schema compatibility

    So instead of this 13 lines of json you provided as example one can use simple "variantFeatureA": true configuration

  5. zhiyuanliang-ms commented on May 27, 2026

    @zhiyuanliang-ms
    Member

    Hey, Степан (@Stepami)

    The underlying scenario is correct. It's about being able to change the state of the flag at runtime.

    So you are not using any feature filter?

    Could you check this PR: #607

    This PR enhance the existing variant service provider and WithVariantService api to achieve the "FeatureServiceProvider`

  6. Stepami commented on Jun 4, 2026

    @Stepami
    Author
  7. Stepami commented on Jun 6, 2026

    @Stepami
    Author

    in addition to #605 (comment)

    it'd be really cool to resolve services by status with context allowing featurefilters and "EnabledFor" stuff:

    public interface IFeatureServiceProvider<TService> where TService : class
    {
         // feature status only
        Task<TService> GetServiceAsync();
    
        // feature filter involved
        Task<TService> GetServiceAsync<TContext>(TContext context);
    }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions