dotnet / sdk

Core functionality needed to create .NET Core projects, that is shared between Visual Studio and CLI
https://dot.net/core
MIT License
2.67k stars 1.06k forks source link

[Bug]: ProjectReference.ExcludeAssets ignored for transitive dependencies #42708

Open gthvidsten opened 1 month ago

gthvidsten commented 1 month ago

Issue Description

This is sort of an inverse of dotnet/msbuild#4717 .

If you have a project, C, that depends on project B, and project B depends on project A (C -> B -> A) and you have the project reference in project C set up like this:

<ProjectReference Include="..\B\ProjectB.csproj">
    <Private>false</Private>
    <ExcludeAssets>runtime</ExcludeAssets>
</ProjectReference>

Then ProjectB.dll is not copied to the output folder, as expected, but ProjectA.dll is copied.

I have tried adding <DisableTransitiveProjectReferences>true</DisableTransitiveProjectReferences> to the project definition in ProjectC.csproj, but then I'm not allowed to use code defined in ProjectA.csproj.

Steps to Reproduce

Expected Behavior

When <ExcludeAssets>runtime</ExcludeAssets> is set on a project reference none of its assets, transitive or not, should be copied to the bin folder

Actual Behavior

The transitive dependency to ProjectA.dll is copied to the bin folder, while ProjectB.dll is not

Analysis

No response

Versions & Configurations

Visual Studio Professional 2022 (17.10.4)

MSBuild version 17.10.4+10fbfbf2e for .NET Framework 17.10.4.21802

Windows 11 23H2 22631.3958

rainersigwald commented 1 month ago

Moving to SDK since the transitive-to-direct-reference-promotion behavior is defined there.

jdrst commented 2 weeks ago

We're also experiencing this behaviour. This only seems to affect ProjectReferences and not PackageReferences (in Project B).

Have you, by chance, found a feasible workaround @gthvidsten?

gthvidsten commented 2 weeks ago

@jdrst I don't know how feasible a workaround this would be for you, but for my project I could include the transitive dependency directly (so that is was no longer transitive) and setting the same Private and ExcludeAssets elements to the ProjectReference. I now had specific control over this project and how it was copied to the output folder (or not). Fortunately this project had no other transitive project references.

This workaround has to be done for every transitive project reference, so if you have many of those then the project references could quickly become unmanagable.

jdrst commented 2 weeks ago

yeah, i was afraid that that would be the answer :( thank you for your response nonetheless!