Skip to content

Conversation

@tmat
Copy link
Member

@tmat tmat commented Jul 1, 2025

Adding a package or project reference requires the following steps:

  1. Roslyn validating that the change is allowed (e.g. changing version of preexisting dependency is not allowed since we replace assembly that's already loaded with a new one).
  2. Roslyn determines which projects need redeployment and returns the set in ModuleUpdates (along with projects to rebuild/restart).
    Redeploying means copying dependencies that were added via package/project reference. These dlls are not present in output directory and need to be copied there.
    dotnet-watch executes ReferenceCopyLocalPathsOutputGroup target on these projects.
  3. At runtime the DotNetDeltaApplier needs to implement AssemblyResolving event that loads the new dependencies. These are not automatically loaded by the runtime since they were not present in the .deps.json file when the app launched.

We also need to move managed code update application after dependencies have been built and deployed, otherwise the updated code might start calling to the dependency that's not deployed yet.

@github-actions github-actions bot added the Area-AspNetCore RazorSDK, BlazorWebAssemblySDK, dotnet-watch label Jul 1, 2025
@dotnet-policy-service
Copy link
Contributor

Thanks for your PR, @@tmat.
To learn about the PR process and branching schedule of this repo, please take a look at the SDK PR Guide.

@tmat tmat marked this pull request as ready for review August 13, 2025 17:32
Copilot AI review requested due to automatic review settings August 13, 2025 17:32
@tmat tmat requested a review from a team as a code owner August 13, 2025 17:32
Copy link
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 implements support for changing project and package references in dotnet-watch. The feature allows adding package or project references during Hot Reload sessions, handling the necessary steps of validation, redeployment, and runtime assembly resolution.

Key changes include:

  • Enhanced compilation handler to support dependency deployment alongside managed code updates
  • Added assembly resolution capability to the DotNetDeltaApplier for newly added dependencies
  • Comprehensive test coverage for both project reference and package reference scenarios

Reviewed Changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
test/dotnet-watch.Tests/HotReload/RuntimeProcessLauncherTests.cs Added comprehensive tests for project and package reference addition scenarios
test/TestAssets/TestProjects/WatchAppWithProjectDeps/Dependency/Foo.cs Added console output to support test verification
test/TestAssets/TestProjects/WatchAppWithProjectDeps/AppWithDeps/Program.cs Refactored to support dynamic library calls in tests
src/BuiltInTools/dotnet-watch/UI/IReporter.cs Added message descriptor for project dependency deployment reporting
src/BuiltInTools/dotnet-watch/HotReload/IncrementalMSBuildWorkspace.cs Fixed project reference mapping for newly added projects
src/BuiltInTools/dotnet-watch/HotReload/HotReloadDotNetWatcher.cs Implemented dependency deployment logic and updated flow to apply updates after deployment
src/BuiltInTools/dotnet-watch/HotReload/CompilationHandler.cs Refactored to separate dependency deployment from update application
src/BuiltInTools/dotnet-watch/Build/BuildNames.cs Added constants for dependency deployment target names
src/BuiltInTools/DotNetDeltaApplier/StartupHook.cs Implemented assembly resolution for newly added dependencies at runtime

@tmat
Copy link
Member Author

tmat commented Aug 13, 2025

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@tmat
Copy link
Member Author

tmat commented Aug 14, 2025

@DustinCampbell @phil-allen-msft ptal

Directory.CreateDirectory(directory);
}

File.Copy(sourcePath, targetPath, overwrite: false);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if the file is different? Is it expected that we use the old dependency?

Copy link
Member Author

@tmat tmat Aug 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, if the file exists it might have been loaded already. We could try to overwrite it and catch the exception, but I think that would result in less predictable behavior. The app might load the dependency at any point in time while it's running.

Roslyn will report a rude edit if the assembly version changed. In such scenario we would not get here.
We also don't get here when a referenced project is updated because that produces update delta, not a new binary that needs to be copied over.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense! Thanks for the explanation.

@tmat tmat merged commit d691a1a into dotnet:main Aug 21, 2025
28 checks passed
@tmat tmat deleted the References branch August 21, 2025 19:23
@tmat
Copy link
Member Author

tmat commented Aug 28, 2025

/backport release/10.0.1xx

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area-AspNetCore RazorSDK, BlazorWebAssemblySDK, dotnet-watch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants