Skip to content

Cache uncached AppContext.TryGetSwitch calls#66513

Open
pavelsavara wants to merge 7 commits intodotnet:mainfrom
pavelsavara:cache_AppContext_TryGetSwitch
Open

Cache uncached AppContext.TryGetSwitch calls#66513
pavelsavara wants to merge 7 commits intodotnet: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.

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