ISystemClock not available in netstandard2.0 - c#

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?

Related

Is it possible to use a .Net5 (core) library from a .Net Framework app?

I've been trying to determine if I can call a .Net5 library/DLL from .Net Framework4.x code. There seems to be a number of articles about using .Net Standard but now that things are suppose to be consolidated into .Net 5 I'm not sure if/how things have changed. Any good references or articles out there? Can I even access a .Net5 Library from a framework app?
Check the official documentation
You mentioned:
now that things are suppose to be consolidated into .Net 5
Not really true, as you can see in the documentation:
.NET 5.0 is the next major release of .NET Core following 3.1. We named this new release .NET 5.0 instead of .NET Core 4.0 for two reasons:
We skipped version numbers 4.x to avoid confusion with .NET Framework 4.x.
We dropped "Core" from the name to emphasize that this is the main implementation of .NET going forward. .NET 5.0 supports more types of apps and more platforms than .NET Core or .NET Framework.
So it's still net core in all but name. You still need to use .net standard to support both platforms. Check te comments for compatibility.
This might also be interesting to you: choosing-core-framework-server

When a ".Net Standard" project is built - what does that mean?

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

Running different frameworks in the same solution?

I have a class library using .Net Framework 4.5, in the code I'm using HttpWebRequest of System.Net.
If I use in a console application using .Net Framework 4.5, it's ok.
If I use in a console application using .Net Core 2.2, it's ok but it's using System.net from .Net Core 2.2 and not from .Net Framework 4.5.
There's a bug/correction in .Net Core 2.2 HttpWebRequest and I want to use the .Net Framework 4.5 version but my application is in .Net Core 2.2.
Is this possible?
Nope. It's best to think of the target framework for a class library as simply an interface. It's dictating a certain API footprint, but the actual framework code is not bundled into the class library.
The actual framework dependencies are satisfied by the end application that utilizes the class library. As long as there's an acceptable level of API compatibility, then you can add the reference, but when it comes time to compile, the target framework will be that of the application itself, not the class library.
If you absolutely need the .NET Framework version, then your only choice is to make your console application target .NET Framework as well, instead of .NET Core. You can still use the new project format; you just won't benefit from cross-platform or things like being able to deploy self-contained.

With the final release of netstandard 2.0 and netcore 2.0, why we care to build netstandard2 library while we can use the full framework 4.6.1

.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).

Can I use any old arbitrary WIndows library in a .net core web app?

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

Categories