I have a library targeting netstandard2.0
that I use in a ASP.NET Core 2.2
application that relies on a couple of Microsoft.Extensions
packages
Here is my csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="2.2.0" />
</ItemGroup>
</Project>
I now want to be able to use this same library in a new ASP.NET Core 3
application as well as my existing ASP.NET Core 2.2
applications.
Looking at the Microsoft.Extensions.*
packages, their versions always appear to match the release versions of ASP.NET Core
.
My options are
ASP.NET Core 3
application?3.0
equivalents .. Will this package still work in an ASP.NET Core 2
application?ASP.NET Core 2.2
applications), but create a new package using the 3.0
equivalents for use in ASP.NET Core 3.0
applicationsThe overall question is as a library author, what is the correlation between a specific version of a Microsoft.Extensions.*
package and its use within a specific ASP.NET Core
target?
You can (and should) do multi-targeting.
Target netstandard2.0
and netstandard2.1
, for netstandard2.0
reference the 2.x (lowest one which works for you, prob 2.0, there should be no breaking changes in 2.x) and for netstandard2.1
reference the 3.x versions of it.
Because its a major version jump, usually ending up with new apis, removal of old or change of method signatures (in other words: breaking changes) and since netstandard2.1
requires .NET Core 3.0 so also applications referencing it rely on Microsoft.Extensions.*
3.x version APi surface
To conditionally reference a package, do
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.0"/>
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.1' ">
<PackageReference Include="Microsoft.Extensions.Logging" Version="3.0"/>
</ItemGroup>
Alternatively
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.0" Condition=" '$(TargetFramework)' == 'netstandard2.01' "/>
<PackageReference Include="Microsoft.Extensions.Logging" Version="3.0" Condition=" '$(TargetFramework)' == 'netstandard2.1' "/>
works too, but its less readable. This will still create one NugetPackage, but it will have two folders netstandard2.0
and netstandard2.1
with two separately complied assemblies targeting the different versions.
When this package is restored on .NET Core 3, it will use the netstandard2.1
version, if restored on .NET Core 2.x it will use netstandard2.0
.
If there are api differences, you have to use preprocessor directives in your code
#if NETSTANDARD2_0
// API call of 2.x library
#elif NETSTANDARD2_1
// Api call of 3.x library
#endif
with reference to your options:
Do nothing .. Will this package still work in an ASP.NET Core 3 application?
Can't give exact answer, it depends on the classes availability in the target framework, you may check in .NET API Browser for all .NET versions
Upgrade the packages to their 3.0 equivalents .. Will this package still work in an ASP.NET Core 2 application?
No, when you target a higher version it will try to install all related dependencies from the higher versioned framework as well, and this will make a lot of confusion.
Keep the existing package (for ASP.NET Core 2.2 applications), but create a new package using the 3.0 equivalents for use in ASP.NET Core 3.0 applications
This can solve the issue but it is not a practical solution, you will double the work when you work on any updates.
As mentioned in the previous comment, you can do multiple target nuget package (consider this option only if you need framework specific dependencies)
@Tseng already explained the conditional targeting, I will add only the targeting for .NET Core 3, since most of the nuget packages are already included in the core 3 framework you may only need to add framework reference as below:
<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.0'">
<FrameworkReference Include="Microsoft.AspNetCore.App" Version="3.0.0" Exclude="Build,Analyzers" />
</ItemGroup>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With