From 319fc2b4dad4fab079348577ea0eaf898aea3745 Mon Sep 17 00:00:00 2001
From: Zhiyuan Liang <141655842+zhiyuanliang-ms@users.noreply.github.com>
Date: Fri, 21 Jun 2024 07:08:09 +0800
Subject: [PATCH 1/6] version bump 3.4.0 (#465)
---
.../Microsoft.FeatureManagement.AspNetCore.csproj | 4 ++--
.../Microsoft.FeatureManagement.csproj | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/Microsoft.FeatureManagement.AspNetCore/Microsoft.FeatureManagement.AspNetCore.csproj b/src/Microsoft.FeatureManagement.AspNetCore/Microsoft.FeatureManagement.AspNetCore.csproj
index 94d93f15..73ab8dfa 100644
--- a/src/Microsoft.FeatureManagement.AspNetCore/Microsoft.FeatureManagement.AspNetCore.csproj
+++ b/src/Microsoft.FeatureManagement.AspNetCore/Microsoft.FeatureManagement.AspNetCore.csproj
@@ -4,8 +4,8 @@
3
- 3
- 1
+ 4
+ 0
diff --git a/src/Microsoft.FeatureManagement/Microsoft.FeatureManagement.csproj b/src/Microsoft.FeatureManagement/Microsoft.FeatureManagement.csproj
index ea79919a..39cdd2e6 100644
--- a/src/Microsoft.FeatureManagement/Microsoft.FeatureManagement.csproj
+++ b/src/Microsoft.FeatureManagement/Microsoft.FeatureManagement.csproj
@@ -4,8 +4,8 @@
3
- 3
- 1
+ 4
+ 0
From 990d8fab5b1614a902045ca4ef34ff3afafecf34 Mon Sep 17 00:00:00 2001
From: Zhiyuan Liang <141655842+zhiyuanliang-ms@users.noreply.github.com>
Date: Tue, 25 Jun 2024 12:53:20 +0800
Subject: [PATCH 2/6] re-add nuget package in readme (#469)
---
README.md | 3 +++
1 file changed, 3 insertions(+)
diff --git a/README.md b/README.md
index 7a6ff819..415773b6 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,8 @@
# .NET Feature Management
+[](https://www.nuget.org/packages/Microsoft.FeatureManagement)
+[](https://www.nuget.org/packages/Microsoft.FeatureManagement.AspNetCore)
+
Feature management provides a way to develop and expose application functionality based on features. Many applications have special requirements when a new feature is developed such as when the feature should be enabled and under what conditions. This library provides a way to define these relationships, and also integrates into common .NET code patterns to make exposing these features possible.
## Get started
From 138a4e24936d3e3d4a63ead98eb0ae03db606efc Mon Sep 17 00:00:00 2001
From: Ross Grambo
Date: Mon, 15 Jul 2024 11:33:33 -0700
Subject: [PATCH 3/6] Adds Default Targeting Accessor and extension method
WithTargeting (#466)
* Adds default targeting accessor and extension method WithTargeting variation for ASP.NET
* Updates accessor to internal
* Forced query evaluation
* Updated description of .WithTargeting extension
---
.../QueryStringAuthenticationHandler.cs | 2 +-
examples/FeatureFlagDemo/ClaimTypes.cs | 10 ---
.../HttpContextTargetingContextAccessor.cs | 66 -----------------
examples/FeatureFlagDemo/Startup.cs | 2 +-
...tCoreFeatureManagementBuilderExtensions.cs | 26 +++++++
.../DefaultHttpTargetingContextAccessor.cs | 74 +++++++++++++++++++
6 files changed, 102 insertions(+), 78 deletions(-)
delete mode 100644 examples/FeatureFlagDemo/ClaimTypes.cs
delete mode 100644 examples/FeatureFlagDemo/HttpContextTargetingContextAccessor.cs
create mode 100644 src/Microsoft.FeatureManagement.AspNetCore/DefaultHttpTargetingContextAccessor.cs
diff --git a/examples/FeatureFlagDemo/Authentication/QueryStringAuthenticationHandler.cs b/examples/FeatureFlagDemo/Authentication/QueryStringAuthenticationHandler.cs
index 073b7452..0049cca3 100644
--- a/examples/FeatureFlagDemo/Authentication/QueryStringAuthenticationHandler.cs
+++ b/examples/FeatureFlagDemo/Authentication/QueryStringAuthenticationHandler.cs
@@ -49,7 +49,7 @@ protected override Task HandleAuthenticateAsync()
foreach (string group in groups)
{
- identity.AddClaim(new Claim(ClaimTypes.GroupName, group));
+ identity.AddClaim(new Claim(ClaimTypes.Role, group));
}
Logger.LogInformation($"Assigning the following groups '{string.Join(", ", groups)}' to the request.");
diff --git a/examples/FeatureFlagDemo/ClaimTypes.cs b/examples/FeatureFlagDemo/ClaimTypes.cs
deleted file mode 100644
index b24dfd20..00000000
--- a/examples/FeatureFlagDemo/ClaimTypes.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT license.
-//
-namespace FeatureFlagDemo
-{
- static class ClaimTypes
- {
- public static string GroupName = "http://schemas.featureflagdemo.featuremanagement.microsoft.com/claims/groupname";
- }
-}
diff --git a/examples/FeatureFlagDemo/HttpContextTargetingContextAccessor.cs b/examples/FeatureFlagDemo/HttpContextTargetingContextAccessor.cs
deleted file mode 100644
index 9f9c8964..00000000
--- a/examples/FeatureFlagDemo/HttpContextTargetingContextAccessor.cs
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT license.
-//
-using Microsoft.AspNetCore.Http;
-using Microsoft.FeatureManagement.FeatureFilters;
-using System;
-using System.Collections.Generic;
-using System.Security.Claims;
-using System.Threading.Tasks;
-
-namespace FeatureFlagDemo
-{
- ///
- /// Provides an implementation of that creates a targeting context using info from the current HTTP request.
- ///
- public class HttpContextTargetingContextAccessor : ITargetingContextAccessor
- {
- private const string TargetingContextLookup = "HttpContextTargetingContextAccessor.TargetingContext";
- private readonly IHttpContextAccessor _httpContextAccessor;
-
- public HttpContextTargetingContextAccessor(IHttpContextAccessor httpContextAccessor)
- {
- _httpContextAccessor = httpContextAccessor ?? throw new ArgumentNullException(nameof(httpContextAccessor));
- }
-
- public ValueTask GetContextAsync()
- {
- HttpContext httpContext = _httpContextAccessor.HttpContext;
-
- //
- // Try cache lookup
- if (httpContext.Items.TryGetValue(TargetingContextLookup, out object value))
- {
- return new ValueTask((TargetingContext)value);
- }
-
- ClaimsPrincipal user = httpContext.User;
-
- List groups = new List();
-
- //
- // This application expects groups to be specified in the user's claims
- foreach (Claim claim in user.Claims)
- {
- if (claim.Type == ClaimTypes.GroupName)
- {
- groups.Add(claim.Value);
- }
- }
-
- //
- // Build targeting context based off user info
- TargetingContext targetingContext = new TargetingContext
- {
- UserId = user.Identity.Name,
- Groups = groups
- };
-
- //
- // Cache for subsequent lookup
- httpContext.Items[TargetingContextLookup] = targetingContext;
-
- return new ValueTask(targetingContext);
- }
- }
-}
diff --git a/examples/FeatureFlagDemo/Startup.cs b/examples/FeatureFlagDemo/Startup.cs
index 4c5722bd..f29f4934 100644
--- a/examples/FeatureFlagDemo/Startup.cs
+++ b/examples/FeatureFlagDemo/Startup.cs
@@ -45,7 +45,7 @@ public void ConfigureServices(IServiceCollection services)
services.AddFeatureManagement()
.AddFeatureFilter()
- .WithTargeting()
+ .WithTargeting()
.UseDisabledFeaturesHandler(new FeatureNotEnabledDisabledHandler());
services.AddMvc(o =>
diff --git a/src/Microsoft.FeatureManagement.AspNetCore/AspNetCoreFeatureManagementBuilderExtensions.cs b/src/Microsoft.FeatureManagement.AspNetCore/AspNetCoreFeatureManagementBuilderExtensions.cs
index 742b942e..9091a4b0 100644
--- a/src/Microsoft.FeatureManagement.AspNetCore/AspNetCoreFeatureManagementBuilderExtensions.cs
+++ b/src/Microsoft.FeatureManagement.AspNetCore/AspNetCoreFeatureManagementBuilderExtensions.cs
@@ -3,9 +3,12 @@
//
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.DependencyInjection.Extensions;
+using Microsoft.FeatureManagement.FeatureFilters;
using Microsoft.FeatureManagement.Mvc;
using System;
using System.Collections.Generic;
+using System.Linq;
namespace Microsoft.FeatureManagement
{
@@ -44,5 +47,28 @@ public static IFeatureManagementBuilder UseDisabledFeaturesHandler(this IFeature
return builder;
}
+
+ ///
+ /// Enables the use of targeting within the application and adds a targeting context accessor that extracts targeting details from a request's HTTP context.
+ ///
+ /// The used to customize feature management functionality.
+ /// A that can be used to customize feature management functionality.
+ public static IFeatureManagementBuilder WithTargeting(this IFeatureManagementBuilder builder)
+ {
+ //
+ // Register the targeting context accessor with the same lifetime as the feature manager
+ if (builder.Services.Any(descriptor => descriptor.ServiceType == typeof(IFeatureManager) && descriptor.Lifetime == ServiceLifetime.Scoped))
+ {
+ builder.Services.TryAddScoped();
+ }
+ else
+ {
+ builder.Services.TryAddSingleton();
+ }
+
+ builder.AddFeatureFilter();
+
+ return builder;
+ }
}
}
diff --git a/src/Microsoft.FeatureManagement.AspNetCore/DefaultHttpTargetingContextAccessor.cs b/src/Microsoft.FeatureManagement.AspNetCore/DefaultHttpTargetingContextAccessor.cs
new file mode 100644
index 00000000..8eb99090
--- /dev/null
+++ b/src/Microsoft.FeatureManagement.AspNetCore/DefaultHttpTargetingContextAccessor.cs
@@ -0,0 +1,74 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+//
+using Microsoft.AspNetCore.Http;
+using Microsoft.FeatureManagement.FeatureFilters;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Security.Claims;
+using System.Threading.Tasks;
+
+namespace Microsoft.FeatureManagement
+{
+ ///
+ /// Provides a default implementation of that creates using info from the current HTTP request.
+ ///
+ internal sealed class DefaultHttpTargetingContextAccessor : ITargetingContextAccessor
+ {
+ ///
+ /// The key used to store and retrieve the from the items.
+ ///
+ private static object _cacheKey = new object();
+
+ private readonly IHttpContextAccessor _httpContextAccessor;
+
+ ///
+ /// Creates an instance of the DefaultHttpTargetingContextAccessor
+ ///
+ public DefaultHttpTargetingContextAccessor(IHttpContextAccessor httpContextAccessor)
+ {
+ _httpContextAccessor = httpContextAccessor ?? throw new ArgumentNullException(nameof(httpContextAccessor));
+ }
+
+ ///
+ /// Gets from the current HTTP request.
+ ///
+ public ValueTask GetContextAsync()
+ {
+ HttpContext httpContext = _httpContextAccessor.HttpContext;
+
+ //
+ // Try cache lookup
+ if (httpContext.Items.TryGetValue(_cacheKey, out object value))
+ {
+ return new ValueTask((TargetingContext)value);
+ }
+
+ //
+ // Treat user identity name as user id
+ ClaimsPrincipal user = httpContext.User;
+
+ string userId = user?.Identity?.Name;
+
+ //
+ // Treat claims of type Role as groups
+ IEnumerable groups = httpContext.User.Claims
+ .Where(c => c.Type == ClaimTypes.Role)
+ .Select(c => c.Value)
+ .ToList();
+
+ TargetingContext targetingContext = new TargetingContext
+ {
+ UserId = userId,
+ Groups = groups
+ };
+
+ //
+ // Cache for subsequent lookup
+ httpContext.Items[_cacheKey] = targetingContext;
+
+ return new ValueTask(targetingContext);
+ }
+ }
+}
\ No newline at end of file
From 9ae3c19f669b0a12a80286ac5d7070bd3c97ab6e Mon Sep 17 00:00:00 2001
From: Zhiyuan Liang <141655842+zhiyuanliang-ms@users.noreply.github.com>
Date: Wed, 17 Jul 2024 13:08:38 +0800
Subject: [PATCH 4/6] Add linting rule (#472)
* remove unused package
* fix format issue
* enforce format check
---
.editorconfig | 39 +++++++++++++++++++
.../BlazorServerApp/BlazorServerApp.csproj | 4 ++
examples/BlazorServerApp/BrowserFilter.cs | 2 +-
examples/BlazorServerApp/Program.cs | 2 +-
examples/ConsoleApp/AccountServiceContext.cs | 2 +-
examples/ConsoleApp/ConsoleApp.csproj | 4 ++
examples/ConsoleApp/Program.cs | 7 +++-
.../QueryStringAuthenticationHandler.cs | 4 --
examples/FeatureFlagDemo/BrowserFilter.cs | 5 ---
.../FeatureFlagDemo/BrowserFilterSettings.cs | 2 -
.../Controllers/BetaController.cs | 2 +-
.../Controllers/HomeController.cs | 6 +--
.../FeatureFlagDemo/FeatureFlagDemo.csproj | 6 ++-
.../FeatureFlagDemo/Models/ErrorViewModel.cs | 4 +-
examples/FeatureFlagDemo/SuperUserFilter.cs | 1 -
.../FeatureFlagDemo/ThirdPartyActionFilter.cs | 2 -
.../FeatureFlagDemo/ThirdPartyMiddleware.cs | 4 --
.../Views/Shared/Error.cshtml.cs | 2 +-
examples/RazorPages/Pages/Error.cshtml.cs | 2 +-
examples/RazorPages/Pages/Index.cshtml.cs | 2 +-
examples/RazorPages/Pages/Privacy.cshtml.cs | 5 +--
examples/RazorPages/RazorPages.csproj | 4 ++
.../Identity/IUserRepository.cs | 2 -
.../Identity/InMemoryUserRepository.cs | 4 --
examples/TargetingConsoleApp/Identity/User.cs | 2 -
examples/TargetingConsoleApp/Program.cs | 2 +-
.../TargetingConsoleApp.csproj | 5 +++
.../FeatureGateAttribute.cs | 12 +++---
...rosoft.FeatureManagement.AspNetCore.csproj | 6 ++-
.../TagHelpers/FeatureTagHelper.cs | 6 +--
.../AssemblyInfo.cs | 4 +-
.../ConfigurationFeatureDefinitionProvider.cs | 6 +--
.../ConfigurationFields.cs | 2 +-
.../ConfigurationWrapper.cs | 18 ++++-----
.../FeatureFilters/ISystemClock.cs | 2 +-
.../Recurrence/RecurrenceEvaluator.cs | 1 -
.../FeatureManagementBuilder.cs | 6 +--
.../FeatureManager.cs | 12 +++---
.../IFilterParametersBinder.cs | 2 +-
.../Microsoft.FeatureManagement.csproj | 6 ++-
.../MicrosoftFeatureManagementFields.cs | 2 +-
.../ServiceCollectionExtensions.cs | 32 +++++++--------
.../Targeting/ContextualTargetingFilter.cs | 1 -
.../FeatureManagementAspNetCore.cs | 1 -
.../MvcFilter.cs | 2 +-
.../Tests.FeatureManagement.AspNetCore.csproj | 6 ++-
.../CustomTargetingFilter.cs | 3 +-
.../FeatureManagement.cs | 8 ++--
.../RecurrenceEvaluation.cs | 4 +-
.../Tests.FeatureManagement.csproj | 6 ++-
50 files changed, 159 insertions(+), 115 deletions(-)
create mode 100644 .editorconfig
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 00000000..233e6128
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,39 @@
+# editorconfig.org
+
+# top-most EditorConfig file
+root = true
+
+## Default settings ##
+[*]
+insert_final_newline = true
+indent_style = space
+indent_size = 4
+trim_trailing_whitespace = true
+
+## Formatting rule ##
+# https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0055
+dotnet_diagnostic.IDE0055.severity = error
+
+# 'Using' directive preferences
+dotnet_sort_system_directives_first = false
+
+# New line preferences
+dotnet_diagnostic.IDE2002.severity = error
+csharp_style_allow_blank_lines_between_consecutive_braces_experimental = false
+dotnet_diagnostic.IDE2004.severity = error
+csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = false
+dotnet_diagnostic.IDE2005.severity = error
+csharp_style_allow_blank_line_after_token_in_conditional_expression_experimental = false
+dotnet_diagnostic.IDE2006.severity = error
+csharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimental = false
+dotnet_diagnostic.IDE2000.severity = error
+dotnet_style_allow_multiple_blank_lines_experimental = false
+dotnet_diagnostic.IDE2003.severity = error
+dotnet_style_allow_statement_immediately_after_block_experimental = false
+
+[*.csproj]
+indent_size = 2
+charset = utf-8
+
+[*.json]
+indent_size = 2
\ No newline at end of file
diff --git a/examples/BlazorServerApp/BlazorServerApp.csproj b/examples/BlazorServerApp/BlazorServerApp.csproj
index eeae537e..115de563 100644
--- a/examples/BlazorServerApp/BlazorServerApp.csproj
+++ b/examples/BlazorServerApp/BlazorServerApp.csproj
@@ -9,4 +9,8 @@
+
+ True
+
+
diff --git a/examples/BlazorServerApp/BrowserFilter.cs b/examples/BlazorServerApp/BrowserFilter.cs
index 5105b8a8..376f323e 100644
--- a/examples/BlazorServerApp/BrowserFilter.cs
+++ b/examples/BlazorServerApp/BrowserFilter.cs
@@ -45,7 +45,7 @@ private static bool IsChromeBrowser(string userAgentContext)
return false;
}
- return userAgentContext.Contains("chrome", StringComparison.OrdinalIgnoreCase) &&
+ return userAgentContext.Contains("chrome", StringComparison.OrdinalIgnoreCase) &&
!userAgentContext.Contains("edg", StringComparison.OrdinalIgnoreCase);
}
diff --git a/examples/BlazorServerApp/Program.cs b/examples/BlazorServerApp/Program.cs
index 4a66f68c..1dfd1c43 100644
--- a/examples/BlazorServerApp/Program.cs
+++ b/examples/BlazorServerApp/Program.cs
@@ -48,4 +48,4 @@ public static void Main(string[] args)
app.Run();
}
}
-}
\ No newline at end of file
+}
diff --git a/examples/ConsoleApp/AccountServiceContext.cs b/examples/ConsoleApp/AccountServiceContext.cs
index 85114371..95f85a33 100644
--- a/examples/ConsoleApp/AccountServiceContext.cs
+++ b/examples/ConsoleApp/AccountServiceContext.cs
@@ -4,4 +4,4 @@
class AccountServiceContext : IAccountContext
{
public string AccountId { get; set; }
-}
\ No newline at end of file
+}
diff --git a/examples/ConsoleApp/ConsoleApp.csproj b/examples/ConsoleApp/ConsoleApp.csproj
index fe29b948..1ef47ac8 100644
--- a/examples/ConsoleApp/ConsoleApp.csproj
+++ b/examples/ConsoleApp/ConsoleApp.csproj
@@ -21,4 +21,8 @@
+
+ True
+
+
diff --git a/examples/ConsoleApp/Program.cs b/examples/ConsoleApp/Program.cs
index 12028ca2..fb43a50e 100644
--- a/examples/ConsoleApp/Program.cs
+++ b/examples/ConsoleApp/Program.cs
@@ -1,4 +1,7 @@
-using Microsoft.Extensions.Configuration;
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+//
+using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.FeatureManagement;
@@ -49,4 +52,4 @@
// Output results
Console.WriteLine($"The {FeatureName} feature is {(enabled ? "enabled" : "disabled")} for the '{account}' account.");
}
-}
\ No newline at end of file
+}
diff --git a/examples/FeatureFlagDemo/Authentication/QueryStringAuthenticationHandler.cs b/examples/FeatureFlagDemo/Authentication/QueryStringAuthenticationHandler.cs
index 0049cca3..7770ed3d 100644
--- a/examples/FeatureFlagDemo/Authentication/QueryStringAuthenticationHandler.cs
+++ b/examples/FeatureFlagDemo/Authentication/QueryStringAuthenticationHandler.cs
@@ -2,14 +2,10 @@
// Licensed under the MIT license.
//
using Microsoft.AspNetCore.Authentication;
-using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.Primitives;
-using System.Collections.Generic;
-using System.Linq;
using System.Security.Claims;
using System.Text.Encodings.Web;
-using System.Threading.Tasks;
namespace FeatureFlagDemo.Authentication
{
diff --git a/examples/FeatureFlagDemo/BrowserFilter.cs b/examples/FeatureFlagDemo/BrowserFilter.cs
index efeb8e70..335e6d4c 100644
--- a/examples/FeatureFlagDemo/BrowserFilter.cs
+++ b/examples/FeatureFlagDemo/BrowserFilter.cs
@@ -1,12 +1,7 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
//
-using Microsoft.AspNetCore.Http;
-using Microsoft.Extensions.Configuration;
using Microsoft.FeatureManagement;
-using System;
-using System.Linq;
-using System.Threading.Tasks;
namespace FeatureFlagDemo.FeatureManagement.FeatureFilters
{
diff --git a/examples/FeatureFlagDemo/BrowserFilterSettings.cs b/examples/FeatureFlagDemo/BrowserFilterSettings.cs
index 91b8211a..c4cce8a3 100644
--- a/examples/FeatureFlagDemo/BrowserFilterSettings.cs
+++ b/examples/FeatureFlagDemo/BrowserFilterSettings.cs
@@ -1,8 +1,6 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
//
-using System.Collections.Generic;
-
namespace FeatureFlagDemo.FeatureManagement.FeatureFilters
{
public class BrowserFilterSettings
diff --git a/examples/FeatureFlagDemo/Controllers/BetaController.cs b/examples/FeatureFlagDemo/Controllers/BetaController.cs
index 9b69d9cf..4fed13f8 100644
--- a/examples/FeatureFlagDemo/Controllers/BetaController.cs
+++ b/examples/FeatureFlagDemo/Controllers/BetaController.cs
@@ -7,7 +7,7 @@
namespace FeatureFlagDemo.Controllers
{
- public class BetaController: Controller
+ public class BetaController : Controller
{
private readonly IFeatureManager _featureManager;
diff --git a/examples/FeatureFlagDemo/Controllers/HomeController.cs b/examples/FeatureFlagDemo/Controllers/HomeController.cs
index 6e43fba2..e7bfcd43 100644
--- a/examples/FeatureFlagDemo/Controllers/HomeController.cs
+++ b/examples/FeatureFlagDemo/Controllers/HomeController.cs
@@ -1,13 +1,11 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
//
-using System.Diagnostics;
-using Microsoft.AspNetCore.Mvc;
using FeatureFlagDemo.Models;
-using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
using Microsoft.FeatureManagement;
using Microsoft.FeatureManagement.Mvc;
-using System.Threading.Tasks;
+using System.Diagnostics;
namespace FeatureFlagDemo.Controllers
{
diff --git a/examples/FeatureFlagDemo/FeatureFlagDemo.csproj b/examples/FeatureFlagDemo/FeatureFlagDemo.csproj
index fcf18a50..c3955ace 100644
--- a/examples/FeatureFlagDemo/FeatureFlagDemo.csproj
+++ b/examples/FeatureFlagDemo/FeatureFlagDemo.csproj
@@ -1,4 +1,4 @@
-
+
net6.0
@@ -32,4 +32,8 @@
+
+ True
+
+
diff --git a/examples/FeatureFlagDemo/Models/ErrorViewModel.cs b/examples/FeatureFlagDemo/Models/ErrorViewModel.cs
index 17542f32..bd9dea6c 100644
--- a/examples/FeatureFlagDemo/Models/ErrorViewModel.cs
+++ b/examples/FeatureFlagDemo/Models/ErrorViewModel.cs
@@ -1,8 +1,6 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
//
-using System;
-
namespace FeatureFlagDemo.Models
{
public class ErrorViewModel
@@ -11,4 +9,4 @@ public class ErrorViewModel
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
}
-}
\ No newline at end of file
+}
diff --git a/examples/FeatureFlagDemo/SuperUserFilter.cs b/examples/FeatureFlagDemo/SuperUserFilter.cs
index 25dc8e5f..4174c3c1 100644
--- a/examples/FeatureFlagDemo/SuperUserFilter.cs
+++ b/examples/FeatureFlagDemo/SuperUserFilter.cs
@@ -2,7 +2,6 @@
// Licensed under the MIT license.
//
using Microsoft.FeatureManagement;
-using System.Threading.Tasks;
namespace FeatureFlagDemo.FeatureManagement.FeatureFilters
{
diff --git a/examples/FeatureFlagDemo/ThirdPartyActionFilter.cs b/examples/FeatureFlagDemo/ThirdPartyActionFilter.cs
index a2d3abd1..4fb4c550 100644
--- a/examples/FeatureFlagDemo/ThirdPartyActionFilter.cs
+++ b/examples/FeatureFlagDemo/ThirdPartyActionFilter.cs
@@ -1,9 +1,7 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
//
-using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Filters;
-using Microsoft.Extensions.Logging;
namespace FeatureFlagDemo
{
diff --git a/examples/FeatureFlagDemo/ThirdPartyMiddleware.cs b/examples/FeatureFlagDemo/ThirdPartyMiddleware.cs
index 74907908..52bdeddf 100644
--- a/examples/FeatureFlagDemo/ThirdPartyMiddleware.cs
+++ b/examples/FeatureFlagDemo/ThirdPartyMiddleware.cs
@@ -1,10 +1,6 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
//
-using Microsoft.AspNetCore.Http;
-using Microsoft.Extensions.Logging;
-using System.Threading.Tasks;
-
namespace FeatureFlagDemo
{
public class ThirdPartyMiddleware
diff --git a/examples/FeatureFlagDemo/Views/Shared/Error.cshtml.cs b/examples/FeatureFlagDemo/Views/Shared/Error.cshtml.cs
index d832e108..79b17264 100644
--- a/examples/FeatureFlagDemo/Views/Shared/Error.cshtml.cs
+++ b/examples/FeatureFlagDemo/Views/Shared/Error.cshtml.cs
@@ -24,4 +24,4 @@ public void OnGet()
RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
}
}
-}
\ No newline at end of file
+}
diff --git a/examples/RazorPages/Pages/Error.cshtml.cs b/examples/RazorPages/Pages/Error.cshtml.cs
index 74050d52..149f1f23 100644
--- a/examples/RazorPages/Pages/Error.cshtml.cs
+++ b/examples/RazorPages/Pages/Error.cshtml.cs
@@ -24,4 +24,4 @@ public void OnGet()
RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
}
}
-}
\ No newline at end of file
+}
diff --git a/examples/RazorPages/Pages/Index.cshtml.cs b/examples/RazorPages/Pages/Index.cshtml.cs
index 05dd8805..55bed039 100644
--- a/examples/RazorPages/Pages/Index.cshtml.cs
+++ b/examples/RazorPages/Pages/Index.cshtml.cs
@@ -18,4 +18,4 @@ public void OnGet()
}
}
-}
\ No newline at end of file
+}
diff --git a/examples/RazorPages/Pages/Privacy.cshtml.cs b/examples/RazorPages/Pages/Privacy.cshtml.cs
index c1cd207f..cf5897c5 100644
--- a/examples/RazorPages/Pages/Privacy.cshtml.cs
+++ b/examples/RazorPages/Pages/Privacy.cshtml.cs
@@ -1,5 +1,4 @@
-using Microsoft.AspNetCore.Mvc;
-using Microsoft.AspNetCore.Mvc.RazorPages;
+using Microsoft.AspNetCore.Mvc.RazorPages;
namespace RazorPages.Pages
{
@@ -16,4 +15,4 @@ public void OnGet()
{
}
}
-}
\ No newline at end of file
+}
diff --git a/examples/RazorPages/RazorPages.csproj b/examples/RazorPages/RazorPages.csproj
index 2a2cbb46..7eab2e16 100644
--- a/examples/RazorPages/RazorPages.csproj
+++ b/examples/RazorPages/RazorPages.csproj
@@ -10,4 +10,8 @@
+
+ True
+
+
diff --git a/examples/TargetingConsoleApp/Identity/IUserRepository.cs b/examples/TargetingConsoleApp/Identity/IUserRepository.cs
index 15fedc84..ea5a99f4 100644
--- a/examples/TargetingConsoleApp/Identity/IUserRepository.cs
+++ b/examples/TargetingConsoleApp/Identity/IUserRepository.cs
@@ -1,8 +1,6 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
//
-using System.Threading.Tasks;
-
namespace TargetingConsoleApp.Identity
{
interface IUserRepository
diff --git a/examples/TargetingConsoleApp/Identity/InMemoryUserRepository.cs b/examples/TargetingConsoleApp/Identity/InMemoryUserRepository.cs
index 450c7044..1159bda0 100644
--- a/examples/TargetingConsoleApp/Identity/InMemoryUserRepository.cs
+++ b/examples/TargetingConsoleApp/Identity/InMemoryUserRepository.cs
@@ -1,10 +1,6 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
//
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-
namespace TargetingConsoleApp.Identity
{
class InMemoryUserRepository : IUserRepository
diff --git a/examples/TargetingConsoleApp/Identity/User.cs b/examples/TargetingConsoleApp/Identity/User.cs
index be27cac1..de1f4069 100644
--- a/examples/TargetingConsoleApp/Identity/User.cs
+++ b/examples/TargetingConsoleApp/Identity/User.cs
@@ -1,8 +1,6 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
//
-using System.Collections.Generic;
-
namespace TargetingConsoleApp.Identity
{
class User
diff --git a/examples/TargetingConsoleApp/Program.cs b/examples/TargetingConsoleApp/Program.cs
index 5b89807a..d8ee6359 100644
--- a/examples/TargetingConsoleApp/Program.cs
+++ b/examples/TargetingConsoleApp/Program.cs
@@ -54,4 +54,4 @@
// Output results
Console.WriteLine($"The {FeatureName} feature is {(enabled ? "enabled" : "disabled")} for the user '{userId}'.");
}
-}
\ No newline at end of file
+}
diff --git a/examples/TargetingConsoleApp/TargetingConsoleApp.csproj b/examples/TargetingConsoleApp/TargetingConsoleApp.csproj
index e1ffbd53..c699e5ab 100644
--- a/examples/TargetingConsoleApp/TargetingConsoleApp.csproj
+++ b/examples/TargetingConsoleApp/TargetingConsoleApp.csproj
@@ -20,4 +20,9 @@
Always
+
+
+ True
+
+
diff --git a/src/Microsoft.FeatureManagement.AspNetCore/FeatureGateAttribute.cs b/src/Microsoft.FeatureManagement.AspNetCore/FeatureGateAttribute.cs
index fb15e5b1..caf30a28 100644
--- a/src/Microsoft.FeatureManagement.AspNetCore/FeatureGateAttribute.cs
+++ b/src/Microsoft.FeatureManagement.AspNetCore/FeatureGateAttribute.cs
@@ -106,9 +106,9 @@ public override async Task OnActionExecutionAsync(ActionExecutingContext context
//
// Enabled state is determined by either 'any' or 'all' features being enabled.
- bool enabled = RequirementType == RequirementType.All ?
- await Features.All(async feature => await fm.IsEnabledAsync(feature).ConfigureAwait(false)) :
- await Features.Any(async feature => await fm.IsEnabledAsync(feature).ConfigureAwait(false));
+ bool enabled = RequirementType == RequirementType.All
+ ? await Features.All(async feature => await fm.IsEnabledAsync(feature).ConfigureAwait(false))
+ : await Features.Any(async feature => await fm.IsEnabledAsync(feature).ConfigureAwait(false));
if (enabled)
{
@@ -134,9 +134,9 @@ public async Task OnPageHandlerExecutionAsync(PageHandlerExecutingContext contex
//
// Enabled state is determined by either 'any' or 'all' features being enabled.
- bool enabled = RequirementType == RequirementType.All ?
- await Features.All(async feature => await fm.IsEnabledAsync(feature).ConfigureAwait(false)) :
- await Features.Any(async feature => await fm.IsEnabledAsync(feature).ConfigureAwait(false));
+ bool enabled = RequirementType == RequirementType.All
+ ? await Features.All(async feature => await fm.IsEnabledAsync(feature).ConfigureAwait(false))
+ : await Features.Any(async feature => await fm.IsEnabledAsync(feature).ConfigureAwait(false));
if (enabled)
{
diff --git a/src/Microsoft.FeatureManagement.AspNetCore/Microsoft.FeatureManagement.AspNetCore.csproj b/src/Microsoft.FeatureManagement.AspNetCore/Microsoft.FeatureManagement.AspNetCore.csproj
index 73ab8dfa..c35cf77b 100644
--- a/src/Microsoft.FeatureManagement.AspNetCore/Microsoft.FeatureManagement.AspNetCore.csproj
+++ b/src/Microsoft.FeatureManagement.AspNetCore/Microsoft.FeatureManagement.AspNetCore.csproj
@@ -1,4 +1,4 @@
-
+
@@ -44,4 +44,8 @@
+
+ True
+
+
diff --git a/src/Microsoft.FeatureManagement.AspNetCore/TagHelpers/FeatureTagHelper.cs b/src/Microsoft.FeatureManagement.AspNetCore/TagHelpers/FeatureTagHelper.cs
index 4a0da1e0..2fddf486 100644
--- a/src/Microsoft.FeatureManagement.AspNetCore/TagHelpers/FeatureTagHelper.cs
+++ b/src/Microsoft.FeatureManagement.AspNetCore/TagHelpers/FeatureTagHelper.cs
@@ -54,9 +54,9 @@ public override async Task ProcessAsync(TagHelperContext context, TagHelperOutpu
{
IEnumerable names = Name.Split(',').Select(n => n.Trim());
- enabled = Requirement == RequirementType.All ?
- await names.All(async n => await _featureManager.IsEnabledAsync(n).ConfigureAwait(false)) :
- await names.Any(async n => await _featureManager.IsEnabledAsync(n).ConfigureAwait(false));
+ enabled = Requirement == RequirementType.All
+ ? await names.All(async n => await _featureManager.IsEnabledAsync(n).ConfigureAwait(false))
+ : await names.Any(async n => await _featureManager.IsEnabledAsync(n).ConfigureAwait(false));
}
if (Negate)
diff --git a/src/Microsoft.FeatureManagement/AssemblyInfo.cs b/src/Microsoft.FeatureManagement/AssemblyInfo.cs
index 955518ef..75bfb2fa 100644
--- a/src/Microsoft.FeatureManagement/AssemblyInfo.cs
+++ b/src/Microsoft.FeatureManagement/AssemblyInfo.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Microsoft Corporation.
+// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
//
using System.Runtime.CompilerServices;
@@ -9,4 +9,4 @@
"3ae70fbea5662f61dd9d640de2205b7bd5359a43dda006e51d83d1f5f7a7d3f849267a0a28676d" +
"cf49727a32487d4c75c4aacd5febb0069e1adc66ec63bbd18ec2276091a0e3c1326aa626c9e4db" +
"800714a134f2a81e405f35752b55220021923429cb61776cd2fa66d25c335f8dc27bb92292905a" +
-"3798d896")]
\ No newline at end of file
+"3798d896")]
diff --git a/src/Microsoft.FeatureManagement/ConfigurationFeatureDefinitionProvider.cs b/src/Microsoft.FeatureManagement/ConfigurationFeatureDefinitionProvider.cs
index ebd1c621..28af7ce6 100644
--- a/src/Microsoft.FeatureManagement/ConfigurationFeatureDefinitionProvider.cs
+++ b/src/Microsoft.FeatureManagement/ConfigurationFeatureDefinitionProvider.cs
@@ -381,9 +381,9 @@ private IEnumerable GetFeatureDefinitionSections()
.FirstOrDefault(section =>
string.Equals(
section.Key,
- _microsoftFeatureManagementSchemaEnabled ?
- MicrosoftFeatureManagementFields.FeatureManagementSectionName :
- ConfigurationFields.FeatureManagementSectionName,
+ _microsoftFeatureManagementSchemaEnabled
+ ? MicrosoftFeatureManagementFields.FeatureManagementSectionName
+ : ConfigurationFields.FeatureManagementSectionName,
StringComparison.OrdinalIgnoreCase));
if (featureManagementConfigurationSection == null)
diff --git a/src/Microsoft.FeatureManagement/ConfigurationFields.cs b/src/Microsoft.FeatureManagement/ConfigurationFields.cs
index a5472cd8..8b6ba82c 100644
--- a/src/Microsoft.FeatureManagement/ConfigurationFields.cs
+++ b/src/Microsoft.FeatureManagement/ConfigurationFields.cs
@@ -17,4 +17,4 @@ internal static class ConfigurationFields
public const string NameKeyword = "Name";
public const string FeatureManagementSectionName = "FeatureManagement";
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.FeatureManagement/ConfigurationWrapper.cs b/src/Microsoft.FeatureManagement/ConfigurationWrapper.cs
index 99f0b2a6..61d921f5 100644
--- a/src/Microsoft.FeatureManagement/ConfigurationWrapper.cs
+++ b/src/Microsoft.FeatureManagement/ConfigurationWrapper.cs
@@ -1,10 +1,10 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
//
-using System;
-using System.Collections.Generic;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Primitives;
+using System;
+using System.Collections.Generic;
namespace Microsoft.FeatureManagement
{
@@ -27,13 +27,13 @@ public string this[string key]
set => _configuration[key] = value;
}
- public IEnumerable GetChildren() =>
- _configuration.GetChildren();
+ public IEnumerable GetChildren()
+ => _configuration.GetChildren();
- public IChangeToken GetReloadToken() =>
- _configuration.GetReloadToken();
+ public IChangeToken GetReloadToken()
+ => _configuration.GetReloadToken();
- public IConfigurationSection GetSection(string key) =>
- _configuration.GetSection(key);
+ public IConfigurationSection GetSection(string key)
+ => _configuration.GetSection(key);
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.FeatureManagement/FeatureFilters/ISystemClock.cs b/src/Microsoft.FeatureManagement/FeatureFilters/ISystemClock.cs
index 50c6743d..1fc9b667 100644
--- a/src/Microsoft.FeatureManagement/FeatureFilters/ISystemClock.cs
+++ b/src/Microsoft.FeatureManagement/FeatureFilters/ISystemClock.cs
@@ -17,4 +17,4 @@ internal interface ISystemClock
///
public DateTimeOffset UtcNow { get; }
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.FeatureManagement/FeatureFilters/Recurrence/RecurrenceEvaluator.cs b/src/Microsoft.FeatureManagement/FeatureFilters/Recurrence/RecurrenceEvaluator.cs
index 4dba080a..5e8b6872 100644
--- a/src/Microsoft.FeatureManagement/FeatureFilters/Recurrence/RecurrenceEvaluator.cs
+++ b/src/Microsoft.FeatureManagement/FeatureFilters/Recurrence/RecurrenceEvaluator.cs
@@ -339,7 +339,6 @@ private static int CalculateWeeklyDayOffset(DayOfWeek day1, DayOfWeek day2)
return ((int)day1 - (int)day2 + DaysPerWeek) % DaysPerWeek;
}
-
///
/// Sorts a collection of days of week based on their offsets from a specified first day of week.
/// A collection of days of week.
diff --git a/src/Microsoft.FeatureManagement/FeatureManagementBuilder.cs b/src/Microsoft.FeatureManagement/FeatureManagementBuilder.cs
index 2b2af56c..ab07a595 100644
--- a/src/Microsoft.FeatureManagement/FeatureManagementBuilder.cs
+++ b/src/Microsoft.FeatureManagement/FeatureManagementBuilder.cs
@@ -1,11 +1,11 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
//
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.FeatureManagement.FeatureFilters;
using System;
using System.Collections.Generic;
using System.Linq;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.FeatureManagement.FeatureFilters;
namespace Microsoft.FeatureManagement
{
@@ -35,7 +35,7 @@ public IFeatureManagementBuilder AddFeatureFilter() where T : IFeatureFilterM
}
IEnumerable featureFilterImplementations = implementationType.GetInterfaces()
- .Where(i => i == typeof(IFeatureFilter) ||
+ .Where(i => i == typeof(IFeatureFilter) ||
(i.IsGenericType && i.GetGenericTypeDefinition().IsAssignableFrom(typeof(IContextualFeatureFilter<>))));
if (featureFilterImplementations.Count() > 1)
diff --git a/src/Microsoft.FeatureManagement/FeatureManager.cs b/src/Microsoft.FeatureManagement/FeatureManager.cs
index 9080929d..ec7ae990 100644
--- a/src/Microsoft.FeatureManagement/FeatureManager.cs
+++ b/src/Microsoft.FeatureManagement/FeatureManager.cs
@@ -144,7 +144,7 @@ private async Task IsEnabledAsync(string feature, TContext appCo
if (featureDefinition.RequirementType == RequirementType.All && _options.IgnoreMissingFeatureFilters)
{
throw new FeatureManagementException(
- FeatureManagementError.Conflict,
+ FeatureManagementError.Conflict,
$"The 'IgnoreMissingFeatureFilters' flag cannot use used in combination with a feature of requirement type 'All'.");
}
@@ -183,7 +183,7 @@ private async Task IsEnabledAsync(string feature, TContext appCo
enabled = true;
break;
}
-
+
continue;
}
@@ -268,7 +268,7 @@ await contextualFilter.EvaluateAsync(context, appContext).ConfigureAwait(false)
{
throw new FeatureManagementException(FeatureManagementError.MissingFeature, errorMessage);
}
-
+
Logger?.LogDebug(errorMessage);
}
@@ -335,7 +335,8 @@ private IFeatureFilterMetadata GetFeatureFilterMetadata(string filterName, Type
{
IFeatureFilterMetadata filter = _filterMetadataCache.GetOrAdd(
$"{filterName}{Environment.NewLine}{appContextType?.FullName}",
- (_) => {
+ (_) =>
+ {
IEnumerable matchingFilters = _featureFilters.Where(f =>
{
@@ -413,7 +414,8 @@ private ContextualFeatureFilterEvaluator GetContextualFeatureFilter(string filte
ContextualFeatureFilterEvaluator filter = _contextualFeatureFilterCache.GetOrAdd(
$"{filterName}{Environment.NewLine}{appContextType.FullName}",
- (_) => {
+ (_) =>
+ {
IFeatureFilterMetadata metadata = GetFeatureFilterMetadata(filterName, appContextType);
diff --git a/src/Microsoft.FeatureManagement/IFilterParametersBinder.cs b/src/Microsoft.FeatureManagement/IFilterParametersBinder.cs
index bd572e71..fe889893 100644
--- a/src/Microsoft.FeatureManagement/IFilterParametersBinder.cs
+++ b/src/Microsoft.FeatureManagement/IFilterParametersBinder.cs
@@ -18,4 +18,4 @@ public interface IFilterParametersBinder
/// A settings object that is understood by the implementer of .
object BindParameters(IConfiguration parameters);
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.FeatureManagement/Microsoft.FeatureManagement.csproj b/src/Microsoft.FeatureManagement/Microsoft.FeatureManagement.csproj
index 39cdd2e6..954d6361 100644
--- a/src/Microsoft.FeatureManagement/Microsoft.FeatureManagement.csproj
+++ b/src/Microsoft.FeatureManagement/Microsoft.FeatureManagement.csproj
@@ -1,4 +1,4 @@
-
+
@@ -52,4 +52,8 @@
+
+ True
+
+
diff --git a/src/Microsoft.FeatureManagement/MicrosoftFeatureManagementFields.cs b/src/Microsoft.FeatureManagement/MicrosoftFeatureManagementFields.cs
index 50351526..20b576b3 100644
--- a/src/Microsoft.FeatureManagement/MicrosoftFeatureManagementFields.cs
+++ b/src/Microsoft.FeatureManagement/MicrosoftFeatureManagementFields.cs
@@ -24,4 +24,4 @@ internal static class MicrosoftFeatureManagementFields
public const string Name = "name";
public const string Parameters = "parameters";
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.FeatureManagement/ServiceCollectionExtensions.cs b/src/Microsoft.FeatureManagement/ServiceCollectionExtensions.cs
index b0a9bdd6..50a6ba7f 100644
--- a/src/Microsoft.FeatureManagement/ServiceCollectionExtensions.cs
+++ b/src/Microsoft.FeatureManagement/ServiceCollectionExtensions.cs
@@ -42,21 +42,21 @@ public static IFeatureManagementBuilder AddFeatureManagement(this IServiceCollec
// Add required services
services.TryAddSingleton();
- services.AddSingleton(sp =>
+ services.AddSingleton(sp =>
new FeatureManager(
sp.GetRequiredService(),
sp.GetRequiredService>().Value)
- {
- FeatureFilters = sp.GetRequiredService>(),
- SessionManagers = sp.GetRequiredService>(),
- Cache = sp.GetRequiredService(),
- Logger = sp.GetRequiredService().CreateLogger()
- });
+ {
+ FeatureFilters = sp.GetRequiredService>(),
+ SessionManagers = sp.GetRequiredService>(),
+ Cache = sp.GetRequiredService(),
+ Logger = sp.GetRequiredService().CreateLogger()
+ });
services.AddScoped();
var builder = new FeatureManagementBuilder(services);
-
+
//
// Add built-in feature filters
builder.AddFeatureFilter();
@@ -119,16 +119,16 @@ public static IFeatureManagementBuilder AddScopedFeatureManagement(this IService
// Add required services
services.TryAddSingleton();
- services.AddScoped(sp =>
+ services.AddScoped(sp =>
new FeatureManager(
sp.GetRequiredService(),
sp.GetRequiredService>().Value)
- {
- FeatureFilters = sp.GetRequiredService>(),
- SessionManagers = sp.GetRequiredService>(),
- Cache = sp.GetRequiredService(),
- Logger = sp.GetRequiredService().CreateLogger()
- });
+ {
+ FeatureFilters = sp.GetRequiredService>(),
+ SessionManagers = sp.GetRequiredService>(),
+ Cache = sp.GetRequiredService(),
+ Logger = sp.GetRequiredService().CreateLogger()
+ });
services.AddScoped();
@@ -138,7 +138,7 @@ public static IFeatureManagementBuilder AddScopedFeatureManagement(this IService
// Add built-in feature filters
builder.AddFeatureFilter();
- builder.AddFeatureFilter(sp =>
+ builder.AddFeatureFilter(sp =>
new TimeWindowFilter()
{
Cache = sp.GetRequiredService()
diff --git a/src/Microsoft.FeatureManagement/Targeting/ContextualTargetingFilter.cs b/src/Microsoft.FeatureManagement/Targeting/ContextualTargetingFilter.cs
index b4b43bde..e2c3d5e4 100644
--- a/src/Microsoft.FeatureManagement/Targeting/ContextualTargetingFilter.cs
+++ b/src/Microsoft.FeatureManagement/Targeting/ContextualTargetingFilter.cs
@@ -132,7 +132,6 @@ public Task EvaluateAsync(FeatureFilterEvaluationContext context, ITargeti
return Task.FromResult(IsTargeted(defaultContextId, settings.Audience.DefaultRolloutPercentage));
}
-
///
/// Determines if a given context id should be targeted based off the provided percentage
///
diff --git a/tests/Tests.FeatureManagement.AspNetCore/FeatureManagementAspNetCore.cs b/tests/Tests.FeatureManagement.AspNetCore/FeatureManagementAspNetCore.cs
index 3e5d6aa0..19e29dab 100644
--- a/tests/Tests.FeatureManagement.AspNetCore/FeatureManagementAspNetCore.cs
+++ b/tests/Tests.FeatureManagement.AspNetCore/FeatureManagementAspNetCore.cs
@@ -9,7 +9,6 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.FeatureManagement;
-using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
diff --git a/tests/Tests.FeatureManagement.AspNetCore/MvcFilter.cs b/tests/Tests.FeatureManagement.AspNetCore/MvcFilter.cs
index 0635a289..cbf617d5 100644
--- a/tests/Tests.FeatureManagement.AspNetCore/MvcFilter.cs
+++ b/tests/Tests.FeatureManagement.AspNetCore/MvcFilter.cs
@@ -1,8 +1,8 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
//
-using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Filters;
+using System.Threading.Tasks;
namespace Tests.FeatureManagement.AspNetCore
{
diff --git a/tests/Tests.FeatureManagement.AspNetCore/Tests.FeatureManagement.AspNetCore.csproj b/tests/Tests.FeatureManagement.AspNetCore/Tests.FeatureManagement.AspNetCore.csproj
index b14bbfdb..33f4704a 100644
--- a/tests/Tests.FeatureManagement.AspNetCore/Tests.FeatureManagement.AspNetCore.csproj
+++ b/tests/Tests.FeatureManagement.AspNetCore/Tests.FeatureManagement.AspNetCore.csproj
@@ -1,4 +1,4 @@
-
+
net6.0;net7.0;net8.0
@@ -47,4 +47,8 @@
+
+ True
+
+
diff --git a/tests/Tests.FeatureManagement/CustomTargetingFilter.cs b/tests/Tests.FeatureManagement/CustomTargetingFilter.cs
index cc89482f..a0bdbace 100644
--- a/tests/Tests.FeatureManagement/CustomTargetingFilter.cs
+++ b/tests/Tests.FeatureManagement/CustomTargetingFilter.cs
@@ -1,7 +1,6 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
//
-using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.FeatureManagement;
@@ -26,7 +25,7 @@ public CustomTargetingFilter(IOptions options, ILogg
public Task EvaluateAsync(FeatureFilterEvaluationContext context)
{
- return _contextualFilter.EvaluateAsync(context, new TargetingContext(){ UserId = "Jeff" });
+ return _contextualFilter.EvaluateAsync(context, new TargetingContext() { UserId = "Jeff" });
}
}
}
diff --git a/tests/Tests.FeatureManagement/FeatureManagement.cs b/tests/Tests.FeatureManagement/FeatureManagement.cs
index 964f8dd4..ce337200 100644
--- a/tests/Tests.FeatureManagement/FeatureManagement.cs
+++ b/tests/Tests.FeatureManagement/FeatureManagement.cs
@@ -106,7 +106,6 @@ public async Task ReadsTopLevelConfiguration()
Assert.True(await featureManager.IsEnabledAsync(feature));
}
-
[Fact]
public void AddsScopedFeatureManagement()
{
@@ -175,7 +174,7 @@ public async Task AllowsDuplicatedFilterAlias()
var appContext = new AppContext();
var dummyContext = new DummyContext();
-
+
var targetingContext = new TargetingContext();
Assert.True(await featureManager.IsEnabledAsync(featureName));
@@ -271,7 +270,7 @@ public async Task CustomFilterContextualTargetingWithNullSetting()
IConfiguration config = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build();
ServiceCollection services = new ServiceCollection();
-
+
var targetingContextAccessor = new OnDemandTargetingContextAccessor();
services.AddSingleton(targetingContextAccessor);
@@ -343,7 +342,7 @@ public async Task TimeWindow()
Assert.False(await featureManager.IsEnabledAsync(feature4));
Assert.True(await featureManager.IsEnabledAsync(feature5));
Assert.False(await featureManager.IsEnabledAsync(feature6));
-
+
for (int i = 0; i < 10; i++)
{
Assert.True(await featureManager.IsEnabledAsync(Features.RecurringTimeWindowTestFeature));
@@ -882,7 +881,6 @@ public async Task UsesRequirementType()
// Set filters to all return true
testFeatureFilter.Callback = _ => Task.FromResult(true);
-
Assert.True(await featureManager.IsEnabledAsync(anyFilterFeature));
Assert.True(await featureManager.IsEnabledAsync(allFilterFeature));
diff --git a/tests/Tests.FeatureManagement/RecurrenceEvaluation.cs b/tests/Tests.FeatureManagement/RecurrenceEvaluation.cs
index 50c6e449..184f3612 100644
--- a/tests/Tests.FeatureManagement/RecurrenceEvaluation.cs
+++ b/tests/Tests.FeatureManagement/RecurrenceEvaluation.cs
@@ -594,7 +594,7 @@ public void MatchDailyRecurrenceTest()
Range = new RecurrenceRange()
}
},
- false ),
+ false )
};
ConsumeEvaluationTestData(testData);
@@ -1671,7 +1671,7 @@ public async void RecurrenceEvaluationThroughCacheTest()
mockedTimeProvider.UtcNow = DateTimeOffset.Parse("2024-2-7T00:00:00+08:00");
Assert.False(await mockedTimeWindowFilter.EvaluateAsync(context));
- for (int i = 0; i < 10; i++ )
+ for (int i = 0; i < 10; i++)
{
mockedTimeProvider.UtcNow = mockedTimeProvider.UtcNow.AddDays(1);
Assert.False(await mockedTimeWindowFilter.EvaluateAsync(context));
diff --git a/tests/Tests.FeatureManagement/Tests.FeatureManagement.csproj b/tests/Tests.FeatureManagement/Tests.FeatureManagement.csproj
index ebf99ad6..fbde38d2 100644
--- a/tests/Tests.FeatureManagement/Tests.FeatureManagement.csproj
+++ b/tests/Tests.FeatureManagement/Tests.FeatureManagement.csproj
@@ -1,4 +1,4 @@
-
+
net48;net6.0;net7.0;net8.0
@@ -51,4 +51,8 @@
+
+ True
+
+
From 106ccc431ab963260b3d6a5af88cc2f2ffa9bcb7 Mon Sep 17 00:00:00 2001
From: Zhiyuan Liang <141655842+zhiyuanliang-ms@users.noreply.github.com>
Date: Thu, 18 Jul 2024 00:08:45 +0800
Subject: [PATCH 5/6] Add directory props (#474)
* add directory props
* update
---
Directory.Build.props | 7 +++++++
examples/BlazorServerApp/BlazorServerApp.csproj | 4 ----
examples/ConsoleApp/ConsoleApp.csproj | 6 +-----
examples/FeatureFlagDemo/FeatureFlagDemo.csproj | 4 ----
examples/RazorPages/RazorPages.csproj | 4 ----
examples/TargetingConsoleApp/TargetingConsoleApp.csproj | 4 ----
.../Microsoft.FeatureManagement.AspNetCore.csproj | 4 ----
.../Microsoft.FeatureManagement.csproj | 4 ----
.../Tests.FeatureManagement.AspNetCore.csproj | 6 +-----
.../Tests.FeatureManagement/Tests.FeatureManagement.csproj | 4 ----
10 files changed, 9 insertions(+), 38 deletions(-)
create mode 100644 Directory.Build.props
diff --git a/Directory.Build.props b/Directory.Build.props
new file mode 100644
index 00000000..e1220a8d
--- /dev/null
+++ b/Directory.Build.props
@@ -0,0 +1,7 @@
+
+
+
+ True
+
+
+
\ No newline at end of file
diff --git a/examples/BlazorServerApp/BlazorServerApp.csproj b/examples/BlazorServerApp/BlazorServerApp.csproj
index 115de563..eeae537e 100644
--- a/examples/BlazorServerApp/BlazorServerApp.csproj
+++ b/examples/BlazorServerApp/BlazorServerApp.csproj
@@ -9,8 +9,4 @@
-
- True
-
-
diff --git a/examples/ConsoleApp/ConsoleApp.csproj b/examples/ConsoleApp/ConsoleApp.csproj
index 1ef47ac8..8a40ebaf 100644
--- a/examples/ConsoleApp/ConsoleApp.csproj
+++ b/examples/ConsoleApp/ConsoleApp.csproj
@@ -20,9 +20,5 @@
Always
-
-
- True
-
-
+
diff --git a/examples/FeatureFlagDemo/FeatureFlagDemo.csproj b/examples/FeatureFlagDemo/FeatureFlagDemo.csproj
index c3955ace..94a10cc8 100644
--- a/examples/FeatureFlagDemo/FeatureFlagDemo.csproj
+++ b/examples/FeatureFlagDemo/FeatureFlagDemo.csproj
@@ -32,8 +32,4 @@
-
- True
-
-
diff --git a/examples/RazorPages/RazorPages.csproj b/examples/RazorPages/RazorPages.csproj
index 7eab2e16..2a2cbb46 100644
--- a/examples/RazorPages/RazorPages.csproj
+++ b/examples/RazorPages/RazorPages.csproj
@@ -10,8 +10,4 @@
-
- True
-
-
diff --git a/examples/TargetingConsoleApp/TargetingConsoleApp.csproj b/examples/TargetingConsoleApp/TargetingConsoleApp.csproj
index c699e5ab..2d3d3985 100644
--- a/examples/TargetingConsoleApp/TargetingConsoleApp.csproj
+++ b/examples/TargetingConsoleApp/TargetingConsoleApp.csproj
@@ -20,9 +20,5 @@
Always
-
-
- True
-
diff --git a/src/Microsoft.FeatureManagement.AspNetCore/Microsoft.FeatureManagement.AspNetCore.csproj b/src/Microsoft.FeatureManagement.AspNetCore/Microsoft.FeatureManagement.AspNetCore.csproj
index c35cf77b..7e6b3226 100644
--- a/src/Microsoft.FeatureManagement.AspNetCore/Microsoft.FeatureManagement.AspNetCore.csproj
+++ b/src/Microsoft.FeatureManagement.AspNetCore/Microsoft.FeatureManagement.AspNetCore.csproj
@@ -44,8 +44,4 @@
-
- True
-
-
diff --git a/src/Microsoft.FeatureManagement/Microsoft.FeatureManagement.csproj b/src/Microsoft.FeatureManagement/Microsoft.FeatureManagement.csproj
index 954d6361..95e64f26 100644
--- a/src/Microsoft.FeatureManagement/Microsoft.FeatureManagement.csproj
+++ b/src/Microsoft.FeatureManagement/Microsoft.FeatureManagement.csproj
@@ -52,8 +52,4 @@
-
- True
-
-
diff --git a/tests/Tests.FeatureManagement.AspNetCore/Tests.FeatureManagement.AspNetCore.csproj b/tests/Tests.FeatureManagement.AspNetCore/Tests.FeatureManagement.AspNetCore.csproj
index 33f4704a..4f9cbc6b 100644
--- a/tests/Tests.FeatureManagement.AspNetCore/Tests.FeatureManagement.AspNetCore.csproj
+++ b/tests/Tests.FeatureManagement.AspNetCore/Tests.FeatureManagement.AspNetCore.csproj
@@ -46,9 +46,5 @@
Always
-
-
- True
-
-
+
diff --git a/tests/Tests.FeatureManagement/Tests.FeatureManagement.csproj b/tests/Tests.FeatureManagement/Tests.FeatureManagement.csproj
index fbde38d2..c75fb404 100644
--- a/tests/Tests.FeatureManagement/Tests.FeatureManagement.csproj
+++ b/tests/Tests.FeatureManagement/Tests.FeatureManagement.csproj
@@ -51,8 +51,4 @@
-
- True
-
-
From 7557b1db7d68c2e1080fb69a03f780ee5794b1cc Mon Sep 17 00:00:00 2001
From: Zhiyuan Liang
Date: Thu, 18 Jul 2024 14:13:33 +0800
Subject: [PATCH 6/6] adjust spacing
---
examples/BlazorServerApp/BlazorServerApp.csproj | 2 +-
examples/ConsoleApp/ConsoleApp.csproj | 2 +-
examples/TargetingConsoleApp/TargetingConsoleApp.csproj | 4 ++--
.../Microsoft.FeatureManagement.AspNetCore.csproj | 3 ++-
.../Microsoft.FeatureManagement.csproj | 1 +
.../Tests.FeatureManagement.AspNetCore.csproj | 2 +-
6 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/examples/BlazorServerApp/BlazorServerApp.csproj b/examples/BlazorServerApp/BlazorServerApp.csproj
index eeae537e..e1ab1c73 100644
--- a/examples/BlazorServerApp/BlazorServerApp.csproj
+++ b/examples/BlazorServerApp/BlazorServerApp.csproj
@@ -4,7 +4,7 @@
net6.0
enable
-
+
diff --git a/examples/ConsoleApp/ConsoleApp.csproj b/examples/ConsoleApp/ConsoleApp.csproj
index 8a40ebaf..fe29b948 100644
--- a/examples/ConsoleApp/ConsoleApp.csproj
+++ b/examples/ConsoleApp/ConsoleApp.csproj
@@ -20,5 +20,5 @@
Always
-
+
diff --git a/examples/TargetingConsoleApp/TargetingConsoleApp.csproj b/examples/TargetingConsoleApp/TargetingConsoleApp.csproj
index 2d3d3985..fe29b948 100644
--- a/examples/TargetingConsoleApp/TargetingConsoleApp.csproj
+++ b/examples/TargetingConsoleApp/TargetingConsoleApp.csproj
@@ -5,7 +5,7 @@
net6.0
enable
-
+
@@ -20,5 +20,5 @@
Always
-
+
diff --git a/src/Microsoft.FeatureManagement.AspNetCore/Microsoft.FeatureManagement.AspNetCore.csproj b/src/Microsoft.FeatureManagement.AspNetCore/Microsoft.FeatureManagement.AspNetCore.csproj
index 5610dc3a..bdafc42d 100644
--- a/src/Microsoft.FeatureManagement.AspNetCore/Microsoft.FeatureManagement.AspNetCore.csproj
+++ b/src/Microsoft.FeatureManagement.AspNetCore/Microsoft.FeatureManagement.AspNetCore.csproj
@@ -1,4 +1,5 @@
+
@@ -31,7 +32,7 @@
https://aka.ms/AzureAppConfigurationPackageIcon
© Microsoft Corporation. All rights reserved.
-
+
diff --git a/src/Microsoft.FeatureManagement/Microsoft.FeatureManagement.csproj b/src/Microsoft.FeatureManagement/Microsoft.FeatureManagement.csproj
index be817edb..5ffcb495 100644
--- a/src/Microsoft.FeatureManagement/Microsoft.FeatureManagement.csproj
+++ b/src/Microsoft.FeatureManagement/Microsoft.FeatureManagement.csproj
@@ -1,4 +1,5 @@
+
diff --git a/tests/Tests.FeatureManagement.AspNetCore/Tests.FeatureManagement.AspNetCore.csproj b/tests/Tests.FeatureManagement.AspNetCore/Tests.FeatureManagement.AspNetCore.csproj
index 4f9cbc6b..47592cc5 100644
--- a/tests/Tests.FeatureManagement.AspNetCore/Tests.FeatureManagement.AspNetCore.csproj
+++ b/tests/Tests.FeatureManagement.AspNetCore/Tests.FeatureManagement.AspNetCore.csproj
@@ -46,5 +46,5 @@
Always
-
+