Transitive references in .Net Core 1.1
Asked Answered
P

3

20

While developing a sample web app in .NET Core 1.1 and Visual Studio 2017 RC, I realized the following:

enter image description here

As you can see:

  • ClassLibrary3 has a reference to ClassLibrary2,
  • and ClassLibrary2 has a reference to ClassLibrary1

I wrote a simple method in class Class3 of ClassLibrary3 project, and the Intellisense allowed me to use Class1 just writing the name of the class, I mean, without doing an explicit reference to ClassLibrary1 project.

Am I missing some point here? I don't want somebody simply comes and overlooks ClassLibrary2.

Thanks.

Pericynthion answered 24/2, 2017 at 0:11 Comment(4)
ClassLibrary1 is included in ClassLibrary3 due to the fact that it is needed by ClassLibrary2, so of course Class1 is available there. You just need to add using ClassLibrary as it says. You may need to clarify what your goal is - what are you trying to achieve?Dulcia
Well, I can't remember if previous versions of Visual Studio/.NET worked like that. I think it was mandatory to reference directly a project to be able to use its elements, not just having a transitive reference.Pericynthion
I found a possible solution for this question: ardalis.com/…Pericynthion
.NET Framework projects do not work like this. In .NET Framework, if A references B and B references C, that doesn't mean A references C. They changed this in .NET Core projects. I don't like this because A may not want to use C. The other day, a coworker accidentally used an extension method in a NuGet package that his project did not reference, a method named after something in Linq.Enumerable. ReSharper offered to "import missing references in file" so the coworker never saw the unexpected namespace. Plus, in theory, A's build can break if C creates a name collision somewhere.Orrin
B
11

Transitive project-to-project references are a new feature of Visual Studio 2017 and Microsoft.NET.Sdk. This is intentional behavior.

See https://github.com/dotnet/sdk/issues/200.

Bramante answered 24/2, 2017 at 5:18 Comment(2)
Nice. I suppose that now it will be more clear the dependency that UI layers have on Data layers in traditional 3-layered architectures.Pericynthion
How is a UI supposed to get access to data if it doesn't at some point have a dependency on the data layer?Unskillful
C
11

If you're interested in disabling the transitive reference behavior, I finally found a way.

If you want Project A to reference B and B to reference C, but don't want A to reference C, you can add PrivateAssets="All" to B's ProjectReference to C, like so:

In B.csproj

<ItemGroup>
  <ProjectReference Include="..\C\C.csproj" PrivateAssets="All" />
</ItemGroup>

This setting makes C's reference private so it only exists within B. Now projects that reference B will no longer also reference C.

Source: https://github.com/dotnet/project-system/issues/2313

Chappell answered 30/9, 2017 at 4:3 Comment(0)
D
2

You have two options.

  1. In ClassLibrary1.csproj use DisableTransitiveProjectReferences property

    <Project Sdk="Microsoft.NET.Sdk">
        <PropertyGroup>
            <TargetFramework>netcoreapp3.1</TargetFramework>
            <DisableTransitiveProjectReferences>true</DisableTransitiveProjectReferences>
        </PropertyGroup>
        <ItemGroup>
            <ProjectReference Include="..\ClassLibraryCore2\ClassLibraryCore2.csproj" />
        </ItemGroup>
    </Project>
    
  2. In ClassLibrary2.csproj use PrivateAssets="All"

    <Project Sdk="Microsoft.NET.Sdk">
        <PropertyGroup>
            <TargetFramework>netcoreapp3.1</TargetFramework>
        </PropertyGroup>
        <ItemGroup>
            <ProjectReference Include="..\ClassLibraryCore3\ClassLibraryCore3.csproj" 
                PrivateAssets="All" />
        </ItemGroup>
    </Project>
    

I explained the difference more in other answer.

Ducal answered 25/3, 2020 at 15:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.