I'm looking to use multi-targeting for some common projects that need to compile both to .NET Standard 2.0 (for legacy .NET Framework 4.8 projects) and to .NET 6.0 (for new projects). Some of the dependencies of these common projects need to be referenced conditionally. For example, the .NET Standard 2.0 target needs to stay on Entity Framework Core 3.1, whilst the .NET 6.0 target can use Entity Framework Core 6.0.
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net6.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="morelinq" Version="3.3.2" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.18" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="3.1.18" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="3.1.18" />
<PackageReference Include="Microsoft.Extensions.Options.DataAnnotations" Version="3.1.18" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net6.0' ">
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Options.DataAnnotations" Version="6.0.0" />
</ItemGroup>
However, I'm running into issues with the Visual Studio "Manage NuGet Packages…" feature for updating packages, since it doesn't seem to support target frameworks. This affects all versions of Visual Studio, including 2022:
Is there a proper way to handle package upgrades on multi-targeted projects?
The best workaround I've found so far is to use a solution-wide find-and-replace to temporarily change the <TargetFrameworks> in the csproj files to single targets when updating NuGet packages.
For example, you could first replace all occurrences of <TargetFrameworks>netstandard2.0;net6.0</TargetFrameworks> to <TargetFrameworks>net6.0</TargetFrameworks>. With that change, any package references in <ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' "> groups are ignored, and the Visual Studio "Manage NuGet Packages…" window would allow you to update just the common and the .NET 6.0–specific NuGet package references. (You might need to reload all projects after the replace, e.g. by restarting Visual Studio.)
Next, you would replace all occurrences to <TargetFrameworks>netstandard2.0</TargetFrameworks> and update the .NET Standard 2.0–specific NuGet package references. Finally, you'd perform another find-and-replace to revert back to <TargetFrameworks>netstandard2.0;net6.0</TargetFrameworks>.
I've kept the plural form of <TargetFrameworks> throughout to distinguish it from genuinely single-target projects that originally had <TargetFramework>. You might want to use another means of tracking these temporary find-and-replace changes, such as by adding a <!-- revert --> comment.