Repository navigation
fix(builder): keep the view locator's mappings and leave global state alone on a second build - #4490
Merged
Merged
Conversation
…ocator ConfigureViewLocator registered IViewLocator as a transient factory, so every resolve built a new DefaultViewLocator and reran the configure action. Mappings added by RegisterViews or WithViewModule, or on a resolved locator, were lost. The action now runs once on the registered DefaultViewLocator, or on a new one registered as the single IViewLocator when none is registered.
Splat's AppBuilder applies only the first build in a process and skips the registrations of later builds. ReactiveUIBuilder.Build still replaced the global converter service, message bus, exception handler, suspension host and cache sizes with the later builder's values. A later build now changes none of them.
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #4490 +/- ##
=======================================
Coverage 93.37% 93.38%
=======================================
Files 168 168
Lines 6309 6317 +8
Branches 723 724 +1
=======================================
+ Hits 5891 5899 +8
Misses 417 417
Partials 1 1 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.



Summary
ConfigureViewLocatorconfigures the view locator the app resolves, and a second build leaves global state alone.ConfigureViewLocatorruns its action once, on the registeredDefaultViewLocator. Mappings added withRegisterViews,WithViewModuleor on a resolved locator are kept, and resolvingIViewLocatortwice returns the same instance. When noDefaultViewLocatoris registered, a new one is configured and registered as the singleIViewLocator.Build()/BuildApp()in a process changes global state. A later build no longer replaces the global converter service, message bus, exception handler, suspension host or cache sizes, matching the Splat builder, which already skips that build's registrations.Why
ConfigureViewLocatorregistered a factory that built a new locator on every resolve, and a second build half-applied.IViewLocatorproduced a newDefaultViewLocatorand reran the configure action, so views mapped withRegisterViewsorWithViewModuleresolved tonull.BindingConverters.CurrentandMessageBus.Current, so the first builder's custom converters stopped resolving.Closes #4486
Closes #4487
Breaking changes
None for an app that builds once.
AppBuilderbuilds before ReactiveUI's builder, ReactiveUI's builder no longer sets its static state or marks ReactiveUI as initialized. Its registrations were already skipped in that case.How this was verified
Tests cover a single resolved locator instance that keeps
RegisterViewsmappings and runs the configure action once, and a second build that leaves the first build's converter service and message bus in place.Notes for the reviewer
Two commits, one per fix.
ReactiveUIBuilder.cs:ConfigureViewLocatorreads the registered locator throughCurrent, the same wayConfigureSuspensionDriverdoes.ReactiveUIBuilder.Build.cs:HasBeenBuiltis read beforebase.Build(), and the method returns right after it when a build already happened. Treating the first build as the one that counts follows Splat's documented "later builds have no effect".BuilderMixinsforwarders are reported in 30 BuilderMixins extension methods can never be chosen by extension syntax, and BuilderMixins.ForCustomPlatform behaves differently from the member it shadows #4488 and left alone here, because removing them is a public API decision.Checklist