-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
cc: @dsplaisted @marcpopMSFT @andschwa @ericstj
Repro Steps
- Create a new netstandard lib
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
</Project>
- Create a new net461 Console app that references it:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net461</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\reproLib\reproLib.csproj" />
</ItemGroup>
</Project>
- Publish the project with
dotnet publish
Expected
Because the net461 project is referencing a netstandard library, tooling should inject all of the netstandard facades onto the publish directory to ensure the application will be able to run as expected. This is what happens with .NET 5.0 and previous sdks.
Actual
bin
directory does get the facades injected, but the publish directory won't when you use a 6.0 SDK, which means that if the app tries to run in a machine that only has .NET 461 installed, the app will likely crash at runtime.
Problem
I took a look and the issue here seems to be caused by this change which basically changed the way we calculate the items to be copied to the publish directory and added an additional filter to check if the ResolveCopyLocal
item had the Private
metadata set to false
. When we are injecting the netstandard facades to resolveCopyLocal item, we explicitly set Private to false, which is why they are now all getting excludded from the publish directory. Here is where we set the metadata to false and the explanation of why we do it:
Lines 91 to 109 in 203c2ac
<ItemGroup Condition="'@(_NETStandardLibraryNETFrameworkLib)' != ''"> | |
<!-- Put each facade assembly in two separate items: Reference with Private set to false, which means it won't be | |
copied locally, and ReferenceCopyLocalPaths, which will be copied locally. The reason for this split is to | |
workaround https://github.com/dotnet/core-setup/issues/2981 by ensuring that the facades are written | |
to the deps.json with a type of "referenceassembly" instead of "reference". | |
The exception is netfx.force.conflicts.dll, which shouldn't be copied local. So it isn't included in | |
ReferenceCopyLocalPaths. | |
When we add the Reference items, we use the simple name as the ItemSpec, and refer to the full path | |
to the DLL via the HintPath metadata. This is so that if we're replacing a simple Reference, | |
the OriginalItemSpec of the resolved reference will match to the Reference that was replaced, | |
and VS won't show a warning icon on the reference. See https://github.com/dotnet/sdk/issues/1499 | |
--> | |
<ReferenceCopyLocalPaths Include="@(_NETStandardLibraryNETFrameworkLib)" Condition="'%(FileName)' != 'netfx.force.conflicts'"> | |
<Private>false</Private> | |
</ReferenceCopyLocalPaths> |
This regression has a potential of great impact, so we should consider how we can fix it before 6.0 ships, whether the solution is to not set Private item to false or if the solution is instead to change the new filter on the publish items.