Since .net standard is not an implementation, it's just a set of rules, what happens when a .net standard Class-Library project is built?
I would think that one could only build a .net framework or .net core (etc.) project (which can include a .net standard class-library's files). And yet it is possible to completely build a .net standard class library as a project.
(only a partial answer)
Take a look at what is shown when the Dependencies node is expanded:
A .NET Standard library ends up picking an implementation, in this case it is .NET Core.
Now why .NET Core as opposed to .NET Framework ?
I guess because it is platform agnostic and thus fits the paradigm of .NET Standard which is about openness, the same could not be said for the .NET Framework.
And what is the purpose of netstandard.dll ?
When you open it in the decompiler of your choice, you will see thousands of TypeForwardedTo attributes, i.e. its role is to forward .NET Standard types to an implementation.
Also, interestingly, it's not even written by Microsoft but by the Mono development team.
Microsoft Docs define .NET Standard as below:
.NET Standard is a formal specification of .NET APIs that are intended
to be available on all .NET implementations. The motivation behind
.NET Standard is to establish greater uniformity in the .NET
ecosystem. ECMA 335 continues to establish uniformity for .NET
implementation behavior, and while ECMA 335 specifies a small set of
standard libraries, the .NET Standard specification encompasses a
broader range of .NET APIs.
It is completely possible to build a .NET Standard project in isolation. But, how it can be consumed really depends on the version you are using. Choosing what version of .NET Standard you want to use depends on your use-case. Higher the version more APIs are available but it also means you can target fewer platforms.
Take a very simple example of .NET Standard 2.0 vs 2.1.
Let us say, you need to create a Client Library/ Nuget package for different applications to consume. If you choose .NET Standard 2.0, your library can be targeted by .NET Core 2.0+ and .NET Framework 4.6.1+ (with some caveats).
If however, you know that you will only have consumers on .NET Core 3.0 and above, it is safe to choose .NET Standard 2.1 as your target and get advantages of additional APIs and features available in the .NET Standard 2.1
Related
I'm still getting to grips with .Net Standard vs .Net Core after many years of development ASP.NET Framework. I have set up a new Web Api "app" which targets netcoreapp3.1 framework along with a middle-tier/Business Logic ClassLib and Data Access ClassLib, both of which target .Net Standard for maximum future compatibility. However, I can't seem to use ISystemClock from the Microsoft.AspNetCore.Authentication namespace in the .Net Standard classlibs!
From reading this SO question, I believe this might be because netstandard2.0 might not implement Microsoft.AspNetCore.App framework. Is this correct?
If it doesn't, should I:
Provide my own IMySystemClock interface in my class libraries which
the "app" itself can implement a trivial concrete class for?; or
Change my class middle and data access tiers to netcoreapp3.1
framework (seems over kill and restrictive to do this)?
Something else? Maybe I am missing the point of .Net Standard`?
A service (like ISystemClock) to provide the current (real or mock) time seems quite a fundamental service so I'm unsure why it's not appearing in .net standard framework?
Thanks
BloodBaz
If you want to access that functionality from a library, change the target framework of your library to .NET Core 3.1. Libraries can be built in .NET Standard or .NET Core. You can't use .NET Core functionality within a .NET Standard library, but you can do the reverse. Use .NET Standard functionality within a .NET Core library.
Also as a side note, unless it's required for compatibility reasons, I recommend you switch to .NET Standard 2.1. Visual Studio defaults new projects to .NET Standard 2.0, but a ton of new functionality was added in .NET Standard 2.1.
I spent years in the .NET Framework, so I feel the confusion. It took me a while to get used to it. I have a huge project I recently migrated over from .NET Framework to .NET Standard / .NET Core. What I ended up doing was dividing my code up into three sections. A .NET Standard 2.1 library with all the non .NET Core specific common code, a .NET Core 3.1 library with all my .NET Core specific common code (which referenced my .NET Standard library), and my applications as .NET Core 3.1 projects (which referenced my .NET Core 3.1 library).
Make sure you take a read at the answer in this question as well: What is the difference between .NET Core and .NET Standard Class Library project types?
Whenever I'm creating a new solution with VS2017 I'm usually choosing one of the newer Frameworks as a target (most often currently 4.6.1).
Now though when I create a .dll Subproject within the solution it sets the target Framework for that subproject to .NET Standard 2.0. With that being the most "modern" target Framework that can be set.
This though has the Problem that I can't use some things I'm used to like "Resources.MyResource" (which works fine with Framework 4.6.1).
Now I'm wondering is there any way to rectify this Problem? Either by increasing the .NET Standard, or by enabling one to choose the .NET Framework also for These .dll Projects (aside from creating the .DLL Project outside the solution and then importing it into the solution)?
.Net Standard is a specification of the .NET API's that are available on all implementations of .NET.
What does this mean? - Calling an API in .Net Standard will run on all .Net versions that have implemented that version of the Standard.
SO what does that mean? - .Net Core introduces cross platform development. The need to now possibly share code between a Windows machine and a Linux box require a "standard" that can be implemented across all equally.
Think of it as a contract. If a version of .Net implements .Net Standard 2.0, it is saying that it will have a version of the API's in that standard available for use on all platforms.
So, back to your original question. .Net Standard 2.0 is not a "new" version of the framework. It is the contract that your subproject, assuming it's a class library is going to abide by. If an API appears to be missing it is because it doesn't have it as part of it's contract (maybe). I say maybe because it's not the easiest to find.
**** Start Revised ****
Here is a table of the versions of .Net that support the versions of .Net Standard.
In your case 4.6.1 doesn't even support 2.0. The last version of the Standard that 4.6.1 supported is 1.4.
I thought 4.6.1 supported .Net standard 2.0 after I wrote the above and upon further reading found a more up to date chart along with this post stating it is supported in 4.6.1. sigh
**** End Revised ****
This SO answer seems to indicate that 1.4 does have Resources in it but it was preview versions and things change. I don't see it in the APIs supported list but I could have missed it. The SO answer seems to indicate it was a tooling issue and could be worked around. That could be fixed by now....
Here's where you can look to see what each Standard supports for APIs.
HOWEVER, I don't think this is actually what you want.
I think what you really want is to simply change your sub project's target to 4.6.1 as is your main app since I highly suspect you have no need/desire to run cross platform.
Additionally, prior to .Net Standard 2.0, thousands of API's were not in the Standard. IMO, prior to 2.0, the Standard is a hard sell especially for users on the .Net Full Framework.
From what I can tell the Project Template to use is under "Windows Classic Desktop > Class Library (.Net Framework)"
EDIT
That said, you can add a .resx file to a .Net Standard project and use it in exactly the same way.
.Netstandard2 is released final with .Net Core 2.0 and vs2017.3 with nuget4.3 and API surface cover 32k (except 41 class) and full cover net461
Quoting from Announcing .NET Core 2.0
You can now reference .NET Framework libraries from .NET Standard libraries using Visual Studio 2017 15.3. This feature helps you migrate .NET Framework code to .NET Standard or .NET Core over time (start with binaries and then move to source). It is also useful in the case that the source code is no longer accessible or is lost for a .NET Framework library, enabling it to be still be used in new scenarios.
We expect that this feature will be used most commonly from .NET Standard libraries. It also works for .NET Core apps and libraries. They can depend on .NET Framework libraries, too.
The supported scenario is referencing a .NET Framework library that happens to only use types within the .NET Standard API set. Also, it is only supported for libraries that target .NET Framework 4.6.1 or earlier (even .NET Framework 1.0 is fine).
So, in .netcore2 environment we can continue build/use Full .Net Framework as we did many years without the need to switch to .netstandard2 libraries.
With multi target project ,(net64;netstandard2), we get .net standard 2.0 out of box free (zero time effort) with the same API coverage.
Can you share your experience regarding: Can we continue build Full Framework 4.6.1 class library and use it in .netcore2? what is the limitation?
When you build a .NET Framework library, you can only use 4.6.1 with .NET Standard. If you want to use a newer API that is in e.g. netstandard2.0 or .NET 4.7, you'd need to retarget your library to 4.7, which then cannot be used by netstandard2.0 / netcoreapp2.0 projects. Effectively, you are locked into .NET Framework version 4.6.1 and can (/should) never update it to a newer version. (Of course, there is a workaround involving disabling the implicit fallback definition and manually setting AssetTargetFallback in the consuming project, but it requires manually editing the .csproj file and instructing all package consumers to do so).
Furthermore, the compatibility layer does not protect against using APIs that are not implemented on netstandard so a consuming project may get exceptions about missing types, methods, assemblies etc. Only when you target .NET Standard, your library is guaranteed to work on .NET Standard conformant platforms.
A practical limitation currently is that referencing .NET Framework library projects(!) (not NuGet packages) from .NET Core is not possible / only works with specific setups and workarounds (you will get an incompatible target framework warning).
I just can't understand why I can't use an old library in a .net Core app targeting Windows and the full .net framework (I don't care about multi-platform).
Just trying to understand the limits here. I don't want to hit a wall after investing too much into it.
Steps followed:
Create a new .Net core web Application
Added PetaPoco from NuGet (just an example)
Can't use the library
From a comment from you on a deleted answer to this question
It's not about this particular reference. I just want to understand why I can't use an arbitrary Windows DLL. (I don't care about multi-platform) – Eduardo Molteni
It appears you are not too concerned why this specific project is not working (the deleted answer you commented on covered that quite well and if it was not deleted I would have up-voted it) but why in general you can't use a .NET Framework DLL in a .NET Core project.
Here is a diagram showing the layout of the ".NET ecosystem"
Things built for .NET Framework can't use DLLs built specifically for .NET Core, and things built for .NET Core can't use DLLs built specifically for .NET Framework because they are two "siblings" in the hierarchy.
Both .NET Framework and .NET Core can use .NET Standard libraries in their projects because .NET Standard is the "parent" of both the framework and core. Many newer NuGet packages now release versions that target .NET Standard so the library can be used with both versions. See the below chart to see what version of the .NET Standard library is compatible with various platforms. netstandard libraries are forward compatible so something that is compatible with 1.5 (like .NET 4.6.2) is also compatible with versions 1.0-1.4
I was writing up the supported platforms for my PCL recently, one of which is other PCLs. I was confused if my library (which targets .NET Framework 4.5 and Windows/Phone 8.1) can be used in .NET Core projects as well.
As I understand it, PCLs allow you to share code across multiple platforms without recompilation, while .NET Core does that as well. The only difference is that .NET Core targets a few more platforms, i.e. OS X and Linux, and is open source.
So essentially, I don't see how .NET Core is any different than Microsoft rebranding the PCL and saying "PAY ATTENTION we're going open source and targeting non-Windows platforms!"
So the bottom line is, are PCLs compatible with .NET Core, and vice versa? What's the difference between them?
There is a beautiful article series about it which solved my questions around it ...
https://oren.codes/2015/06/16/demystifying-pcls-net-core-dnx-and-uwp-redux/
https://oren.codes/2015/07/29/targeting-net-core/
.Net Core has all his libraries (e.g. System.IO) in separate NuGet packages (each of them available for the SDKs DNX, UWP and .Net 4.6). Third party libraries target dnxcore50 (DNX) or uap10.0 (UWP) if they access the platform natively or rely on their features. If they do not access the platform but only rely on other packages, they should target dotnet.
dotnet effectively means: I am compatible with any platform which satisfy my dependencies (your library XYZ "dotnet" which uses System.Reflection dnxcore5+net45 could not be used by a UWP uap10.0 app). This effectively ends the combinatoric nightmare of the platforms. The previous target combination dnxcore5+net45 created an intersection between the platforms libraries and each addition would make the situation even worse. dotnet on the other side does not restrict the library on a target but instead forwards this restriction decision to its dependencies (where suddenly new restrictions like the famous unicorn platform can show up).
Therefore as a library author you can target dotnet if you just need other libraries.
Answering your question:
Your PCL is compatible with .Net Core style environments like DNX and UWP if you add the target dotnet, dnxcore50 or uap10.0 depending on the need of your library (see Owen's article for same basic compatibility with the contract Profile 259).
.Net Core is much more than a set of PCLed libraries. It is a new CLR, a new organized framework (packaged in small parts) and the infrastructure for new .Net SDKs (DNX, UWP, and whatever comes next). The term ".Net Core" targets both, the base class library "CoreFx" and the CLR "CoreCLR". But the real platforms are in reality DNX (by ASP.Net team) and UWP (by Windows team).
All of that answer is my current understanding of the .Net Core library situation. It is work in progress, and like mentioned in the posts, not yet public documented.
NOTE DEC 2016: Be aware, dotnet as the predecessor to netstandard1.x has changed in its concept starting with netstandard2.x (.NET Core 2.0; ~JUN 2017). Beginning with netstandard2.0 there will be one common contract (the netstandard.dll) which all platforms (.NET Core, .NET Framework, Xamarin, Mono, Unity3D) implement. This contract will be extended over time and the platform have to either drop support for the latest standard, throw NotImplementedException or implement it.
My understanding is they both are in concept different.
.NET Portable built upon the .NET Full, .NET Core, Windows Phone,etc, as sort of 'bridging layer'.
It actually has no concrete implementation, consider it a 'Package' of assemblies of the 'Interfaces'(contracts).
The scope of .NET Portable 'Package' is dynamic, depends on what 'Targets' platforms you are going to 'bridge'. It's a intersection of the platforms you target, the more platforms the smaller package.
During runtime, this Portable layer is hooked/adapted to the real implementation of .NET full, .net core or...