Skip to content

Adopt MSBuild partial ProjectInstance evaluation in CLI hot paths#55271

Merged
baronfel merged 4 commits into
mainfrom
vihofer/partial-projectinstance-eval
Jul 16, 2026
Merged

Adopt MSBuild partial ProjectInstance evaluation in CLI hot paths#55271
baronfel merged 4 commits into
mainfrom
vihofer/partial-projectinstance-eval

Conversation

@ViktorHofer

Copy link
Copy Markdown
Member

Summary

Adopts MSBuild's new partial (stop-after-pass) evaluation API in dotnet CLI hot paths. Instead of fully evaluating a project just to read a handful of properties or ProjectReference items, these sites now use ProjectInstance.FromFile / ProjectInstance.FromProjectRootElement with a ProjectOptions.EvaluationStage, stopping evaluation after the pass that produces the data they need.

This depends on the MSBuild-side change (dotnet/msbuild#14340, merged), which restricts partial evaluation to ProjectInstance and switched the -getProperty/-getItem CLI paths accordingly. The required API arrived here via Microsoft.Build 18.10.0-1.26363.117.

Why ProjectInstance (not Project)

Project is mutable and cached in a ProjectCollection. A partially-evaluated cached Project would either serve stale state or be silently upgraded to a full evaluation on later access. ProjectInstance is uncached and read-only, so partial instances are trap-proof.

Changes

Site Stage Reads
MsbuildProject.GetEvaluatedProject Properties properties + FullPath
ReleasePropertyProjectLocator.TryGetProjectInstance Properties release properties
ReferenceListCommand Items ProjectReference items
SolutionAddCommand Items ProjectReference items + default project type GUID

Also adds ProjectInstance overloads of GetRuntimeIdentifiers, GetTargetFrameworks, and GetPropertyCommaSeparatedValues.

Validation

dotnet.csproj builds cleanly (0 warnings, 0 errors). Behavior is preserved: all reads occur within their declared evaluation stage, and ProjectInstance.FromFile matches the previous LoadProject(FullPath) semantics for these callers (all use a fresh ProjectCollection with empty global properties).

Use ProjectInstance.FromFile/FromProjectRootElement with a ProjectOptions
EvaluationStage (Properties or Items) to stop evaluation after the pass
that produces the data each site needs, avoiding unnecessary full
evaluation. ProjectInstance is uncached and read-only, so partial
instances cannot be silently upgraded to full or serve stale state
(unlike the mutable, ProjectCollection-cached Project type).

- MsbuildProject/ReleasePropertyProjectLocator: stage Properties.
- ReferenceListCommand/SolutionAddCommand: stage Items.
- Add ProjectInstance overloads of GetRuntimeIdentifiers,
  GetTargetFrameworks, and GetPropertyCommaSeparatedValues.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 008efa7a-b4fc-4f33-9dc7-d37d3f0e93c3
Copilot AI review requested due to automatic review settings July 14, 2026 14:38
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).
2 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 updates several dotnet CLI code paths to use MSBuild’s partial (stop-after-pass) project evaluation API via ProjectInstance.FromFile / ProjectInstance.FromProjectRootElement with ProjectOptions.EvaluationStage, avoiding full evaluation when only properties (or items) are needed. The goal is to reduce overhead in CLI hot paths that previously performed more evaluation work than required.

Changes:

  • Switch project evaluation in CLI helpers from full evaluation / legacy ProjectInstance constructors to ProjectInstance.FromFile / FromProjectRootElement with EvaluationStage set to Properties or Items as appropriate.
  • Cache a single ProjectInstance evaluation in MsbuildProject for repeated property reads (TFM/RID/configuration-related).
  • Add ProjectInstance extension helpers mirroring existing Project extension helpers for property parsing and TFM/RID extraction.
Show a summary per file
File Description
src/Cli/dotnet/ReleasePropertyProjectLocator.cs Uses partial evaluation (Properties stage) when reading PackRelease/PublishRelease-related properties from projects.
src/Cli/dotnet/MsbuildProject.cs Replaces cached Project evaluation with a cached partially-evaluated ProjectInstance for property-only reads.
src/Cli/dotnet/Extensions/ProjectInstanceExtensions.cs Adds ProjectInstance overloads for RID/TFM parsing and comma-separated property parsing.
src/Cli/dotnet/Commands/Solution/Add/SolutionAddCommand.cs Uses Items-stage partial evaluation for reading ProjectReference items and select properties.
src/Cli/dotnet/Commands/Reference/List/ReferenceListCommand.cs Uses Items-stage partial evaluation for listing ProjectReference items.

Copilot's findings

  • Files reviewed: 5/5 changed files
  • Comments generated: 0

@baronfel baronfel left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looks broadly good! I wish we didn't have as much random MSBuild Object Model usage around the codebase, but we can consolidate in a later PR.

@baronfel
baronfel enabled auto-merge (squash) July 14, 2026 18:54
@ViktorHofer

Copy link
Copy Markdown
Member Author

@baronfel hmm any idea what these failures are about? Pre-existing issue or something from my changes?

@baronfel

Copy link
Copy Markdown
Member

AOT build issues? Yeah, those legs shouldn't be running AOT test but are for some reason. I've got a fix in my AOT CLI enablement PR that should land today.

@ViktorHofer

ViktorHofer commented Jul 14, 2026

Copy link
Copy Markdown
Member Author

OK yeah, I see that CI is on the floor in this repo. The failures are elsewhere as well: #55272

@ViktorHofer

ViktorHofer commented Jul 15, 2026

Copy link
Copy Markdown
Member Author

OK, now I'm hitting some other unrelated AOT build failures:

dotnet-aot.obj : fatal error LNK1322: cannot avoid potential ARM hazard (Cortex-A53 MPCore processor bug #843419) in section 0x2; please consider using compiler option /Gy if it was not used [D:\a_work\1\s\src\Cli\dotnet-aot\dotnet-aot.csproj]
D:\a_work\1\s.packages\microsoft.dotnet.ilcompiler\11.0.0-preview.7.26363.117\build\Microsoft.NETCore.Native.targets(427,5): error MSB3073: The command ""C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.44.35207\bin\Hostx64\arm64\link.exe" @"D:\a_work\1\s\artifacts\obj\dotnet-aot\Release\net11.0\win-arm64\native\link.rsp"" exited with code 1322. [D:\a_work\1\s\src\Cli\dotnet-aot\dotnet-aot.csproj]
0 Warning(s)
2 Error(s)

@baronfel

Copy link
Copy Markdown
Member

That's only on the windows-arm leg, which is lower prio. What I was gonna do this morning was skip that job and pull in the runtime/linker teams because it seems to be an issue with the linker on ARM specifically.

@ViktorHofer

Copy link
Copy Markdown
Member Author

Maybe someone can let me know when the CI is green again for this PR to get merged. cc @marcpopMSFT

@baronfel

Copy link
Copy Markdown
Member

Working through this over at #55144, hopefully ready in the next hour.

@baronfel

Copy link
Copy Markdown
Member

Fixed in a better way by #55302.

@baronfel
baronfel merged commit 4a5be3c into main Jul 16, 2026
27 checks passed
@baronfel
baronfel deleted the vihofer/partial-projectinstance-eval branch July 16, 2026 08:57
@dotnet-milestone-bot dotnet-milestone-bot Bot added this to the 11.0-preview7 milestone Jul 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants