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
ProjectC should not be able to use elements from ProjectA (public classes for example) since it doesn't reference this project directly.
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 https://github.com/dotnet/project-system/issues/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 ?
msbuild /version output: 15.9.21.664
Visual Studio : Professional 2017, version 15.9.15
Any update on the topic please ?
You could use <DisableTransitiveProjectReferences>true</DisableTransitiveProjectReferences> to turn this off for Project to project references.
Ok, thanks.
I'll try that.
@livarcocc <DisableTransitiveProjectReferences>true</DisableTransitiveProjectReferences> works fine as far as compilation is concerned.
However, ProjectA is still present in ProjectC asset file (same as mentioned in the description); which is a false information since this dependency doesn't exist anymore at compile time.
Any update please ?
<DisableTransitiveProjectReferences>true</DisableTransitiveProjectReferences>
and
<Private>false</Private>
<ExcludeAssets>all</ExcludeAssets>
seems to work to me
You could use
<DisableTransitiveProjectReferences>true</DisableTransitiveProjectReferences>to turn this off for Project to project references.
@thank you @livarcocc It works perfect.
Do you know if there is any documentation for this settings? I cannot find anything. I also don't know when it was introduced (in which version of MSBuild/SDK/VisualStudio?)
Not sure if you are the right person to ask, but just to clarify I have some questions:
So this DisableTransitiveProjectReferences setting changes ProjectReference behavior in new SDK-csproj to be the same as in old csproj where ProjectReference wasn't transitive but the transitive projects' .dlls were copied to bin folder ?
Is the effect the same as setting PrivateAssets="All" on all the dependencies of dependand project? Just that with DisableTransitiveProjectReferences you control this behavior in different place, on project that reference other projects, not on project that might be referenced by other projects.
In other word PrivateAssets="All" is more flexible and fine-grained and you can achieve the same end result like with DisableTransitiveProjectReferences but DisableTransitiveProjectReferences is just more useful if you prefer "old non-SDK csproj" non-transitive behavior of ProjectReferences (or if you are in process of migrating to .NET Core or SDK-style csproj)
Most helpful comment
@thank you @livarcocc It works perfect.
Do you know if there is any documentation for this settings? I cannot find anything. I also don't know when it was introduced (in which version of MSBuild/SDK/VisualStudio?)
Not sure if you are the right person to ask, but just to clarify I have some questions:
So this
DisableTransitiveProjectReferencessetting changesProjectReferencebehavior in new SDK-csproj to be the same as in old csproj whereProjectReferencewasn't transitive but the transitive projects'.dllswere copied tobinfolder ?Is the effect the same as setting
PrivateAssets="All"on all the dependencies of dependand project? Just that withDisableTransitiveProjectReferencesyou control this behavior in different place, on project that reference other projects, not on project that might be referenced by other projects.In other word
PrivateAssets="All"is more flexible and fine-grained and you can achieve the same end result like withDisableTransitiveProjectReferencesbutDisableTransitiveProjectReferencesis just more useful if you prefer "old non-SDK csproj" non-transitive behavior ofProjectReferences (or if you are in process of migrating to .NET Core or SDK-style csproj)