Skip to content

ProjectReference transitive dependencies #4717

@joeltankam

Description

@joeltankam

Steps to reproduce

Let's consider these 3 project files :

ProjectA

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net471</TargetFramework>
  </PropertyGroup>
</Project>

ProjectB

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net471</TargetFramework>
  </PropertyGroup>
  <ItemGroup>
    <ProjectReference Include="..\ProjectA\ProjectA.csproj" />
  </ItemGroup>
</Project>

ProjectC

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net471</TargetFramework>
  </PropertyGroup>
  <ItemGroup>
    <ProjectReference Include="..\ProjectB\ProjectB.csproj" />
  </ItemGroup>
</Project>

The 3 projects depends on each other as follows : ProjectC -(depends on)-> ProjectB -> ProjectA

Expected behavior

ProjectC should not be able to use elements from ProjectA (public classes for example) since it doesn't reference this project directly.

Actual behavior

ProjectC has access to ProjectA via transitivity as it can be seen in his assets file :

{
      ...
      "ProjectA/1.0.0": {
        "type": "project",
        "framework": ".NETFramework,Version=v4.7.1",
        "compile": {
          "bin/placeholder/ProjectA.dll": {}
        },
        "runtime": {
          "bin/placeholder/ProjectA.dll": {}
        }
      },
      "ProjectB/1.0.0": {
        "type": "project",
        "framework": ".NETFramework,Version=v4.7.1",
        "dependencies": {
          "ProjectA": "1.0.0"
        },
        "compile": {
          "bin/placeholder/ProjectB.dll": {}
        },
        "runtime": {
          "bin/placeholder/ProjectB.dll": {}
        }
      }
      ...
}

As mentioned in dotnet/project-system#2313, it appears that this behavior can be cancelled by using PrivateAssets, from PackageReference dependency assets, when referencing ProjectA :

  <ItemGroup>
    <ProjectReference Include="..\ProjectA\ProjectA.csproj" PrivateAssets="all" />
  </ItemGroup>

Using ExcludeAssets when referencing ProjectB also works :

  <ItemGroup>
    <ProjectReference Include="..\ProjectB\ProjectB.csproj" ExcludeAssets="all" />
  </ItemGroup>

However, these metadatas are originally applicable only for PackageReference and I can't find any documentation of this behavior for ProjectReference (in the ProjectReference item reference for example).
So, should this (PrivateAssets or ExcludeAsssets) be really used in ProjectReference tag ?

Environment data

msbuild /version output: 15.9.21.664
Visual Studio : Professional 2017, version 15.9.15

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions