Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions src/OpenFeature.Hosting/OpenFeatureBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,6 @@ public class OpenFeatureBuilder(IServiceCollection services)
/// <summary> The services being configured. </summary>
public IServiceCollection Services { get; } = services;

/// <summary>
/// Indicates whether the evaluation context has been configured.
/// This property is used to determine if specific configurations or services
/// should be initialized based on the presence of an evaluation context.
/// </summary>
public bool IsContextConfigured { get; internal set; }

/// <summary>
/// Indicates whether the policy has been configured.
/// </summary>
Expand Down
53 changes: 20 additions & 33 deletions src/OpenFeature.Hosting/OpenFeatureBuilderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ public static OpenFeatureBuilder AddContext(this OpenFeatureBuilder builder, Act
Guard.ThrowIfNull(builder);
Guard.ThrowIfNull(configure);

builder.IsContextConfigured = true;
builder.Services.TryAddTransient(provider =>
{
var contextBuilder = EvaluationContext.Builder();
Expand Down Expand Up @@ -163,47 +162,35 @@ internal static OpenFeatureBuilder AddClient(this OpenFeatureBuilder builder, st
{
if (string.IsNullOrWhiteSpace(name))
{
if (builder.IsContextConfigured)
builder.Services.TryAddScoped<IFeatureClient>(static provider =>
{
builder.Services.TryAddScoped<IFeatureClient>(static provider =>
var api = provider.GetRequiredService<Api>();
var client = api.GetClient();

var context = provider.GetService<EvaluationContext>();
if (context is not null)
{
var api = provider.GetRequiredService<Api>();
var client = api.GetClient();
var context = provider.GetRequiredService<EvaluationContext>();
client.SetContext(context);
return client;
});
}
else
{
builder.Services.TryAddScoped<IFeatureClient>(static provider =>
{
var api = provider.GetRequiredService<Api>();
return api.GetClient();
});
}
}

return client;
});
}
else
{
if (builder.IsContextConfigured)
builder.Services.TryAddKeyedScoped<IFeatureClient>(name, static (provider, key) =>
{
builder.Services.TryAddKeyedScoped<IFeatureClient>(name, static (provider, key) =>
var api = provider.GetRequiredService<Api>();
var client = api.GetClient(key!.ToString());

var context = provider.GetService<EvaluationContext>();
if (context is not null)
{
var api = provider.GetRequiredService<Api>();
var client = api.GetClient(key!.ToString());
var context = provider.GetRequiredService<EvaluationContext>();
client.SetContext(context);
return client;
});
}
else
{
builder.Services.TryAddKeyedScoped<IFeatureClient>(name, static (provider, key) =>
{
var api = provider.GetRequiredService<Api>();
return api.GetClient(key!.ToString());
});
}
}

return client;
});
}

return builder;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ public void AddContext_Delegate_ShouldAddServiceToCollection(bool useServiceProv

// Assert
Assert.Equal(_systemUnderTest, featureBuilder);
Assert.True(_systemUnderTest.IsContextConfigured, "The context should be configured.");
Assert.Single(_services, serviceDescriptor =>
serviceDescriptor.ServiceType == typeof(EvaluationContext) &&
serviceDescriptor.Lifetime == ServiceLifetime.Transient);
Expand All @@ -52,7 +51,6 @@ public void AddContext_Delegate_ShouldCorrectlyHandles(bool useServiceProviderDe
var context = serviceProvider.GetService<EvaluationContext>();

// Assert
Assert.True(_systemUnderTest.IsContextConfigured, "The context should be configured.");
Assert.NotNull(context);
Assert.True(delegateCalled, "The delegate should be invoked.");
}
Expand All @@ -78,7 +76,6 @@ public void AddProvider_ShouldAddProviderToCollection(int providerRegistrationTy
};

// Assert
Assert.False(_systemUnderTest.IsContextConfigured, "The context should not be configured.");
Assert.Equal(expectsDefaultProvider, _systemUnderTest.HasDefaultProvider);
Assert.False(_systemUnderTest.IsPolicyConfigured, "The policy should not be configured.");
Assert.Equal(expectsDomainBoundProvider, _systemUnderTest.DomainBoundProviderRegistrationCount);
Expand Down Expand Up @@ -169,7 +166,6 @@ public void AddProvider_VerifiesDefaultAndDomainBoundProvidersBasedOnConfigurati
};

// Assert
Assert.False(_systemUnderTest.IsContextConfigured, "The context should not be configured.");
Assert.Equal(expectsDefaultProvider, _systemUnderTest.HasDefaultProvider);
Assert.False(_systemUnderTest.IsPolicyConfigured, "The policy should not be configured.");
Assert.Equal(expectsDomainBoundProvider, _systemUnderTest.DomainBoundProviderRegistrationCount);
Expand Down Expand Up @@ -518,6 +514,31 @@ public void AddClient_WithNameAndContext_AddsFeatureClient()
Assert.Equal("euw", region.AsString);
}

[Fact]
public void AddClient_WithContextAfterAddProvider_AddsFeatureClient()
{
// Arrange
_services.AddSingleton(sp => Api.Instance);

_systemUnderTest
.AddProvider("client-name", (_systemUnderTest, name) => new NoOpFeatureProvider());

// Act
_systemUnderTest
.AddClient("client-name")
.AddContext((a) => a.Set("region", "euw"));

// Act
using var serviceProvider = _services.BuildServiceProvider();
var client = serviceProvider.GetKeyedService<IFeatureClient>("client-name");

Assert.NotNull(client);

var context = client.GetContext();
var region = context.GetValue("region");
Assert.Equal("euw", region.AsString);
}

[Fact]
public void AddPolicyBasedClient_AddsScopedFeatureClient()
{
Expand Down