Skip to content

Cache uncached AppContext.TryGetSwitch calls#66513

Merged
pavelsavara merged 9 commits into
dotnet:mainfrom
pavelsavara:cache_AppContext_TryGetSwitch
May 12, 2026
Merged

Cache uncached AppContext.TryGetSwitch calls#66513
pavelsavara merged 9 commits into
dotnet:mainfrom
pavelsavara:cache_AppContext_TryGetSwitch

Conversation

@pavelsavara
Copy link
Copy Markdown
Member

@pavelsavara pavelsavara commented Apr 28, 2026

Fixes #66280

AppContext.TryGetSwitch involves a dictionary lookup on every call. Several call sites in the repo were not caching the result, causing repeated lookups on hot paths (e.g., per-request in middleware).

This PR caches all previously-uncached AppContext.TryGetSwitch calls into static readonly fields or static auto-property initializers ({ get; } =), so the switch is read once at static initialization time.

Breaking change

If someone was calling AppContext.SetSwitch on the feature switches during execution, this is a breaking change.

I think that those features are designed to be configured at compile time and not changed during execution.
I'm advocating to make this breaking change.

Changes

Server-side (no trimmer interaction)

  • AuthorizationMiddleware — cached Microsoft.AspNetCore.Authorization.SuppressUseHttpContextAsAuthorizationResource into a static readonly bool field. This was the most impactful case since it ran on every HTTP request through the authorization pipeline.
  • SignInManager<TUser> — cached Microsoft.AspNetCore.Identity.CheckPasswordSignInAlwaysResetLockoutOnSuccess into a static readonly bool field.
  • DefaultEditorTemplates — cached Switch.Microsoft.AspNetCore.Mvc.UsePasswordValue into a static readonly bool field.

Components (trimmer/NAOT/WASM-safe)

These properties already had [FeatureSwitchDefinition] attributes or ILLink substitution entries, which let the trimmer replace the getter with a constant. The change from expression-bodied (=>) to auto-property initializer ({ get; } =) caches the value at runtime (when not trimmed) without affecting trimmer behavior.

  • RemoteNavigationManager._throwNavigationException
  • HttpNavigationManager._throwNavigationException
  • HotReloadManager.IsSupported (shared source, compiled into 6 assemblies)
  • RegexConstraintSupport.IsEnabled

@pavelsavara pavelsavara added this to the 11.0-preview5 milestone Apr 28, 2026
@pavelsavara pavelsavara self-assigned this Apr 28, 2026
@github-actions github-actions Bot added the area-blazor Includes: Blazor, Razor Components label Apr 28, 2026
Comment thread src/Components/Components/src/Routing/RegexConstraintSupport.cs
@pavelsavara pavelsavara marked this pull request as ready for review May 6, 2026 10:27
Copilot AI review requested due to automatic review settings May 6, 2026 10:28
@pavelsavara pavelsavara requested review from a team and halter73 as code owners May 6, 2026 10:28
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves runtime performance by caching previously-uncached AppContext.TryGetSwitch feature switch reads so hot paths avoid repeated dictionary lookups. It updates a few server/identity/mvc code paths, and adjusts Components feature-switch patterns (including tests) to keep the same behaviors while avoiding per-call switch checks.

Changes:

  • Cache AppContext.TryGetSwitch results into static fields/properties for Authorization middleware, Identity sign-in, and MVC editor templates.
  • Convert several Components feature-switch checks to cached statics while preserving trimming/linker substitution behavior.
  • Update affected tests to override cached values via reflection.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/Security/Authorization/test/AuthorizationMiddlewareTests.cs Updates test to force cached AuthorizationMiddleware switch value via reflection.
src/Security/Authorization/Policy/src/AuthorizationMiddleware.cs Caches the authorization resource compat switch in a static field to avoid per-request lookups.
src/Mvc/Mvc.ViewFeatures/src/DefaultEditorTemplates.cs Caches the password editor template switch in a static field.
src/Identity/Core/src/SignInManager.cs Caches the lockout-reset switch to avoid repeated lookups during sign-in.
src/Components/Shared/src/HotReloadManager.cs Caches hot reload support switch into a mutable static for test override + feature switch definition.
src/Components/Server/src/Circuits/RemoteNavigationManager.cs Caches navigation exception switch using an auto-property initializer.
src/Components/Endpoints/test/EndpointHtmlRendererTest.cs Updates navigation-related test to override cached switch value via reflection.
src/Components/Endpoints/src/DependencyInjection/HttpNavigationManager.cs Caches navigation exception switch in a mutable static for test override + feature switch definition.
src/Components/Components/test/RendererTest.cs Updates hot reload test to override cached switch value via reflection.
src/Components/Components/src/Routing/RegexConstraintSupport.cs Caches regex constraint switch using an auto-property initializer.

Comment thread src/Security/Authorization/test/AuthorizationMiddlewareTests.cs Outdated
Comment thread src/Components/Components/test/RendererTest.cs Outdated
Comment thread src/Components/Endpoints/test/EndpointHtmlRendererTest.cs Outdated
@pavelsavara pavelsavara requested a review from BrennanConroy May 6, 2026 12:10
Comment thread src/Components/Components/test/RendererTest.cs Outdated
@dariatiurina
Copy link
Copy Markdown
Contributor

Added the same pattern that was introduced in PR to newly merged QuickGridFeatureFlag.

@pavelsavara pavelsavara merged commit 31fc9ba into dotnet:main May 12, 2026
25 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-blazor Includes: Blazor, Razor Components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Perf regression: fortunes, fortunes, updates

5 participants