Skip to content
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

Register built-in filter by default #287

Merged
merged 10 commits into from
Oct 26, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public IFeatureManagementBuilder AddFeatureFilter<T>() where T : IFeatureFilterM

if (!Services.Any(descriptor => descriptor.ServiceType == serviceType && descriptor.ImplementationType == implementationType))
{
Services.AddSingleton(typeof(IFeatureFilterMetadata), typeof(T));
Services.AddSingleton(serviceType, implementationType);
}

return this;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
//
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.FeatureManagement.FeatureFilters;

namespace Microsoft.FeatureManagement
{
/// <summary>
/// Extensions used to add feature management functionality.
/// </summary>
public static class FeatureManagementBuilderExtensions
{
/// <summary>
/// Adds an <see cref="ITargetingContextAccessor"/> to be used for targeting and registers the targeting filter to the feature management system.
/// </summary>
/// <param name="builder">The <see cref="IFeatureManagementBuilder"/> used to customize feature management functionality.</param>
/// <returns>A <see cref="IFeatureManagementBuilder"/> that can be used to customize feature management functionality.</returns>
public static IFeatureManagementBuilder WithTargeting<T>(this IFeatureManagementBuilder builder) where T : ITargetingContextAccessor
{
builder.Services.TryAddSingleton(typeof(ITargetingContextAccessor), typeof(T));

builder.AddFeatureFilter<TargetingFilter>();

return builder;
}
}
}
15 changes: 13 additions & 2 deletions src/Microsoft.FeatureManagement/ServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Logging;
using Microsoft.FeatureManagement.FeatureFilters;
using System;

namespace Microsoft.FeatureManagement
Expand All @@ -15,7 +16,7 @@ namespace Microsoft.FeatureManagement
public static class ServiceCollectionExtensions
{
/// <summary>
/// Adds required feature management services.
/// Adds required feature management services and built-in feature filters.
/// </summary>
/// <param name="services">The service collection that feature management services are added to.</param>
/// <returns>A <see cref="IFeatureManagementBuilder"/> that can be used to customize feature management functionality.</returns>
Expand All @@ -33,7 +34,17 @@ public static IFeatureManagementBuilder AddFeatureManagement(this IServiceCollec

services.AddScoped<IFeatureManagerSnapshot, FeatureManagerSnapshot>();

return new FeatureManagementBuilder(services);
var builder = new FeatureManagementBuilder(services);

//
// Add built-in feature filters
builder.AddFeatureFilter<PercentageFilter>();

builder.AddFeatureFilter<TimeWindowFilter>();

builder.AddFeatureFilter<ContextualTargetingFilter>();

return builder;
}

/// <summary>
Expand Down
28 changes: 10 additions & 18 deletions tests/Tests.FeatureManagement/FeatureManagement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public async Task ReadsOnlyFeatureManagementSection()
}

[Fact]
public async Task AllowDuplicatedFilterAlias()
public async Task AllowsDuplicatedFilterAlias()
{
const string duplicatedFilterName = "DuplicatedFilterName";

Expand All @@ -101,8 +101,7 @@ public async Task AllowDuplicatedFilterAlias()
.AddFeatureManagement()
.AddFeatureFilter<DuplicatedAliasFeatureFilter1>()
.AddFeatureFilter<ContextualDuplicatedAliasFeatureFilterWithAccountContext>()
.AddFeatureFilter<ContextualDuplicatedAliasFeatureFilterWithDummyContext1>()
.AddFeatureFilter<PercentageFilter>();
.AddFeatureFilter<ContextualDuplicatedAliasFeatureFilterWithDummyContext1>();

ServiceProvider serviceProvider = services.BuildServiceProvider();

Expand All @@ -127,8 +126,7 @@ public async Task AllowDuplicatedFilterAlias()
services
.AddSingleton(config)
.AddFeatureManagement()
.AddFeatureFilter<DuplicatedAliasFeatureFilter1>()
.AddFeatureFilter<PercentageFilter>();
.AddFeatureFilter<DuplicatedAliasFeatureFilter1>();

serviceProvider = services.BuildServiceProvider();

Expand All @@ -142,8 +140,7 @@ public async Task AllowDuplicatedFilterAlias()
.AddSingleton(config)
.AddFeatureManagement()
.AddFeatureFilter<DuplicatedAliasFeatureFilter1>()
.AddFeatureFilter<DuplicatedAliasFeatureFilter2>()
.AddFeatureFilter<PercentageFilter>();
.AddFeatureFilter<DuplicatedAliasFeatureFilter2>();

serviceProvider = services.BuildServiceProvider();

Expand All @@ -163,8 +160,7 @@ public async Task AllowDuplicatedFilterAlias()
.AddSingleton(config)
.AddFeatureManagement()
.AddFeatureFilter<ContextualDuplicatedAliasFeatureFilterWithDummyContext1>()
.AddFeatureFilter<ContextualDuplicatedAliasFeatureFilterWithDummyContext2>()
.AddFeatureFilter<PercentageFilter>();
.AddFeatureFilter<ContextualDuplicatedAliasFeatureFilterWithDummyContext2>();

serviceProvider = services.BuildServiceProvider();

Expand All @@ -183,8 +179,7 @@ public async Task AllowDuplicatedFilterAlias()
services
.AddSingleton(config)
.AddFeatureManagement()
.AddFeatureFilter<ContextualDuplicatedAliasFeatureFilterWithAccountContext>()
.AddFeatureFilter<PercentageFilter>();
.AddFeatureFilter<ContextualDuplicatedAliasFeatureFilterWithAccountContext>();

serviceProvider = services.BuildServiceProvider();

Expand Down Expand Up @@ -246,8 +241,7 @@ public async Task TimeWindow()
var serviceCollection = new ServiceCollection();

serviceCollection.AddSingleton(config)
.AddFeatureManagement()
.AddFeatureFilter<TimeWindowFilter>();
.AddFeatureManagement();

ServiceProvider provider = serviceCollection.BuildServiceProvider();

Expand All @@ -272,8 +266,7 @@ public async Task Percentage()
var serviceCollection = new ServiceCollection();

serviceCollection.AddSingleton(config)
.AddFeatureManagement()
.AddFeatureFilter<PercentageFilter>();
.AddFeatureManagement();

ServiceProvider provider = serviceCollection.BuildServiceProvider();

Expand Down Expand Up @@ -307,8 +300,7 @@ public async Task Targeting()

services
.AddSingleton(config)
.AddFeatureManagement()
.AddFeatureFilter<ContextualTargetingFilter>();
.AddFeatureManagement();

ServiceProvider serviceProvider = services.BuildServiceProvider();

Expand Down Expand Up @@ -374,7 +366,7 @@ public async Task TargetingAccessor()
services
.AddSingleton(config)
.AddFeatureManagement()
.AddFeatureFilter<TargetingFilter>();
.WithTargeting<OnDemandTargetingContextAccessor>();

ServiceProvider serviceProvider = services.BuildServiceProvider();

Expand Down