From 31ce07cc9fde1580b2681229b1a3fba0919163c8 Mon Sep 17 00:00:00 2001 From: "Lingling Ye (from Dev Box)" Date: Wed, 22 Apr 2026 13:31:31 +0800 Subject: [PATCH 1/2] Example app for paramters object --- .../InMemoryFeatureDefinitionProvider.cs | 76 +++++++++++++++++++ .../ParameterObjectConsoleApp.csproj | 19 +++++ examples/ParameterObjectConsoleApp/Program.cs | 40 ++++++++++ examples/ParameterObjectConsoleApp/README.md | 33 ++++++++ 4 files changed, 168 insertions(+) create mode 100644 examples/ParameterObjectConsoleApp/InMemoryFeatureDefinitionProvider.cs create mode 100644 examples/ParameterObjectConsoleApp/ParameterObjectConsoleApp.csproj create mode 100644 examples/ParameterObjectConsoleApp/Program.cs create mode 100644 examples/ParameterObjectConsoleApp/README.md diff --git a/examples/ParameterObjectConsoleApp/InMemoryFeatureDefinitionProvider.cs b/examples/ParameterObjectConsoleApp/InMemoryFeatureDefinitionProvider.cs new file mode 100644 index 00000000..a9fea33f --- /dev/null +++ b/examples/ParameterObjectConsoleApp/InMemoryFeatureDefinitionProvider.cs @@ -0,0 +1,76 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. +// +using Microsoft.FeatureManagement; +using Microsoft.FeatureManagement.FeatureFilters; +namespace ParameterObjectConsoleApp +{ + /// + /// A custom feature definition provider that supplies targeting filter settings + /// directly using the ParametersObject property, avoiding the need to construct IConfiguration. + /// + public class InMemoryFeatureDefinitionProvider : IFeatureDefinitionProvider + { + private readonly Dictionary _featureDefinitions; + + public InMemoryFeatureDefinitionProvider() + { + // + // Define feature flags with targeting settings. + // This demonstrates supplying filter parameters directly via ParametersObject + // instead of constructing an IConfiguration with key-value pairs. + _featureDefinitions = new Dictionary + { + ["Beta"] = new FeatureDefinition + { + Name = "Beta", + EnabledFor = new List + { + new FeatureFilterConfiguration + { + Name = "Microsoft.Targeting", + ParametersObject = new TargetingFilterSettings + { + Audience = new Audience + { + Users = new List { "Jeff", "Anne" }, + Groups = new List + { + new GroupRollout + { + Name = "Management", + RolloutPercentage = 100 + }, + new GroupRollout + { + Name = "TeamMembers", + RolloutPercentage = 45 + } + }, + DefaultRolloutPercentage = 20 + } + } + } + } + } + }; + } + + public Task GetFeatureDefinitionAsync(string featureName) + { + _featureDefinitions.TryGetValue(featureName, out FeatureDefinition definition); + + return Task.FromResult(definition); + } + + public async IAsyncEnumerable GetAllFeatureDefinitionsAsync() + { + foreach (var definition in _featureDefinitions.Values) + { + yield return definition; + } + + await Task.CompletedTask; + } + } +} diff --git a/examples/ParameterObjectConsoleApp/ParameterObjectConsoleApp.csproj b/examples/ParameterObjectConsoleApp/ParameterObjectConsoleApp.csproj new file mode 100644 index 00000000..d78a4b80 --- /dev/null +++ b/examples/ParameterObjectConsoleApp/ParameterObjectConsoleApp.csproj @@ -0,0 +1,19 @@ + + + + Exe + net8.0 + enable + + + + + + + + + + + + + diff --git a/examples/ParameterObjectConsoleApp/Program.cs b/examples/ParameterObjectConsoleApp/Program.cs new file mode 100644 index 00000000..bcceb259 --- /dev/null +++ b/examples/ParameterObjectConsoleApp/Program.cs @@ -0,0 +1,40 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. +// +using Microsoft.FeatureManagement; +using Microsoft.FeatureManagement.FeatureFilters; +using ParameterObjectConsoleApp; + +// +// Create a feature manager using a custom definition provider +// that supplies targeting filter settings directly via ParametersObject. +var featureManager = new FeatureManager(new InMemoryFeatureDefinitionProvider()) +{ + FeatureFilters = new List { new ContextualTargetingFilter() } +}; + +// +// Simulate evaluating the "Beta" feature for different users +var users = new List<(string UserId, List Groups)> +{ + ("Jeff", new List { "TeamMembers" }), // Targeted by user name + ("Anne", new List { "Management" }), // Targeted by user name + ("Sam", new List { "Management" }), // Targeted by group (100% rollout) + ("Alice", new List { "TeamMembers" }), // May be targeted by group (45% rollout) + ("Bob", new List { "External" }) // Only targeted by default rollout (20%) +}; + +foreach (var (userId, groups) in users) +{ + const string FeatureName = "Beta"; + + var targetingContext = new TargetingContext + { + UserId = userId, + Groups = groups + }; + + bool enabled = await featureManager.IsEnabledAsync(FeatureName, targetingContext); + + Console.WriteLine($"The {FeatureName} feature is {(enabled ? "enabled" : "disabled")} for the user '{userId}'."); +} diff --git a/examples/ParameterObjectConsoleApp/README.md b/examples/ParameterObjectConsoleApp/README.md new file mode 100644 index 00000000..b6405328 --- /dev/null +++ b/examples/ParameterObjectConsoleApp/README.md @@ -0,0 +1,33 @@ +# ParametersObject Console App + +This example demonstrates how to use the `ParametersObject` property on `FeatureFilterConfiguration` to supply filter settings directly from a custom `IFeatureDefinitionProvider`. + +## Overview + +When implementing a custom `IFeatureDefinitionProvider` that sources feature definitions from alternative backends (e.g., databases, REST APIs), you no longer need to construct an `IConfiguration` object to pass filter parameters. Instead, you can assign settings like `TargetingFilterSettings` directly to `ParametersObject`. + +## Key Concept + +```csharp +new FeatureFilterConfiguration +{ + Name = "Microsoft.Targeting", + ParametersObject = new TargetingFilterSettings + { + Audience = new Audience + { + Users = new List { "Jeff", "Anne" }, + Groups = new List { ... }, + DefaultRolloutPercentage = 20 + } + } +} +``` + +This eliminates the need for verbose `IConfiguration` construction with magic string keys. + +## Running + +``` +dotnet run +``` From 537ccaa055e0507709e1e1803d9257ce90131153 Mon Sep 17 00:00:00 2001 From: "Lingling Ye (from Dev Box)" Date: Mon, 11 May 2026 16:34:22 +0800 Subject: [PATCH 2/2] update --- .../InMemoryFeatureDefinitionProvider.cs | 2 +- .../ParametersObjectConsoleApp.csproj} | 6 ------ .../Program.cs | 2 +- .../README.md | 2 +- 4 files changed, 3 insertions(+), 9 deletions(-) rename examples/{ParameterObjectConsoleApp => ParametersObjectConsoleApp}/InMemoryFeatureDefinitionProvider.cs (98%) rename examples/{ParameterObjectConsoleApp/ParameterObjectConsoleApp.csproj => ParametersObjectConsoleApp/ParametersObjectConsoleApp.csproj} (55%) rename examples/{ParameterObjectConsoleApp => ParametersObjectConsoleApp}/Program.cs (97%) rename examples/{ParameterObjectConsoleApp => ParametersObjectConsoleApp}/README.md (91%) diff --git a/examples/ParameterObjectConsoleApp/InMemoryFeatureDefinitionProvider.cs b/examples/ParametersObjectConsoleApp/InMemoryFeatureDefinitionProvider.cs similarity index 98% rename from examples/ParameterObjectConsoleApp/InMemoryFeatureDefinitionProvider.cs rename to examples/ParametersObjectConsoleApp/InMemoryFeatureDefinitionProvider.cs index a9fea33f..702b7e84 100644 --- a/examples/ParameterObjectConsoleApp/InMemoryFeatureDefinitionProvider.cs +++ b/examples/ParametersObjectConsoleApp/InMemoryFeatureDefinitionProvider.cs @@ -3,7 +3,7 @@ // using Microsoft.FeatureManagement; using Microsoft.FeatureManagement.FeatureFilters; -namespace ParameterObjectConsoleApp +namespace ParametersObjectConsoleApp { /// /// A custom feature definition provider that supplies targeting filter settings diff --git a/examples/ParameterObjectConsoleApp/ParameterObjectConsoleApp.csproj b/examples/ParametersObjectConsoleApp/ParametersObjectConsoleApp.csproj similarity index 55% rename from examples/ParameterObjectConsoleApp/ParameterObjectConsoleApp.csproj rename to examples/ParametersObjectConsoleApp/ParametersObjectConsoleApp.csproj index d78a4b80..7d1a899b 100644 --- a/examples/ParameterObjectConsoleApp/ParameterObjectConsoleApp.csproj +++ b/examples/ParametersObjectConsoleApp/ParametersObjectConsoleApp.csproj @@ -6,12 +6,6 @@ enable - - - - - - diff --git a/examples/ParameterObjectConsoleApp/Program.cs b/examples/ParametersObjectConsoleApp/Program.cs similarity index 97% rename from examples/ParameterObjectConsoleApp/Program.cs rename to examples/ParametersObjectConsoleApp/Program.cs index bcceb259..c80a36bf 100644 --- a/examples/ParameterObjectConsoleApp/Program.cs +++ b/examples/ParametersObjectConsoleApp/Program.cs @@ -3,7 +3,7 @@ // using Microsoft.FeatureManagement; using Microsoft.FeatureManagement.FeatureFilters; -using ParameterObjectConsoleApp; +using ParametersObjectConsoleApp; // // Create a feature manager using a custom definition provider diff --git a/examples/ParameterObjectConsoleApp/README.md b/examples/ParametersObjectConsoleApp/README.md similarity index 91% rename from examples/ParameterObjectConsoleApp/README.md rename to examples/ParametersObjectConsoleApp/README.md index b6405328..81845aac 100644 --- a/examples/ParameterObjectConsoleApp/README.md +++ b/examples/ParametersObjectConsoleApp/README.md @@ -29,5 +29,5 @@ This eliminates the need for verbose `IConfiguration` construction with magic st ## Running ``` -dotnet run +dotnet run --project examples/ParametersObjectConsoleApp/ParametersObjectConsoleApp.csproj ```