Skip to content

Commit 7050fa0

Browse files
authored
Merge pull request #500 from microsoft/preview
Merge preview into main
2 parents c9b9fb6 + 8603981 commit 7050fa0

File tree

227 files changed

+154948
-1985
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

227 files changed

+154948
-1985
lines changed

Microsoft.FeatureManagement.sln

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,21 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Examples", "Examples", "{FB
1515
EndProject
1616
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tests.FeatureManagement.AspNetCore", "tests\Tests.FeatureManagement.AspNetCore\Tests.FeatureManagement.AspNetCore.csproj", "{FC0DC3E2-5646-4AEC-A7DB-2D6167BC3BB4}"
1717
EndProject
18-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleApp", "examples\ConsoleApp\ConsoleApp.csproj", "{7B98D293-F270-423E-A9A6-0D388E903AE9}"
18+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsoleApp", "examples\ConsoleApp\ConsoleApp.csproj", "{7B98D293-F270-423E-A9A6-0D388E903AE9}"
1919
EndProject
20-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RazorPages", "examples\RazorPages\RazorPages.csproj", "{36DBB413-D9CA-4C56-AE5B-EAEA4C344DB3}"
20+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RazorPages", "examples\RazorPages\RazorPages.csproj", "{36DBB413-D9CA-4C56-AE5B-EAEA4C344DB3}"
2121
EndProject
22-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FeatureFlagDemo", "examples\FeatureFlagDemo\FeatureFlagDemo.csproj", "{DACAB624-4611-42E8-844C-529F93A54980}"
22+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FeatureFlagDemo", "examples\FeatureFlagDemo\FeatureFlagDemo.csproj", "{DACAB624-4611-42E8-844C-529F93A54980}"
2323
EndProject
24-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TargetingConsoleApp", "examples\TargetingConsoleApp\TargetingConsoleApp.csproj", "{283D3EBB-4716-4F1D-BA51-A435F7E2AB82}"
24+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TargetingConsoleApp", "examples\TargetingConsoleApp\TargetingConsoleApp.csproj", "{283D3EBB-4716-4F1D-BA51-A435F7E2AB82}"
2525
EndProject
26-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BlazorServerApp", "examples\BlazorServerApp\BlazorServerApp.csproj", "{12BAB5A6-4EEB-4917-B5D9-4AFB6253008E}"
26+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.FeatureManagement.Telemetry.ApplicationInsights", "src\Microsoft.FeatureManagement.Telemetry.ApplicationInsights\Microsoft.FeatureManagement.Telemetry.ApplicationInsights.csproj", "{7964DC66-B2D3-412D-B18A-86D1E07D149D}"
27+
EndProject
28+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VariantAndTelemetryDemo", "examples\VariantAndTelemetryDemo\VariantAndTelemetryDemo.csproj", "{1502529E-47E9-4306-98C4-BF6CF7C7C275}"
29+
EndProject
30+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BlazorServerApp", "examples\BlazorServerApp\BlazorServerApp.csproj", "{12BAB5A6-4EEB-4917-B5D9-4AFB6253008E}"
31+
EndProject
32+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VariantServiceDemo", "examples\VariantServiceDemo\VariantServiceDemo.csproj", "{E8E17CB9-434E-4386-BF96-FA53BBFDCD6F}"
2733
EndProject
2834
Global
2935
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -63,10 +69,22 @@ Global
6369
{283D3EBB-4716-4F1D-BA51-A435F7E2AB82}.Debug|Any CPU.Build.0 = Debug|Any CPU
6470
{283D3EBB-4716-4F1D-BA51-A435F7E2AB82}.Release|Any CPU.ActiveCfg = Release|Any CPU
6571
{283D3EBB-4716-4F1D-BA51-A435F7E2AB82}.Release|Any CPU.Build.0 = Release|Any CPU
72+
{7964DC66-B2D3-412D-B18A-86D1E07D149D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
73+
{7964DC66-B2D3-412D-B18A-86D1E07D149D}.Debug|Any CPU.Build.0 = Debug|Any CPU
74+
{7964DC66-B2D3-412D-B18A-86D1E07D149D}.Release|Any CPU.ActiveCfg = Release|Any CPU
75+
{7964DC66-B2D3-412D-B18A-86D1E07D149D}.Release|Any CPU.Build.0 = Release|Any CPU
76+
{1502529E-47E9-4306-98C4-BF6CF7C7C275}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
77+
{1502529E-47E9-4306-98C4-BF6CF7C7C275}.Debug|Any CPU.Build.0 = Debug|Any CPU
78+
{1502529E-47E9-4306-98C4-BF6CF7C7C275}.Release|Any CPU.ActiveCfg = Release|Any CPU
79+
{1502529E-47E9-4306-98C4-BF6CF7C7C275}.Release|Any CPU.Build.0 = Release|Any CPU
6680
{12BAB5A6-4EEB-4917-B5D9-4AFB6253008E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
6781
{12BAB5A6-4EEB-4917-B5D9-4AFB6253008E}.Debug|Any CPU.Build.0 = Debug|Any CPU
6882
{12BAB5A6-4EEB-4917-B5D9-4AFB6253008E}.Release|Any CPU.ActiveCfg = Release|Any CPU
6983
{12BAB5A6-4EEB-4917-B5D9-4AFB6253008E}.Release|Any CPU.Build.0 = Release|Any CPU
84+
{E8E17CB9-434E-4386-BF96-FA53BBFDCD6F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
85+
{E8E17CB9-434E-4386-BF96-FA53BBFDCD6F}.Debug|Any CPU.Build.0 = Debug|Any CPU
86+
{E8E17CB9-434E-4386-BF96-FA53BBFDCD6F}.Release|Any CPU.ActiveCfg = Release|Any CPU
87+
{E8E17CB9-434E-4386-BF96-FA53BBFDCD6F}.Release|Any CPU.Build.0 = Release|Any CPU
7088
EndGlobalSection
7189
GlobalSection(SolutionProperties) = preSolution
7290
HideSolutionNode = FALSE
@@ -78,7 +96,9 @@ Global
7896
{36DBB413-D9CA-4C56-AE5B-EAEA4C344DB3} = {FB5C34DF-695C-4DF9-8AED-B3EA2516EA72}
7997
{DACAB624-4611-42E8-844C-529F93A54980} = {FB5C34DF-695C-4DF9-8AED-B3EA2516EA72}
8098
{283D3EBB-4716-4F1D-BA51-A435F7E2AB82} = {FB5C34DF-695C-4DF9-8AED-B3EA2516EA72}
99+
{1502529E-47E9-4306-98C4-BF6CF7C7C275} = {FB5C34DF-695C-4DF9-8AED-B3EA2516EA72}
81100
{12BAB5A6-4EEB-4917-B5D9-4AFB6253008E} = {FB5C34DF-695C-4DF9-8AED-B3EA2516EA72}
101+
{E8E17CB9-434E-4386-BF96-FA53BBFDCD6F} = {FB5C34DF-695C-4DF9-8AED-B3EA2516EA72}
82102
EndGlobalSection
83103
GlobalSection(ExtensibilityGlobals) = postSolution
84104
SolutionGuid = {84DA6C54-F140-4518-A1B4-E4CF42117FBD}

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ Feature management provides a way to develop and expose application functionalit
2020
* [ASP.NET Core Web App (Razor Page)](./examples/RazorPages)
2121
* [ASP.NET Core Web App (MVC)](./examples/FeatureFlagDemo)
2222
* [Blazor Server App](./examples/BlazorServerApp)
23+
* [ASP.NET Core Web App with Variants and Telemetry](./examples/VariantAndTelemetryDemo)
24+
* [ASP.NET Core Web App with Variant Service](./examples/VariantServiceDemo)
2325

2426
## Contributing
2527

examples/BlazorServerApp/BlazorServerApp.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
<Project Sdk="Microsoft.NET.Sdk.Web">
22

33
<PropertyGroup>
4-
<TargetFramework>net6.0</TargetFramework>
4+
<TargetFramework>net8.0</TargetFramework>
55
<ImplicitUsings>enable</ImplicitUsings>
66
</PropertyGroup>
7-
7+
88
<ItemGroup>
99
<ProjectReference Include="..\..\src\Microsoft.FeatureManagement\Microsoft.FeatureManagement.csproj" />
1010
</ItemGroup>

examples/BlazorServerApp/README.md

Lines changed: 32 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -17,34 +17,44 @@ This app demonstrates how to use the Feature Management library in Blazor apps.
1717
This app uses two feature flags: "BrowserEnhancement" and "Beta".
1818

1919
``` json
20-
"FeatureManagement": {
21-
"BrowserEnhancement": {
22-
"EnabledFor": [
23-
{
24-
"Name": "Browser",
25-
"Parameters": {
26-
"AllowedBrowsers": [ "Edge" ]
27-
}
20+
"feature_management": {
21+
"feature_flags": [
22+
{
23+
"id": "BrowserEnhancement",
24+
"enabled": true,
25+
"conditions": {
26+
"client_filters": [
27+
{
28+
"name": "Browser",
29+
"parameters": {
30+
"AllowedBrowsers": [ "Edge" ]
2831
}
32+
}
2933
]
34+
}
3035
},
31-
"Beta": {
32-
"EnabledFor": [
33-
{
34-
"Name": "Targeting",
35-
"Parameters": {
36-
"Audience": {
37-
"DefaultRolloutPercentage": 50,
38-
"Exclusion": {
39-
"Groups": [
40-
"Guests"
41-
]
42-
}
43-
}
36+
{
37+
"id": "Beta",
38+
"enabled": true,
39+
"conditions": {
40+
"client_filters": [
41+
{
42+
"name": "Targeting",
43+
"parameters": {
44+
"Audience": {
45+
"DefaultRolloutPercentage": 50,
46+
"Exclusion": {
47+
"Groups": [
48+
"Guests"
49+
]
4450
}
51+
}
4552
}
53+
}
4654
]
55+
}
4756
}
57+
]
4858
}
4959
```
5060

@@ -65,6 +75,7 @@ This app uses [cookie authentication](https://learn.microsoft.com/en-us/aspnet/c
6575
Rather than `HttpContext`, the [`AuthenticationStateProvider`](https://learn.microsoft.com/en-us/aspnet/core/blazor/security/?view=aspnetcore-8.0#authenticationstateprovider-service) service is used to obtain the user authentication state information for setting targeting context. The details can be found in the [`MyTargetingContextAccessor`](./MyTargetingContextAccessor.cs).
6676

6777
## Service Registration
78+
6879
Blazor applications like this one typically pull ambient contextual data from scoped services. For example, the `UserAgentContext`, `AuthenticationStateProvider` and `ITargetingContextAccessor` are all scoped services. This pattern *breaks* if the feature management services are added as singleton, which is typical in non-blazor web apps.
6980

7081
In Blazor, *avoid* the following

examples/BlazorServerApp/appsettings.json

Lines changed: 34 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,33 +6,43 @@
66
}
77
},
88
"AllowedHosts": "*",
9-
"FeatureManagement": {
10-
"BrowserEnhancement": {
11-
"EnabledFor": [
12-
{
13-
"Name": "Browser",
14-
"Parameters": {
15-
"AllowedBrowsers": [ "Edge" ]
16-
}
9+
"feature_management": {
10+
"feature_flags": [
11+
{
12+
"id": "BrowserEnhancement",
13+
"enabled": true,
14+
"conditions": {
15+
"client_filters": [
16+
{
17+
"name": "Browser",
18+
"parameters": {
19+
"AllowedBrowsers": [ "Edge" ]
20+
}
21+
}
22+
]
1723
}
18-
]
19-
},
20-
"Beta": {
21-
"EnabledFor": [
22-
{
23-
"Name": "Targeting",
24-
"Parameters": {
25-
"Audience": {
26-
"DefaultRolloutPercentage": 50,
27-
"Exclusion": {
28-
"Groups": [
29-
"Guests"
30-
]
24+
},
25+
{
26+
"id": "Beta",
27+
"enabled": true,
28+
"conditions": {
29+
"client_filters": [
30+
{
31+
"name": "Targeting",
32+
"parameters": {
33+
"Audience": {
34+
"DefaultRolloutPercentage": 50,
35+
"Exclusion": {
36+
"Groups": [
37+
"Guests"
38+
]
39+
}
40+
}
3141
}
3242
}
33-
}
43+
]
3444
}
35-
]
36-
}
45+
}
46+
]
3747
}
3848
}

examples/ConsoleApp/ConsoleApp.csproj

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@
22

33
<PropertyGroup>
44
<OutputType>Exe</OutputType>
5-
<TargetFramework>net6.0</TargetFramework>
5+
<TargetFramework>net8.0</TargetFramework>
66
<ImplicitUsings>enable</ImplicitUsings>
77
</PropertyGroup>
88

99
<ItemGroup>
10-
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0" />
11-
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" />
10+
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
11+
<PackageReference Include="System.Text.Json" Version="8.0.4" />
12+
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
1213
</ItemGroup>
1314

1415
<ItemGroup>
@@ -20,5 +21,5 @@
2021
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
2122
</None>
2223
</ItemGroup>
23-
24+
2425
</Project>
Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,20 @@
11
{
2-
"FeatureManagement": {
3-
"Beta": {
4-
"EnabledFor": [
5-
{
6-
"Name": "AccountId",
7-
"Parameters": {
8-
"AllowedAccounts": [ "abcdefghijklmnopqrstuvwxyz" ]
9-
}
2+
"feature_management": {
3+
"feature_flags": [
4+
{
5+
"id": "Beta",
6+
"enabled": true,
7+
"conditions": {
8+
"client_filters": [
9+
{
10+
"name": "AccountId",
11+
"parameters": {
12+
"AllowedAccounts": [ "abcdefghijklmnopqrstuvwxyz" ]
13+
}
14+
}
15+
]
1016
}
11-
]
12-
}
17+
}
18+
]
1319
}
1420
}

examples/FeatureFlagDemo/Authentication/QueryStringAuthenticationHandler.cs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,8 @@ namespace FeatureFlagDemo.Authentication
1515
///
1616
/// To assign a user, use the following query string structure "?username=JohnDoe&groups=MyGroup1,MyGroup2"
1717
/// </summary>
18-
class QueryStringAuthenticationHandler : AuthenticationHandler<QueryStringAuthenticationOptions>
18+
class QueryStringAuthenticationHandler(IOptionsMonitor<QueryStringAuthenticationOptions> options, ILoggerFactory logger, UrlEncoder encoder) : AuthenticationHandler<QueryStringAuthenticationOptions>(options, logger, encoder)
1919
{
20-
public QueryStringAuthenticationHandler(IOptionsMonitor<QueryStringAuthenticationOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock)
21-
: base(options, logger, encoder, clock)
22-
{
23-
}
24-
2520
protected override Task<AuthenticateResult> HandleAuthenticateAsync()
2621
{
2722
var identity = new ClaimsIdentity();
@@ -32,9 +27,9 @@ protected override Task<AuthenticateResult> HandleAuthenticateAsync()
3227
{
3328
string username = value.First();
3429

35-
identity.AddClaim(new Claim(System.Security.Claims.ClaimTypes.Name, username));
30+
identity.AddClaim(new Claim(ClaimTypes.Name, username));
3631

37-
Logger.LogInformation($"Assigning the username '{username}' to the request.");
32+
Logger.LogInformation("Assigning the username {username} to the request.", username);
3833
}
3934

4035
//
@@ -48,7 +43,7 @@ protected override Task<AuthenticateResult> HandleAuthenticateAsync()
4843
identity.AddClaim(new Claim(ClaimTypes.Role, group));
4944
}
5045

51-
Logger.LogInformation($"Assigning the following groups '{string.Join(", ", groups)}' to the request.");
46+
Logger.LogInformation("Assigning the following groups '{groups}' to the request.", string.Join(", ", groups));
5247
}
5348

5449
//

examples/FeatureFlagDemo/FeatureFlagDemo.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
<Project Sdk="Microsoft.NET.Sdk.Web">
22

33
<PropertyGroup>
4-
<TargetFramework>net6.0</TargetFramework>
4+
<TargetFramework>net8.0</TargetFramework>
55
<ImplicitUsings>enable</ImplicitUsings>
66
</PropertyGroup>
77

88
<ItemGroup>
9-
<PackageReference Include="Microsoft.Azure.AppConfiguration.AspNetCore" Version="3.0.1" />
9+
<PackageReference Include="Microsoft.Azure.AppConfiguration.AspNetCore" Version="7.3.0" />
1010
</ItemGroup>
1111

1212
<ItemGroup>

0 commit comments

Comments
 (0)