You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -96,7 +97,7 @@ The feature management library supports appsettings.json as a feature flag sourc
96
97
97
98
The `FeatureManagement` section of the json document is used by convention to load feature flag settings. In the section above, we see that we have provided three different features. Features define their feature filters using the `EnabledFor` property. In the feature filters for `FeatureT` we see `AlwaysOn`. This feature filter is built-in and if specified will always enable the feature. The `AlwaysOn` feature filter does not require any configuration, so it only has the `Name` property. `FeatureU` has no filters in its `EnabledFor` property and thus will never be enabled. Any functionality that relies on this feature being enabled will not be accessible as long as the feature filters remain empty. However, as soon as a feature filter is added that enables the feature it can begin working. `FeatureV` specifies a feature filter named `TimeWindow`. This is an example of a configurable feature filter. We can see in the example that the filter has a `Parameters` property. This is used to configure the filter. In this case, the start and end times for the feature to be active are configured.
98
99
99
-
The detailed schema of the `FeatureManagement` section can be found [here](./schemas/FeatureManagement.Dotnet.v1.0.0.schema.json).
100
+
The detailed schema of the `FeatureManagement` section can be found [here](./schemas/FeatureManagement.Dotnet.v2.0.0.schema.json).
100
101
101
102
**Advanced:** The usage of colon ':' in feature flag names is forbidden.
102
103
@@ -199,6 +200,36 @@ The feature management library also supports the usage of the [`Microsoft Featur
199
200
200
201
**Note:** If the `feature_management` section can be found in the configuration, the `FeatureManagement` section will be ignored.
201
202
203
+
#### Microsoft Feature Management Schema
204
+
205
+
The feature management library also supports the usage of the [`Microsoft Feature Management schema`](https://github.com/Azure/AppConfiguration/blob/main/docs/FeatureManagement/FeatureManagement.v1.0.0.schema.json) to declare feature flags. This schema is language agnostic in origin and is supported by all Microsoft feature management libraries.
206
+
207
+
```JavaScript
208
+
{
209
+
"feature_management": {
210
+
"feature_flags": [
211
+
{
212
+
"id":"FeatureT",
213
+
"enabled":true,
214
+
"conditions": {
215
+
"client_filters": [
216
+
{
217
+
"name":"Microsoft.TimeWindow",
218
+
"parameters": {
219
+
"Start":"Mon, 01 May 2023 13:59:59 GMT",
220
+
"End":"Sat, 01 July 2023 00:00:00 GMT"
221
+
}
222
+
}
223
+
]
224
+
}
225
+
}
226
+
]
227
+
}
228
+
}
229
+
```
230
+
231
+
**Note:** If the `feature_management` section can be found in the configuration, the `FeatureManagement` section will be ignored.
232
+
202
233
## Consumption
203
234
204
235
The basic form of feature management is checking if a feature flag is enabled and then performing actions based on the result. This is done through the `IFeatureManager`'s `IsEnabledAsync` method.
The variant returned is dependent on the user currently being evaluated, and that information is obtained from an instance of `TargetingContext`. This context can either be passed in when calling `GetVariantAsync` or it can be automatically retrieved from an implementation of [`ITargetingContextAccessor`](#itargetingcontextaccessor) if one is registered.
786
817
787
-
### Defining Variants
818
+
### Variant Feature Flag Declaration
819
+
820
+
Compared to normal feature flags, variant feature flags have two additional properties: `Variants` and `Allocation`. The `Variants` property is an array that contains the variants defined for this feature. The `Allocation` property defines how these variants should be allocated for the feature. Just like declaring normal feature flags, you can set up variant feature flags in a json file. Here is an example of a variant feature flag.
821
+
822
+
```javascript
823
+
824
+
{
825
+
"FeatureManagement":
826
+
{
827
+
"MyVariantFeatureFlag":
828
+
{
829
+
"Allocation": {
830
+
"DefaultWhenEnabled":"Small",
831
+
"Group": [
832
+
{
833
+
"Variant":"Big",
834
+
"Groups": [
835
+
"Ring1"
836
+
]
837
+
}
838
+
]
839
+
},
840
+
"Variants": [
841
+
{
842
+
"Name":"Big"
843
+
},
844
+
{
845
+
"Name":"Small"
846
+
}
847
+
],
848
+
"EnabledFor": [
849
+
{
850
+
"Name":"AlwaysOn"
851
+
}
852
+
]
853
+
}
854
+
}
855
+
}
856
+
857
+
```
858
+
859
+
For more details about how to configure variant feature flags, please see [here](./schemas/FeatureManagement.Dotnet.v2.0.0.schema.json).
860
+
861
+
#### Defining Variants
788
862
789
863
Each variant has two properties: a name and a configuration. The name is used to refer to a specific variant, and the configuration is the value of that variant. The configuration can be set using either the `ConfigurationReference` or `ConfigurationValue` properties. `ConfigurationReference` is a string path that references a section of the current configuration that contains the feature flag declaration. `ConfigurationValue` is an inline configuration that can be a string, number, boolean, or configuration object. If both are specified, `ConfigurationValue` is used. If neither are specified, the returned variant's `Configuration` property will be null.
790
864
791
865
A list of all possible variants is defined for each feature under the `Variants` property.
792
866
793
-
```
867
+
```javascript
794
868
{
795
869
"FeatureManagement":
796
870
{
797
-
"MyFlag":
871
+
"MyVariantFeatureFlag":
798
872
{
799
873
"Variants": [
800
874
{
@@ -815,14 +889,25 @@ A list of all possible variants is defined for each feature under the `Variants`
815
889
]
816
890
}
817
891
}
892
+
893
+
"ShoppingCart": {
894
+
"Big": {
895
+
"Size":600,
896
+
"Color":"green"
897
+
},
898
+
"Small": {
899
+
"Size":300,
900
+
"Color":"gray"
901
+
}
902
+
}
818
903
}
819
904
```
820
905
821
-
### Allocating Variants
906
+
####Allocating Variants
822
907
823
908
The process of allocating a feature's variants is determined by the `Allocation` property of the feature.
824
909
825
-
```
910
+
```javascript
826
911
"Allocation": {
827
912
"DefaultWhenEnabled":"Small",
828
913
"DefaultWhenDisabled":"Small",
@@ -870,7 +955,7 @@ The `Allocation` setting of a feature flag has the following properties:
870
955
|`DefaultWhenDisabled`| Specifies which variant should be used when a variant is requested while the feature is considered disabled. |
871
956
|`DefaultWhenEnabled`| Specifies which variant should be used when a variant is requested while the feature is considered enabled and no other variant was assigned to the user. |
872
957
|`User`| Specifies a variant and a list of users to whom that variant should be assigned. |
873
-
|`Group`| Specifies a variant and a list of groups the current user has to be in for that variant to be assigned. |
958
+
|`Group`| Specifies a variant and a list of groups. The variant will be assigned if the user is in at least one of the groups. |
874
959
|`Percentile`| Specifies a variant and a percentage range the user's calculated percentage has to fit into for that variant to be assigned. |
875
960
|`Seed`| The value which percentage calculations for `Percentile` are based on. The percentage calculation for a specific user will be the same across all features if the same `Seed` value is used. If no `Seed` is specified, then a default seed is created based on the feature name. |
876
961
@@ -880,40 +965,94 @@ If the feature is enabled, the feature manager will check the `User`, `Group`, a
880
965
881
966
Allocation logic is similar to the [Microsoft.Targeting](./README.md#MicrosoftTargeting) feature filter, but there are some parameters that are present in targeting that aren't in allocation, and vice versa. The outcomes of targeting and allocation are not related.
882
967
968
+
**Note:** To allow allocating feature variants, you need to register `ITargetingContextAccessor`. This can be done by calling the `WithTargeting<T>` method.
969
+
883
970
### Overriding Enabled State with a Variant
884
971
885
972
You can use variants to override the enabled state of a feature flag. This gives variants an opportunity to extend the evaluation of a feature flag. If a caller is checking whether a flag that has variants is enabled, the feature manager will check if the variant assigned to the current user is set up to override the result. This is done using the optional variant property `StatusOverride`. By default, this property is set to `None`, which means the variant doesn't affect whether the flag is considered enabled or disabled. Setting `StatusOverride` to `Enabled` allows the variant, when chosen, to override a flag to be enabled. Setting `StatusOverride` to `Disabled` provides the opposite functionality, therefore disabling the flag when the variant is chosen. A feature with a `Status` of `Disabled` cannot be overridden.
886
973
887
974
If you are using a feature flag with binary variants, the `StatusOverride` property can be very helpful. It allows you to continue using APIs like `IsEnabledAsync` and `FeatureGateAttribute` in your application, all while benefiting from the new features that come with variants, such as percentile allocation and seed.
888
975
889
-
```
976
+
```javascript
890
977
"Allocation": {
891
-
"Percentile": [{
892
-
"Variant": "On",
893
-
"From": 10,
894
-
"To": 20
895
-
}],
978
+
"Percentile": [
979
+
{
980
+
"Variant":"On",
981
+
"From":10,
982
+
"To":20
983
+
}
984
+
],
896
985
"DefaultWhenEnabled":"Off",
897
986
"Seed":"Enhanced-Feature-Group"
898
987
},
899
988
"Variants": [
900
-
{
989
+
{
901
990
"Name":"On"
902
991
},
903
-
{
992
+
{
904
993
"Name":"Off",
905
994
"StatusOverride":"Disabled"
906
-
}
995
+
}
907
996
],
908
-
"EnabledFor": [
909
-
{
910
-
"Name": "AlwaysOn"
911
-
}
912
-
]
997
+
"EnabledFor": [
998
+
{
999
+
"Name":"AlwaysOn"
1000
+
}
1001
+
]
913
1002
```
914
1003
915
1004
In the above example, the feature is enabled by the `AlwaysOn` filter. If the current user is in the calculated percentile range of 10 to 20, then the `On` variant is returned. Otherwise, the `Off` variant is returned and because `StatusOverride` is equal to `Disabled`, the feature will now be considered disabled.
916
1005
1006
+
### Variants in Dependency Injection
1007
+
1008
+
Variant feature flags can be used in conjunction with dependency injection to surface different implementations of a service for different users. This is accomplished through the use of the `IVariantServiceProvider<TService>` interface.
In the snippet above, the `IVariantServiceProvider<IAlgorithm>` will retrieve an implementation of `IAlgorithm` from the dependency injection container. The chosen implementation is dependent upon:
1018
+
* The feature flag that the `IAlgorithm` service was registered with.
1019
+
* The allocated variant for that feature.
1020
+
1021
+
The `IVariantServiceProvider<T>` is made available to the application by calling `IFeatureManagementBuilder.WithVariantService<T>(string featureName)`. See below for an example.
The call above makes `IVariantServiceProvider<IAlgorithm>` available in the service collection. Implementation(s) of `IAlgorithm` must be added separately via an add method such as `services.AddSingleton<IAlgorithm, SomeImplementation>()`. The implementation of `IAlgorithm` that the `IVariantServiceProvider` uses depends on the `ForecastAlgorithm` variant feature flag. If no implementation of `IAlgorithm` is added to the service collection, then the `IVariantServiceProvider<IAlgorithm>.GetServiceAsync()` will return a task with a *null* result.
1029
+
1030
+
```javascript
1031
+
{
1032
+
// The example variant feature flag
1033
+
"ForecastAlgorithm": {
1034
+
"Variants": [
1035
+
{
1036
+
"Name":"AlgorithmBeta"
1037
+
},
1038
+
...
1039
+
]
1040
+
}
1041
+
}
1042
+
```
1043
+
1044
+
#### Variant Service Alias Attribute
1045
+
1046
+
```C#
1047
+
[VariantServiceAlias("Beta")]
1048
+
publicclassAlgorithmBeta : IAlgorithm
1049
+
{
1050
+
...
1051
+
}
1052
+
```
1053
+
1054
+
The variant service provider will use the type names of implementations to match the allocated variant. If a variant service is decorated with the `VariantServiceAliasAttribute`, the name declared in this attribute should be used in configuration to reference this variant service.
1055
+
917
1056
## Telemetry
918
1057
919
1058
When a feature flag change is deployed, it is often important to analyze its effect on an application. For example, here are a few questions that may arise:
@@ -931,7 +1070,7 @@ By default, feature flags will not have telemetry emitted. To publish telemetry
931
1070
932
1071
For flags defined in `appsettings.json`, that is done by using the `Telemetry` property on feature flags.
0 commit comments