"So why they are both under .NET Core but referencing different libraries?"
The recommended NET version to create libraries for is now Net Standard Library. That is why the default when you create a class library is the net standard version instead of Net Core. You could manually change that but is not recommended see also this blog post about Introducing .NET Standard Library.
Are both of them Cross Platform or only the console which is using .NET Core?
Yes, they are both cross platform.
And should I avoid using Class libraries in this case?
No, by all means use Class Libraries every time is possible. This was not the original intent of Microsoft in the beginning but they change their mind later, so not all packages are yet compatible with .net standard that's is why you can not use a the net standard version to have a scaffold project because "Microsoft.EntityFrameworkCore.Tools" at the moment is only compatible with Net core, but it will probably be compatible with DotNet Standard soon
As I said if you really want to keep the scaffold option, then you can use a class library project and change manually in the project.json the .net version, then once is compatible you can switch back to .net standard. Your other projects such as a service or data layer depending how you want to keep the separation can be a class library with dotnet standard and they will be able to work correctly.
Or you could have a console application (.net core) appart from your original solution and copy and paste into your real class library using .net standard. (This is what we are currently doing in project)
I will try to further clarify your doubts and extend Jon Skeet answer.
.NET Standard is a specification, so a library compiled for a specific .NET Standard version can be used in different .NET Standard implementations.
As said in my other comment, a good analogy for the relationship between .NET Standard and other .NET Standard Implementations (.NET Core, .NET Framework, etc) is this gist by David Fowler: .NET Standard versions are Interfaces
, while frameworks are implementations of those interfaces.
This simplified diagram may help to understand this relationship:
Anything targetting NetCore10
has access to INetStandard15
APIs and NetCore10
specific APIs (such as DotNetHostPolicy
).
Of course this library cannot be used in different INetStandard15
implementations (NetCore10
is not convertible to NetFramework462
or Mono46
).
If you, instead, need access only to INetStandard15
APIs (and target that specification instead of a concrete framework) your library may be used by any framework which implements it (NetCore10
, NetFramework462
, etc.)
Note: in the original analogy David Fowler used interfaces for both .NET Standard versions and frameworks implementations. I believe that using interfaces and classes is, instead, more intuitive and better represents the relationship between specifications and concrete implementations.
Best Answer
The decision is a trade-off between compatibility and API access.
Use a .NET Standard library when you want to increase the number of applications that will be compatible with your library, and you are okay with a decrease in the .NET API surface area your library can access.
Use a .NET Core library when you want to increase the .NET API surface area your library can access, and you are okay with allowing only .NET Core applications to be compatible with your library.
For example, a library that targets .NET Standard 1.3 will be compatible with applications that target .NET Framework 4.6, .NET Core 1.0, Universal Windows Platform 10.0, and any other platform that supports .NET Standard 1.3. The library will not have access to some parts of the .NET API, though. For instance, the
Microsoft.NETCore.CoreCLR
package is compatible with .NET Core, but not with .NET Standard.Compatibility: Libraries that target .NET Standard will run on any .NET Standard compliant runtime, such as .NET Core, .NET Framework, Mono/Xamarin. On the other hand, libraries that target .NET Core can only run on the .NET Core runtime.
API Surface Area: .NET Standard libraries come with everything in
NETStandard.Library
, whereas .NET Core libraries come with everything inMicrosoft.NETCore.App
. The latter includes approximately 20 additional libraries, some of which we can add manually to our .NET Standard library (such asSystem.Threading.Thread
) and some of which are not compatible with the .NET Standard (such asMicrosoft.NETCore.CoreCLR
).Also, .NET Core libraries specify a runtime and come with an application model. That's important, for instance, to make unit test class libraries runnable.
Ignoring libraries for a moment, the reason that .NET Standard exists is for portability; it defines a set of APIs that .NET platforms agree to implement. Any platform that implements a .NET Standard is compatible with libraries that target that .NET Standard. One of those compatible platforms is .NET Core.
Coming back to libraries, the .NET Standard library templates exist to run on multiple runtimes (at the expense of API surface area). Conversely, the .NET Core library templates exist to access more API surface area (at the expense of compatibility) and to specify a platform against which to build an executable.
Here is an interactive matrix that shows which .NET Standard supports which .NET implementation(s) and how much API surface area is available.