Fix hot reload for Blazor route changes #63972
Merged
+87
−109
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Fixes two bugs that prevented hot reload from applying changes in Blazor routes.
Premature change token disposal
A bug introduced in #53750 caused the change token used by
RazorComponentEndpointDataSource
to be disposed before the callback registered on the token is invoked. This means thatUpdateEndpoints
is not being called at all during hot reload.This PR does not remove the token disposal so that the memory leak is not re-introduced. Instead, the PR moves the disposal of the current token to
UpdateEndpoints
itself. This is valid because the role of the change token is precisely to trigger the update and the token is replaced at the end ofUpdateEndpoints
with a new one (as before).Stale route data
The first bug was previously hiding a further problem in how we cache route data used by the main ASP.NET Core routing. This data was computed once during application start up and then reused in every
UpdateEndpoints
invocation. This means that we did not re-scan the assemblies for added, modified, or removed routes.The PR changes the implementation of
RazorComponentEndpointDataSource
and related types so that we do not store a pre-built instance ofComponentApplicationBuilder
. Instead we store a list of configuration actions that were invoked for the currentRazorComponentEndpointDataSource
. When the route data needs to be updated, these actions are replayed on a newComponentApplicationBuilder
instance, thus ensuring an up-to-date state. Note that this follows the same pattern as we already use for endpoint conventions.Result
After the change, hot reload works as expected in the following scenarios:
Hot reload still does not work when deleting a page with route.
Fixes #52582