Fix culture persistence to not have public API#67367
Conversation
There was a problem hiding this comment.
Pull request overview
This PR removes the unshipped public options/configuration surface for interactive WebAssembly culture persistence and replaces it with an internal options type driven by the Components:UseCultureFromServer configuration key.
Changes:
- Removes
WebAssemblyComponentsOptionsand theAddInteractiveWebAssemblyComponents(..., Action<WebAssemblyComponentsOptions>?)overload, leaving only the parameterlessAddInteractiveWebAssemblyComponents(). - Introduces internal
WebAssemblyComponentsServiceOptionsplus anIPostConfigureOptions<>to readComponents:UseCultureFromServer. - Updates the test server startup to set
Components:UseCultureFromServervia configuration, and updatesPublicAPI.Unshipped.txtaccordingly.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/Components/WebAssembly/Server/src/WebAssemblyRazorComponentsBuilderExtensions.cs | Removes the public overload and switches culture capture behavior to be driven by internal options/config. |
| src/Components/WebAssembly/Server/src/WebAssemblyComponentsServiceOptionsConfiguration.cs | Adds post-configure hook to read Components:UseCultureFromServer from configuration. |
| src/Components/WebAssembly/Server/src/WebAssemblyComponentsServiceOptions.cs | Adds internal options container (defaults UseCultureFromServer to true). |
| src/Components/WebAssembly/Server/src/WebAssemblyComponentsOptions.cs | Removes the (unshipped) public options type. |
| src/Components/WebAssembly/Server/src/PublicAPI.Unshipped.txt | Removes unshipped public API entries for the deleted options type and overload. |
| src/Components/test/testassets/Components.TestServer/RazorComponentEndpointsStartup.cs | Updates test server wiring to set the new configuration key instead of using the removed overload. |
ilonatommy
left a comment
There was a problem hiding this comment.
I will push a draft PR with the cleanup proposal.
ilonatommy
left a comment
There was a problem hiding this comment.
I added allocation removal and cleanup ideas. The issue with setting false from config gave me an idea to check the test coverage. It looks like we have a few gaps. To keep it cheap they should be unit tests.
It would be good to cover the matrix with dimensions: config true/false/not configured, config 1/0, config True/False/garbage e.g. "yes", service registered/not registered.
Fix culture persistence to not have public API
Summary
Reworks how interactive WebAssembly culture persistence is configured so it no longer requires a public API surface, and changes the default behavior. Instead of a public options class and a configuration callback overload (defaulting culture capture on), culture capture is now opt-in and driven by the
Components:UseCultureFromServerconfiguration value, with a fallback based on whether localization is registered.Changes
WebAssemblyComponentsOptionsclass and itsUseCultureFromServerproperty.AddInteractiveWebAssemblyComponents(this IRazorComponentsBuilder, Action<WebAssemblyComponentsOptions>?)overload. Only the parameterless AddInteractiveWebAssemblyComponents()` remains.WebAssemblyComponentsServiceOptionswith a nullableUseCultureFromServerproperty.WebAssemblyComponentsServiceOptionsConfiguration, anIPostConfigureOptions<WebAssemblyComponentsServiceOptions>that reads theComponents:UseCultureFromServerconfiguration value and sets the option totruewhen the value is"true"or"1"(case-insensitive).Microsoft.Extensions.Localization.Abstractionsreference to the project so the registration can probe forIStringLocalizerFactory.PublicAPI.Unshipped.txtto drop the removed public API entries.Components.TestServerstartup to setComponents:UseCultureFromServervia configuration instead of using the removed callback overload.Details
CultureStateProvideris now always registered as a scoped service and always added as a persistent component state registration forRenderMode.InteractiveWebAssembly. Previously both registrations were conditional onUseCultureFromServerbeingtrue.CaptureCurrentCulture()when culture capture is enabled, computed as:options.UseCultureFromServer ?? (IStringLocalizerFactory is registered).This honors an explicit
Components:UseCultureFromServerconfiguration value, and otherwise falls back to enabling culture capture when localization has been added (sinceAddLocalizationregistersIStringLocalizerFactory).Behavior Change
WebAssemblyComponentsOptions.UseCultureFromServerdefaulted totrue). Now culture is only captured whenComponents:UseCultureFromServeris explicitly enabled, or — when not explicitly configured — when localization (IStringLocalizerFactory) is registered. Apps that relied on the previous always-on behavior must now opt in via theComponents:UseCultureFromServerconfiguration value or by adding localization.Testing
RazorComponentEndpointsStartupnow toggles the behavior through theComponents:UseCultureFromServerconfiguration key ("true"/"false") based on the existingEnforceServerCultureOnClientsetting, exercising the new configuration path through the existing E2E culture scenarios.Breaking Changes
WebAssemblyComponentsOptionsand theAction<WebAssemblyComponentsOptions>?overload) is removed. These were unshipped (noPublicAPI.Shipped.txtentries), so no released package is affected. Consumers configuring this behavior should now set theComponents:UseCultureFromServerconfiguration value instead of passing an options callback.Fixes #66829