Can I use netstandard1.* libraries in netstandard2.0 project? - .net-core

Since the major version number has changed I suppose that netstandard2.0 contains changes that are incompatible with netstandard1.*.
Are there any restrictions in using netstandard1.* libraries from the netstandard2.0 project?

You can use any netstandard1.* library with netstandard2.0 project.
From .NET Standard versioning rules:
Additive: .NET Standard versions are logically concentric circles: higher versions incorporate all APIs from previous versions. There are no breaking changes between versions.
and specific for .NET Standart 2. breaking change clarification:
Based on community feedback, we decided not to make .NET Standard 2.0 be a breaking change from 1.x. Instead, .NET Standard 2.0 is a strict superset of .NET Standard 1.6. The plan for handling .NET Framework 4.6.1 and .NET Standard 2.0 is outlined in the spec.
In general the .NET Standard version of your project impact the following:
The higher the version, the more APIs are available to you.
The lower the version, the more platforms implement it.

Related

.NET6 vs .NET Core 3.1 compatibility

Is it safe to have a .NET6 application which references a .NET Core 3.1 NuGet library?
I tested this case using a simple console application. Everything looks good and there are no errors/warning. However, I haven't found any specific information so prefer to make sure.
This is important, as one of my providers offers only a .NET Core 3.1 NuGet package. Knowing the company it'll take them a year or so to prepare a .NET6 / .NETStandard version.
There is a good chance that your .NET Core 3.1 library will run without any compatibility problems as part of your .NET 6 application.
Quoting the .NET fundamentals article Changes that affect compatibility (emphasis mine):
Throughout its history, .NET has attempted to maintain a high level of
compatibility from version to version and across implementations of
.NET. …
Along with compatibility across .NET implementations, developers
expect a high level of compatibility across versions of a given
implementation of .NET. In particular, code written for an earlier
version of .NET Core should run seamlessly on .NET 5 or a later
version. In fact, many developers expect that the new APIs found in
newly released versions of .NET should also be compatible with the
pre-release versions in which those APIs were introduced.
However, compatibility is not guaranteed. The article goes on to say:
This article outlines changes that affect compatibility and the
way in which the .NET team evaluates each type of change.
Understanding how the .NET team approaches possible breaking
changes is particularly helpful for developers who open pull
requests that modify the behavior of existing .NET APIs.
Furthermore, in an answer to the question Clarification on backwards compatibility of .NET Core, a member of the .NET runtime team says:
We do not guarantee 100% compatibility between major versions. This is true for both ASP.NET Core and the runtime itself. We
intentionally make breaking changes where we believe that they are
necessary to move the platform forward and the cost of the .NET
ecosystem adjusting to them is low enough.
Breaking changes that could potentially affect the compatibility of your .NET Core 3.1 library are those that are documented for .NET 5 and .NET 6.
But, if you are not experiencing any problems with your .NET Core 3.1 library, it would appear that none of the documented compatibility problems apply.
Ultimately, of course, you'll have a higher degree of confidence in the library when your vendor provides one that has been updated for .NET 6.
Finally, with the introduction of .NET 5, there became a lesser need for .NET Standard:
.NET Standard is a formal specification of .NET APIs that are
available on multiple .NET implementations. The motivation behind .NET
Standard was to establish greater uniformity in the .NET ecosystem.
.NET 5 and later versions adopt a different approach to establishing uniformity that eliminates the need for .NET Standard in most
scenarios. However, if you want to share code between .NET Framework
and any other .NET implementation, such as .NET Core, your library
should target .NET Standard 2.0. No new versions of .NET Standard will
be released, but .NET 5, .NET 6, and all future versions will continue
to support .NET Standard 2.1 and earlier.

Referencing .net(4.7.1) projects in .net core 2.2

I have a .net Core 2.2 project. This is created using a Webapplication (Model View Controller) template. I can add my .Net Framework 4.7.1 projects into this core project, it compiles, run - and is deployed on my test servers.
1) Then I read about 2.2 End of Life, and I tried to migrate this to 3.1, and I cannot reference .Net Framework 4.7.1 in 3.1 framework. I don't know what is my next step here.
2)I read that I can convert my dll's to .Net Standard and reference - but, how can I do this?
3)These 4.7.1 dll's are shared by .Net Framework projects and core projects, so if I change this to .Net Standard - will my .Net Framework applications work?
4) Also - should I migrate my 2.2 Core projects to 3.0 because of the EOL? Is that mandatory? How will EOL affect audits if I don't migrate?
First, 2.2 is EOL, because 2.1 is the LTS release. You can downgrade to 2.1 if you don't want to jump to 3.x yet, and you'll still have a year or two of support there, I think.
However, 3.x takes the first step towards the new vision of one .NET (.NET 5 for all workflows), so the sooner you can get there, the better. 3.1, specifically, is the LTS release for 3.x, so stick there if you don't want to be forced to upgrade again for a while.
.NET Core 3.x implements .NET Standard 2.1, which is why you can no longer target .NET Framework with that (no version of .NET Framework implements .NET Standard 2.1 and never will). However, .NET Standard 2.0 is supported by both .NET Core (2.x and 3.x) and .NET Framework 4.6.1+. As a result, if you need to share a library between all these targets, you should target .NET Standard 2.0.
As far as converting your existing libraries go, you simply change the target framework to .NET Standard 2.0. That's literally it. Once you do that, some functionality in the library may fail (anything that requires .NET Framework, i.e. Windows-specific APIs). At that point, you either need to rewrite those parts of the library to use .NET Standard-compatible APIs, or use compiler directives to sub-in alternate implementations for .NET Standard 2.0/.NET Core, at which point, you'd have to multi-target the library (i.e. .NET Framework and .NET Standard 2.0 or even specifically .NET Core). When compiling, DLLs will be generated for each specific target, allowing you to seamless reference the same library from projects targeting any of the library targets.
If you're doing anything with ASP.NET Core components in your libraries, you should factor that code out into separate libraries and target .NET Core 3.1 directly there. There's no point in targeting .NET Standard 2.1, as that code will only ever be applicable to .NET Core, anyways. You should also work in the opposite direction. In other words, if there's anything that's only applicable to .NET Framework projects (Web Forms, etc.), then factor that out into separate libraries that will only target .NET Framework. That will allow you to migrate the remaining parts of the library more easily to .NET Standard 2.0.

Should a library explicitly target .NET Core 3?

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://learn.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 depends 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?
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.
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
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://learn.microsoft.com/en-us/dotnet/standard/net-standard

Will application done in .net framework 4.6.1 safely work in .net framework 4.5

I done created an application in .net framework 4.6.1 which works perfectly in localhost. But in the server(Windows server 2012), we have .net framework 4.5.
Should we upgrade it to framework 4.7 or will it work in the current framework?
It depends on whether you use any new features introduced in .NET 4.5.1 or later or not.
To ensure compatibility, you should either
upgrade your target system to (at least) 4.6.1 or
reduce the "Target Framework" setting of your project to (at most) 4.5:
Option 1 would ensure that all features that you use in development are available on the target system.
Option 2 would ensure that you get a compile-time error if you use features which are unavailable in .NET 4.5.
The .NET Framework 4.5 and later versions are backward-compatible with apps that were built with earlier versions of the .NET Framework. In other words, apps and components built with previous versions will work without modification on the .NET Framework 4.5 and later versions. However, by default, apps run on the version of the common language runtime for which they were developed, so you may have to provide a configuration file to enable your app to run on the .NET Framework 4.5 or later versions.
In practice, this compatibility can be broken by seemingly inconsequential changes in the .NET Framework and changes in programming techniques. For example, performance improvements in the .NET Framework 4.5 can expose a race condition that did not occur on earlier versions. Similarly, using a hard-coded path to .NET Framework assemblies, performing an equality comparison with a particular version of the .NET Framework, and getting the value of a private field by using reflection are not backward-compatible practices.
In addition, each version of the .NET Framework includes bug fixes and security-related changes that can affect the compatibility of some apps and components.
So i would suggest you to upgrade it to framework 4.7.
For more details please check:
https://learn.microsoft.com/en-us/dotnet/framework/migration-guide/version-compatibility

What are the .NET Standard versioning rules?

.NET Standard prescribes an API that all .NET Platforms must implement. What are its versioning rules? Is it breaking.adding, in which 1.4 adds to and remains backward compatible with 1.3 whereas 2.x is not backward compatible with 1.x?
The documentation is not clear on this. Some Microsoft docs indicate pure backward compatibility:
Given a .NET Standard Library version, you can use libraries that target that same or lower version. (emphasis added)
Now that 2.0 is out, the above doesn't seem correct. That being said, the release blog post said:
From a library targeting .NET Standard you’ll be able to reference [libraries targeting] .NET Standard, if their version is lower or equal to the version you’re targeting. (emphasis added)
That same blog post contradicted itself by saying:
In order to allow .NET Framework 4.6.1 to support .NET Standard 2.0, we had to remove all the APIs from .NET Standard that were introduced in .NET Standard 1.5 and 1.6.
Now that 2.0 is out, what are the versioning rules? It appears to be breaking.adding. Where has MSFT documented this?
I've explained this in a bit more detail in our On.NET episode on .NET Standard.
Generally, this is how .NET Standard works:
.NET Standard will version linearly, with the intention of not making breaking changes between versions. In other words, you can think of the API surface of .NET Standard as concentric circles, where higher versions have more APIs.
A specific version of a .NET platform will implement a specific version of .NET Standard.
When choosing a .NET Standard version to target consider this trade-off:
The higher the version number, the more APIs you can use
The lower the version number, the more .NET platforms support it
So why is there this talk about breaking changes? The short answer is because we made a mistake when defining .NET Standard 1.x and didn't take platform reach into consideration. You should ignore .NET Standard 1.5 and 1.6 and avoid taking a dependency on them. If you do that, .NET Standard 2.0 is a strict superset of .NET Standard 1.4.
For more details, read the section .NET Standard 2.0 breaking change: adding .NET Framework 4.6.1 compatibility in my blog post on .NET Standard.
Update. After a lot of community feedback we decided not to perform this breaking change. More details around this decision is listed in the .NET Standard FAQ.

Resources