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.73k stars 1.07k forks source link

DisableTransitiveProjectReferences does not appear to work #42947

Closed nbarnwell closed 2 months ago

nbarnwell commented 2 months ago

The bug

I have a project that references another project that references yet another project. ProjectC->ProjectB->ProjectA. All have an appsettings.json file. Every other time I build, the bin folder for ProjectC contains the appsettings.json file for ProjectA, instead of it's own. I've been unable to work out why it's every other time, but in my travels found Github issues and documentation for DisableTransitiveProjectReferences. However, I've added that property all the projects and it's made no difference.

I realise you need a repro, so I made a simple repro project at https://github.com/nbarnwell/DisableTransitiveProjectReferencesTest. This seems to indicate the property isn't having the desired effect, although of course doesn't help with my 50/50 problem - I'll worry about that separately if I can at least get this sample project to respect it.

To Reproduce

See https://github.com/nbarnwell/DisableTransitiveProjectReferencesTest. If you run the project you should see "Setting value = Value1" written to the console window, but actually you see "Setting value = Value2". "Value1" and "Value2" come from the main and library projects respectively.

Further technical details

Dotnet --version

.NET SDK: Version: 8.0.304 Commit: 352dc5a01f Workload version: 8.0.300-manifests.1c0291f2 MSBuild version: 17.10.4+10fbfbf2e

Runtime Environment: OS Name: Windows OS Version: 10.0.22631 OS Platform: Windows RID: win-x64 Base Path: C:\Program Files\dotnet\sdk\8.0.304\

.NET workloads installed: [android] Installation Source: SDK 8.0.300, VS 17.10.35027.167 Manifest Version: 34.0.113/8.0.100 Manifest Path: C:\Program Files\dotnet\sdk-manifests\8.0.100\microsoft.net.sdk.android\34.0.113\WorkloadManifest.json Install Type: FileBased

[aspire] Installation Source: SDK 8.0.300, VS 17.10.35027.167 Manifest Version: 8.0.2/8.0.100 Manifest Path: C:\Program Files\dotnet\sdk-manifests\8.0.100\microsoft.net.sdk.aspire\8.0.2\WorkloadManifest.json Install Type: FileBased

[ios] Installation Source: SDK 8.0.300, VS 17.10.35027.167 Manifest Version: 17.2.8078/8.0.100 Manifest Path: C:\Program Files\dotnet\sdk-manifests\8.0.100\microsoft.net.sdk.ios\17.2.8078\WorkloadManifest.json Install Type: FileBased

[maccatalyst] Installation Source: SDK 8.0.300, VS 17.10.35027.167 Manifest Version: 17.2.8078/8.0.100 Manifest Path: C:\Program Files\dotnet\sdk-manifests\8.0.100\microsoft.net.sdk.maccatalyst\17.2.8078\WorkloadManifest.json Install Type: FileBased

[maui-windows] Installation Source: SDK 8.0.300, VS 17.10.35027.167 Manifest Version: 8.0.61/8.0.100 Manifest Path: C:\Program Files\dotnet\sdk-manifests\8.0.100\microsoft.net.sdk.maui\8.0.61\WorkloadManifest.json Install Type: FileBased

Host: Version: 8.0.8 Architecture: x64 Commit: 08338fcaa5

.NET SDKs installed: 5.0.408 [C:\Program Files\dotnet\sdk] 8.0.206 [C:\Program Files\dotnet\sdk] 8.0.303 [C:\Program Files\dotnet\sdk] 8.0.304 [C:\Program Files\dotnet\sdk]

.NET runtimes installed: Microsoft.AspNetCore.App 3.1.32 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 5.0.17 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 7.0.20 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 8.0.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 8.0.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 8.0.8 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.NETCore.App 3.1.32 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 5.0.17 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 6.0.33 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 7.0.20 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 8.0.6 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 8.0.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 8.0.8 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.WindowsDesktop.App 3.1.32 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 5.0.17 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 6.0.33 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 7.0.20 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 8.0.6 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 8.0.7 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 8.0.8 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

Other architectures found: x86 [C:\Program Files (x86)\dotnet] registered at [HKLM\SOFTWARE\dotnet\Setup\InstalledVersions\x86\InstallLocation]

Environment variables: Not set

global.json file: Not found

Learn more: https://aka.ms/dotnet/info

Download .NET: https://aka.ms/dotnet/download

IDE

KalleOlaviNiemitalo commented 2 months ago

The DisableTransitiveProjectReferencesTest solution contains two projects: DisableTransitiveProjectReferencesTest and ExternalLibrary. The DisableTransitiveProjectReferencesTest project references the ExternalLibrary project, which doesn't reference any project. There is only project reference and that one is direct; there is no transitive reference that the DisableTransitiveProjectReferences or MSBuildCopyContentTransitively (https://github.com/dotnet/msbuild/pull/4865) property could affect.

Setting the property <_GetChildProjectCopyToOutputDirectoryItems>false</_GetChildProjectCopyToOutputDirectoryItems> would disable the copying of content from directly referenced projects too; but it seems undocumented and I don't know whether it will keep working in future versions.

nbarnwell commented 2 months ago

The DisableTransitiveProjectReferencesTest solution contains two projects: DisableTransitiveProjectReferencesTest and ExternalLibrary. The DisableTransitiveProjectReferencesTest project references the ExternalLibrary project, which doesn't reference any project. There is only project reference and that one is direct; there is no transitive reference that the DisableTransitiveProjectReferences or MSBuildCopyContentTransitively (dotnet/msbuild#4865) property could affect.

Setting the property <_GetChildProjectCopyToOutputDirectoryItems>false</_GetChildProjectCopyToOutputDirectoryItems> would disable the copying of content from directly referenced projects too; but it seems undocumented and I don't know whether it will keep working in future versions.

Excellent point - I had been picturing the "transitive dependency" as being the files I didn't want in the dependency project, not a third dependency project entirely.

You mention _GetChildProjectCopyToOutputDirectoryItems, which on the face of it sounds like what I want, but I agree the name and undocumented nature of it makes it sound like I shouldn't lean on it.

Some people seem to have fallen back to adding new post-build targets to their csproj files that re-copy their appsettings.json file to ensure it's placed over the top of any unwanted appsettings.json files brought in from other projects. Google searches indicate lots of people having the same problem, so I might close this issue is it's the wrong question to ask, and raise a new one specifically asking for the idiomatic way to prevent one's appsettings.json (and other matching content files) being brought in incorrectly.