问题
With the release of .NET Standard 2.0, it's advised to target .NET Standard 2.0, even if you target 1.x already.
https://docs.microsoft.com/en-us/dotnet/standard/net-standard:
However, targeting lower .NET Standard versions introduces a number of support dependencies. If your project targets .NET Standard 1.x, we recommend that you also target .NET Standard 2.0. This simplifies the dependency graph for users of your library that run on .NET Standard 2.0 compatible frameworks, and it reduces the number of packages they need to download.
Now another big change is near! .NET Core 3 and I see that Microsoft also is targeting .NET Core 3 for Microsoft packages.
For example, Microsoft.Extensions.Logging is targeting .NET Standard 2.0 and also .NET Core 3 (.NETCoreApp 3.0):
I compared the XML files and both APIs look the same (maybe not the best way to compared them)
Now the question ;)
As a library maintainer that dependents on Microsoft.Extensions.Logging, who trying to support .NET Core 3: Should I also target .NET Core 3 - or is just .NET Standard 2.0 good enough if I don't need specific stuff of .NET Core 3?
回答1:
Short answer
You don't have to target .NET Core 3 if you don't want to use anything from it, or if you don't want to offer any .NET Core 3 optimizations. On the other hand, double targeting doesn't cost you anything and may allow you to get rid of library references that are now built into .NET Core 3. At the very least you may be able to get rid of some library references that now come with the runtime.
Long answer
It depends entirely on what you're doing, what you want to do. A library doesn't have to target .NET Core 3.0 just because its dependencies include it in their targets.
For example, the source code shows that Microsoft.Extensions.Logging
doesn't seem to have any C# 8/.NET Core 3.0 specific code. It targets 3.0 because it's part of that wave of extensions, so double-targeting doesn't require any modifications.
On the other hand, Config.Json doesn't have to reference System.Text.Json
and System.Threading.Tasks.Extensions
because they are part of the runtime.
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
<Reference Include="System.Text.Json" />
<Reference Include="System.Threading.Tasks.Extensions" />
</ItemGroup>
Other benefits
For maintainers, .NET Core 3.0/.NET Standard 2.1 offer a lot of sanity preserving features like:
- Nullable Reference Types. You'll avoid a lot of NREs in your own code. You'll probably catch a lot of hidden bugs too.
- Default interface members. You won't have to worry about breaking users' code when you add a new member to a public interface.
- IAsyncEnumerable. No more waiting for all results from a bunch of asynchronous operations
- The switch expression and far more powerfull pattern matching and deconstruction syntax.
For some of those features you can add only a few methods that will be available only for .NET Core. For example, the ChannelReader class adds a single ReadAllAsync()
method in a partial file that reads items from a channel and returns an IAsyncEnumerable<>
, eg :
public virtual async IAsyncEnumerable<T> ReadAllAsync([EnumeratorCancellation] CancellationToken cancellationToken = default)
{
while (await WaitToReadAsync(cancellationToken).ConfigureAwait(false))
{
while (TryRead(out T item))
{
yield return item;
}
}
}
This is a small but very convenient addition. It allows you to receive messages with :
await foreach(var msg from reader.ReadAllAsync())
{
....
}
NRTs on the other hand will help even for .NET Standard 2.0 because they help you catch nullability bugs in the source code when compiling for .NET Core 3.0.
回答2:
As a library maintainer that dependents on Microsoft.Extensions.Logging, who trying to support .NET Core 3: Should I also target .NET Core 3 - or is just .NET Standard 2.0 good enough if I don't need specific stuff of .NET Core 3?
Targeting .NET Standard 2.0 in your library is good enough for as long as all of your dependencies target .NET Standard 2.0 as well, including Microsoft.Extensions.Logging
.
As Panagiotis Kanavos said, there can be benefits of targeting .NET Core 3.0 for the consumers of your library, so if that's the case and it doesn't cost you too much, then by all means target .NET Core 3.0 in addition to .NET Standard 2.0.
As karann said, nuget will always select the best matching assets for every package in the graph. i.e.
- App A uses your library and targets .NET Core 3.0. Your library targets .NET Standard 2.0 only. NuGet will use that, and it's fine.
- App A uses your library and targets .NET Core 3.0. Your library targets both .NET Standard 2.0 and .NET Core 3.0. NuGet will choose .NET Core 3.0
回答3:
When someone installs a package, NuGet uses the assets from TFM that best matches the TFM of the project. It does this for the transitive dependencies too.
For example - if the project target netcore30 and package A has assets under lib/netcore30 and lib/netstandard20, nuget will select lib/netcore30. Let's say package A depends on B, and package B has assets for netstandard20, net472, nuget will select netstandard20.
Bottom line is, nuget will select the best matching assets for every package in the graph. So, as a library maintainer, you don't need to add two TFMs to support netcore30. You can target netstandard21 which implies support for netcore30 based on this doc https://docs.microsoft.com/en-us/dotnet/standard/net-standard
来源:https://stackoverflow.com/questions/57846163/should-a-library-explicitly-target-net-core-3