Skip to content

Visual Studio restore is broken as projects are missing from the dependency closure #65552

@ViktorHofer

Description

@ViktorHofer

Since I applied various fixes to the product over the last weeks that should make the overall IDE experience better I wanted to try them out and had to realize with dismay that the integrated Visual Studio restore is still broken if an upfront restore via the CLI (dotnet restore) isn't performed. The impact of that is that the solution is unusable.

The root cause for that lies in this code path:

<!-- Don't include reference projects which compose the microsoft.netcore.app targeting pack (except the current leaf's reference project) as those are referenced by the source project via named references
and hence don't need to be part of the solution file (only P2Ps need to).
Include the reference project in the solution file if it targets more than just NetCoreAppCurrent as other frameworks like .NETFramework, .NETStandard or older .NETCoreApp ones require it. -->
<IncludeInSolutionFile Condition="'$(IsNETCoreAppRef)' == 'true' and '$(MSBuildProjectName)' != '$(SlnGenMainProject)' and '$(TargetFramework)' == '$(NetCoreAppCurrent)' and ('$(TargetFrameworks)' == '' or '$(TargetFrameworks)' == '$(NetCoreAppCurrent)')">false</IncludeInSolutionFile>
This causes slngen to not include reference projects which are part of the shared framework and aren't shipping out-of-band. Even though, shared framework reference assemblies are only referenced via "Reference" items by source projects, the reference projects themselves reference each other via ProjectReferences. Note that VS restore requires all dependencies expressed via ProjectReference items to be present in the solution file and ignores Reference items as those point to the compiled assembly and there's nothing for restore to do on those.

As an example, ref/System.Drawing.Common.csproj inside System.Runtime.sln is depending on ref/System.Collections.NonGeneric.csproj but as it is missing, the restore inside Visual Studio fails.

If I remove the condition in the slngen.targets file and re-generate all solution files (dotnet.cmd build src\libraries\slngen.proj), the solution files get larger by about 50 ref projects (as the solution now includes all dependencies) but the solution restore finally works and no up-front restore is necessary anymore. Note that because the reference projects are very small and fast to evaluate, the solution load time doesn't increase noticeably and the solution doesn't look overloaded as all the added projects are grouped inside the "ref" folder (tested with VS 2022 17.2 Preview 1).

Because of that I propose that we remove the condition in the slngen.targets file with the caveat that solutions get bigger but with the huge win that up-front restores aren't necessary anymore. That means instead of:

build.cmd libs.sfx /p:RefOnly=true
build.cmd -restore libs
build.cmd -vs System.Runtime

I can now directly open VS after the libs.ref subset is built:

build.cmd libs.sfx /p:RefOnly=true
start src\libraries\System.Runtime\System.Runtime.sln

or just continue to use the VS switch for convenience (which also uses the repo local SDK which is useful when a matching one isn't globally installed):

build.cmd libs.sfx /p:RefOnly=true
build.cmd -vs System.Runtime

Ultimately at some point in the future when source projects use ProjectReference items instead of Reference items to dynamically express their dependencies, the build.cmd libs.ref step won't be necessary anymore either and a dev will be able to directly open a VS solution file from a fresh clone.

@ericstj @safern @joperezr @carlossanlop any objections to what I'm proposing?

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions