[Hot Reload] Add $(HotReloadCompatibleBuild) MSBuild property + assembly-preparer safety net
- Dominant language
- C#
- Stars
- 2.9k
- Forks
- 576
- Avg merge
- 2d 12h
- Merged PRs (30d)
- 123
Description
Part of #26069.
## Goal
Introduce a single MSBuild property that expresses "this build must not modify user (reloadable) assemblies", and add a safety net that enforces it. This is the foundation the other sub-tasks of #26069 build on.
## Background
Hot Reload works if and only if `$(PrepareAssemblies)` is `true` (the standalone assembly-preparer runs the steps outside the trimmer, where `MarkHandler`s are unavailable). For Hot Reload to keep working, the trimmable static registrar (`Registrar=trimmable-static`) must not modify user/reloadable assemblies.
The grounded invariant: `SaveAssembliesStep` only re-serializes an assembly if it is in `configuration.ModifiedAssemblies` (`tools/assembly-preparer/SaveAssembliesStep.cs:44-49`); that set is populated via the `AppBundleRewriter.AssemblySaved` callback fired by `SaveAssembly` (`tools/assembly-preparer/AssemblyPreparer.cs:236-241`). So:
> No preparer step may call `AppBundleRewriter.SaveAssembly` on a user/reloadable (Copy) assembly.
## Tasks
- [ ] Add a `$(HotReloadCompatibleBuild)` MSBuild property, defaulting to `true` for Debug builds (and `false` otherwise), so that release builds keep their current behaviour/app size — Hot Reload is a debug-only feature.
- [ ] Flow the property into the linker/assembly-preparer configuration (e.g. via `LinkerConfiguration`).
- [ ] Define precisely what a "reloadable/user assembly" is (candidate: a non-SDK, non-product, non-generated assembly whose action is `Copy`, i.e. not being trimmed).
- [ ] Add a safety-net assertion in `AppBundleRewriter.SaveAssembly` (and/or the `AssemblySaved` callback) that throws when a reloadable assembly would be saved while `HotReloadCompatibleBuild` is enabled. This makes any regression fail loudly.
- [ ] Document the new property in `docs/building-apps/build-properties.md`.
## Notes
The other sub-tasks (PreserveSmartEnumConversionsStep, ManagedRegistrarStep, InlineDlfcnMethodsStep, RemoveUserResourcesSubStep) all gate their new no-modification behaviour on this property.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with tools/assembly-preparer/SaveAssembliesStep.cs and tools/assembly-preparer/AssemblyPreparer.cs, then trace AppBundleRewriter.SaveAssembly and the LinkerConfiguration flow. Define the reloadable assembly condition from the issue, add the Debug-default property and safety check, and document it in docs/building-apps/build-properties.md; done means reloadable assemblies are not saved when compatibility is enabled and violations fail loudly.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- build-system
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100