msbuild icon indicating copy to clipboard operation
msbuild copied to clipboard

[Feature Request]: Remove duplicate (Unnecessary) Project Reference in .NET Solution

Open HakamFostok opened this issue 2 years ago • 1 comments

Summary

I have asked this on Stackoverflow, and here is the situation.

I have a .NET solution which contains about 20 projects, and I am using a layered architecture.

Suppose project A will reference Project B.
Project B will reference projects C, D, E and F.
. Projects C, D, E and F all reference the G project.
and G project references H project.

Now I have a path from project A to project H and I can use its types. What I wanted to do to avoid unnecessary <ProjectReference> tags.

For example, there is no need to reference the project H directly from A, B, C, D, E, and F projects, because all of them have reference to it indirectly by referencing G project.

MS-build does not appear to produce any warning, about those duplicated (unnecessary) <ProjectReference>

Should we have this feature?

Background and Motivation

Motivation is the principle of Least Privileges, If anything changes at the bottom of the dependency graph (say project H removed), it would be better to the give error immediately, otherwise than project in above layer turn its dependency from unnecessary to required.

I would really like to do that on the csproj level, even though I belive Msbuild do remove unnecessary project references internally without surfacing them to the user. I want to match my csproj files with the real situation.

That will remove the clutter from the csproj and will enhance the readability and the understandability of it, by removing project references that are just a not needed.

Proposed Feature

Generate warnings when unnecessary <ProjectReference> tag included in a project already has reference indirectly to that project mentioned in the in the <ProjectReference> tag

Alternative Designs

none

HakamFostok avatar Jan 28 '24 14:01 HakamFostok

In order to prevent breaking through the layering separation of SDK style projects you should be using DisableTransitiveProjectReferences (for ProjectReference) or PrivateAssets (for PackageReference). This will immediately uncover and prevent any unwanted bypassing of the layering. Any other option will not prevent the default transitive accessibility that can lead to unitended dependencies.

More info on controling the dependencies behavior through MSBuild: https://github.com/dotnet/msbuild/blob/main/documentation/wiki/Controlling-Dependencies-Behavior.md

This update applies specifically to your case: https://github.com/dotnet/msbuild/pull/9652/files#diff-b5dec84f84d1f113f1c8d8369daf2a8b4958736d3e02764f3bfbd42e42c4a917R9

All that being said - the explicit warning might actually flag good intentions that can be considered good practice (where required dependency is explicitly declared via ProjectReference, despite being accessible transitively). We might however soon give you a lever to flag the pattern in your projects - via allowing to author and mount custom MSBuild analyzers.

JanKrivanek avatar Jan 28 '24 20:01 JanKrivanek

Based on current description - this is intended and desired behavior, so closing as 'not a bug'

JanKrivanek avatar Feb 23 '24 10:02 JanKrivanek