Skip to content

Support Non-Static-Singleton in OpenFeature.Hosting #533

@dflor003

Description

@dflor003

Requirements

My org is exploring adopting OpenFeature as our feature flagging solution in one of our greenfield projects. I was able to plug it into one of our apps relatively easily, but ran into a bit of a roadblock to adopting it. We use WebApplicationFactory<T> for our REST/gRPC API integration tests as outlined in Microsoft's docs here. The integration tests invoke the app's Program.cs, which in turn has the DI registration calls:

builder.Services.AddOpenFeature(options =>
{
  // Provider registration
});

A few of our projects parallelize the integration tests to speed things up and each integration test class gets its own unique DI container so tests don't trample on each other. As I was plugging in OpenFeature I noticed that the test fixtures would pass when run independently but fail if I run the entire suite so I started to do some digging and this line of code is the culprit (Note: This is decompiled code):

public static IServiceCollection AddOpenFeature(
    this IServiceCollection services,
    Action<OpenFeatureBuilder> configure)
  {
    Guard.ThrowIfNull((object) services, nameof (services));
    Guard.ThrowIfNull((object) configure, nameof (configure));
    services.TryAddSingleton<Api>(Api.Instance); // <-- This line
    services.TryAddSingleton<IFeatureLifecycleManager, FeatureLifecycleManager>();
    OpenFeatureBuilder builder = new OpenFeatureBuilder(services);
    configure(builder);
    if (builder.HasDefaultProvider && builder.DomainBoundProviderRegistrationCount == 0)
      return services;
    builder.Validate();
    if (!builder.IsPolicyConfigured)
      builder.AddPolicyName((Action<PolicyNameOptions>) (options => options.DefaultNameSelector = (Func<IServiceProvider, string>) (provider => provider.GetRequiredService<IOptions<OpenFeatureOptions>>().Value.ProviderNames.First<string>())));
    builder.AddPolicyBasedClient();
    return services;
  }

The issue is that while each DI container is independent, they are relying on this static singleton instance of Api which will be the same instance for all tests and when one test tears down its DI container, then the other tests will begin failing due to errors like:

ChannelClosedException : The channel has been closed.

Are there any plans to make the OpenFeature.Hosting library use singletons instantiated through the DI framework rather than static in-memory singletons? Any work arounds or other suggestions? Any help would be much appreciated!

Metadata

Metadata

Assignees

Labels

type: bugSomething isn't working

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions