-
Notifications
You must be signed in to change notification settings - Fork 429
Support .Net Framework (4.8?) for netstandard 2.1 #859
Comments
The .NET Framework 4.8 feature set is still being decided on, which is why we haven't shared any plans yet. As soon as that's decided, I'll update the planning doc. |
I just wanted to ask the same question. Now that 3 days ago it has been announced that asp.net.core will not support .netframework anymore: https://blogs.msdn.microsoft.com/webdev/2018/10/29/a-first-look-at-changes-coming-in-asp-net-core-3-0/ This sounds like netstandard2.1 for netframework will not happen at all. But this rises another question: If everyone has to reference netcore soon, is there any sense for netstandard at all? |
Latest blog post makes this clear, netfx 4.8 will not support .NET Standard 2.1. https://blogs.msdn.microsoft.com/dotnet/2018/11/05/announcing-net-standard-2-1/ |
Yep. Closing. |
RIP .NET Framework. It will not take long till the first NuGet dependency will become netstandard2.1+ only, and then BOOM! |
People will be mutlitargeting netstandard2.0 for a long time. It's not reasonable to expect all frameworks to be locked together in features. |
netstandard was proposed as a solution to nightmare that was PCL. It was to be a common set of features that all frameworks would support. This just killed that. Either we consider .NET Framework to be dead and therefore not included in all frameworks. or netstandard has failed in it's goals. |
No, it was never a goal to have all runtimes support the same features. It was to simplify how we refer to API sets so that we could have broader terms for them. All target frameworks support .NET Standard as a concept, and implement some level/version of netstandard, but they don't all support the latest version of netstandard, that is a deliberate fundamental part of how it works. |
That's a shame because with .NET Standard 2.0 we had the ability to target everything with the one library. However with new Features like span restricted to 2.1, library devs are back to having to make compromises to ether multi target and emit features from some frameworks, or not use new features at all. |
Time will show but I don't believe. Nobody voluntarily floods his code with |
That comparison doesn't work for a number of reasons. But I do hear what you are saying, if someone creates a new library, they might select netstandard2.1 and they will be excluding the full framework from consuming it. I'm hoping that the defaults and the guidance makes it clear the consequences when you are doing "File -> New...". I don't see libraries with existing users just dropping netstandard2.0, there will be a period of conditional compilation, and that would likely be kept for years. We will see. |
And now a lot of C# 8 requires .Net Standard 2.0 / .Net Core 3.0 and won't be working with .Net 4.8. |
Does that mean that there will be a .Net Framework 4.8.x or 4.9.x that will support netstandard 2.1? I mean, if there is no plan to implement the standard in anything but dotnet core, then why not simply work on dotnet core? Don't get me wrong, I think that would be a mistake, but only under my assumption that the full framework would continue to support new netstandard versions. If there are no such plans, I'm basically receiving a message saying I should not write libraries targetting netstandard 2.1. Is that what you want? I know I'd like to see my code thrive and be used. If you're trying to send a different message, you need to clarify! Or is the reasoning here that I should only target 2.1 alongside other targets and code conditionally for each one? If so, that's an abysmal message. I do not want to do that. It sounds like a mess and a ton of pain... I suppose such branching is fine for large public facing libraries. But for internal libraries, I should not have to do that. I realise that there are several teams trying to coordinate these things, and that getting everyone on the same page can be hard. But this needs to be sorted out... |
We expect Mono/Xamarin to support it, and most likely Unity to in due course. |
@danmosemsft I see. My mistake. I've been thinking in terms of only two of the platforms; fullframework & dotnet core. At least then it makes sense, even if I think it's a pity that the fullframework won't get support. I suppose that simply means we should all hasten to move away from fullframework asap, or be left in the dust. ;) |
@gautelo :) |
If you look at my comment from Nov 2th, we already have entered a loop here ;) |
@springy76 Yeah, I read the whole thing. I just wanted to voice my support and add some pressure. |
I am specifically concerned about |
I worry this will hamper libraries that want to use the high performance constructs of .netstandard2.1 and hence be counter productive since .NET Core applications also will run without the Span, SIMD, Whatever features inside the libraries when .NET Standard 2.0 is the common ground. |
This puts our developers in between a rock and a hard place, since there are libraries that we use to access our core database that I worry will never be updated to target .NET Standard. So the choice we will have to make is either go full .NET Framework or stay on .NET Core 2.1, both of which are painful decisions to make. |
@behoyh I guess the bright side is there is no shortage of development jobs to move piles of code around and put those .NET Framework piles of code into .NET Core 3 piles of code. May want to buy two things this summer: Stock in Caterpillar, and a JetBrains ReSharper license. |
In short: Superpackages that span multiple themes are a bad idea. Unfortunately, it's less clear if smaller superpackages + ThemePacks are better or even worse. (ThemePacks are my own moniker for describing the idea that perhaps we should have netstandard-system, netstandard-gui, netstandard-data, netstandard-web, etc.) |
I am using asp.net core 2.2 and target to net471 because of legacy libraries (a lot of them which is out my control). And now I cannot upgrade to asp.net core 3,and efcore 3 which is sad. Maybe .net 5 can support legacy libraries.? If not then I have to stay in asp.net core 2.2 forever? |
@albertwoo (asp)netcore 3 can reference and use net4x assemblies or NuGet packages. You will get compile time warnings and maybe MethodNotFound exceptions on run-time. But it in most cases I've seen so far, it just works because netcore3 has added a lot of APIs from net4x. |
Since .NET Standard 2.0 and .NET Core 2.0 you can reference .NET Framework libraries/NuGet packages. You'll get a warning when building, but we'll try to load the libraries. However, this will only work when the APIs used by the package exists. However, since then we've added a lot of libraries that provide more API support (e.g. the Windows Compatibility Pack). And with .NET Core 3.0, this also includes WinForms & WPF. Post .NET Core 3, the set of supported .NET Framework will not grow in significant ways any more. See dotnet/announcements#130 for details. |
As well as the posting @terrajobst linked above, this blog post is relevant: in particular
|
You can use Xamarin Forms to do desktop with the WPF Backend targeting .NetCore 3.0 and with macOS but Linux desktop is still left hanging because GTK# targets .NetFramework |
Just for common info: netstandard already has been declared "deprecated": |
That's not quite accurate. .NET Standard hasn't been deprecated; it has been merged with .NET Core into .NET 5. Therefore, all investments into .NET Standard carry forward to .NET 5 and all future versions. If a library is targeting .NET Standard today, there is no reason to move .NET 5 unless you need APIs that are net-new in .NET 5. So it's exactly the same as choosing between different versions of .NET Standard. |
Is it, though? Say I packaged a .netstandard nuget package 3 years ago. What transitive assembly gets referenced in that package when I target .NET 5? My point is, I think there is a hidden time dimension (sequential coupling) that makes your statement either true or false. I predict this is where most people will have a lot of confusion, because there is no way to have assemblies as private dependencies other than to have a new AssemblyLoadContext. I reserve the right to change my mind. |
Not sure what you mean. A NuGet package with a .NET Standard binary built three years ago should install and run in a .NET 5 application just fine. If that doesn't work, I'd consider this a bug. |
I'm referring to "private" dependencies that would need to roll forward on major version to get located for loading. (I edited my original response.) |
Could you provide an example? I'm still not sure I follow. The API surface of .NET Standard is entirely accumulative and we'll keep it this way for .NET 5. Thus, there shouldn't be a reason why something built three years no longer works because an API breaking change was performed. |
If I have a project that targets netstandard2.0 and I "privately" (transitively) reference an OOB System package that references netstandard2.0, and then the consumer wants to reference that project in a .NET 5 app and have a "public" (top-level) dependency on the .NET 5 OOB reference, it's a bit hard for the consumer to understand why they get a DLL not found exception when the runtime loads the old dll and goes looking for the new dll, yes? |
Does this describe your setup?
I assume by
You mean a component that is in-box in The expectation is that this just works. The application output for Does this make sense? |
My personal experience when it comes to (transitive) NuGet dependency graphs: |
The use of Project/Nuget, bullets and brackets is very useful notation. Thank you. The set-up I am describing is:
An example of System.C would be System.Data.SqlClient. Is that now in-box for .NET 5? Apologies if I missed that announcement. The concrete example I've given in the past is TaskRunner.exe and Task.dll. Imagine TaskRunner dynamically discovers My analysis is that because the just works bits are all done at compile time, that there is no way to co-integrate or goal seek to solve for the right runtime dependencies in the dynamically loaded plug-in. Worse, users don't know what to do when confronted with a cannot find assembly error, because there is no call to action in the exception telling them what to do. Most people go to the open source project author or StackOverflow for help. I could be wrong. I believe, in the old days, people would link against the dependency they expected to be there at run-time, but also bindingRedirect with a wide range, thereby allowing a single interface contract. I think that user story is not quite solved for. The wide version range bindingRedirect was a crappy solution, but it frankly did work a lot nicer for solving this problem then what I am aware of in .NET 5 (ne .NET Core) today. Note: The key scenario the wide version range bindingRedirect did not handle well in the old days was global tools like MSBuild. For that, you would have to create an IDirtyAssemblyResolveHelper and handle the load event, effectively re-implementing the wide version range bindingRedirect in C#. For that reason, I gave the concrete example of TaskRunner.exe, since it's basically a stripped down version of MSBuild where you write all your targets in C#. |
@terrajobst I edited the last post, SORRY. Just replying here so you see that I edited it. I had one typo in the second top-level bullet tree. |
By the way, I don't think this is fiction. Azure App Services injects the wrong DLL version into application processes when you check SQL Server Monitoring checkbox. How come Azure App Services can't call the MSBuild just works bits as a service? Note: I express this example because, technically, the workaround I have found for the TaskRunner.exe example is to create a dummy TaskRunnerBase class and have people sub-class it and reference their dynamically loaded library, statically. I colloquially refer to this set-up as "In-Process Tool chaining". It solves the run-time dependency problem by effectively converting the run-time dependency to a compile-time dependency, thus opting into the just works bits. However, in the case of Azure App Service, I can't do this transformation, because I don't own Azure App Service bits. |
@springy76 I'm not sure I understood that. In my experience, multi-targeting makes the code more uglier (but potentially more correct) because it forces you to handle any static failures. An example would be ASP.NET Core testing libraries that are written for ASP.NET Core plug-ins and need to work against multiple versions of the ASP.NET Core framework. The reason why the code being more uglier isn't so bad is that we can then Coverlet our code and see what branches we're not covering across all the different TFM permutations. The other learning experience I had is that, precisely this problem I described above, which took me forever to figure out the right approach to solving, in part because System.ComponentModel.DataAnnotations OOB package followed insane assembly versioning practices. I assumed netstandard2.0 and net48 would have identical assembly versions. Boy, was that a surprise! It took me my entire 2018 Christmas break to figure that one out. The last learning experience I had is TFM is mostly irrelevant once you get into C# 7.3 vs C# 8.0 and later discussions. There's no backward compatibility and Visual Studio pretty much eats itself. It creates a weird situation when you want to provide long-term support for a library. I've had situations where I said, "There's no way a .netstandard2.0 customer will ever need to consume this library, so I'll use C# 8.0 since my transitive dependency is async all the way, and the C# 8.0 keywords make that hella easy to read." -- I realize this is now veering a bit off-topic, but it's part of the whole experience. |
That's why I used quotation marks. I don't know whether "obsolete" would be a better fitting word, but at least it is officially superseded by net5 TFM, according to https://docs.microsoft.com/en-us/dotnet/core/dotnet-five#net-standard :
But I can't tell if the linked document is new or old since 09/02/2020 is totally ambiguous to me: could be September or February. |
@springy76 That just means that |
@svick at least this is the plan. But my reading of https://devblogs.microsoft.com/dotnet/the-future-of-net-standard/#what-you-should-target is tl;dr: leave netstandard behind as soon as possible if you can - or at least multi-target your NuGet packages so you don't shoot consumers using net5 in his foot due to exposal of platform specific features. |
@svick Where was this announced? Thanks. @terrajobst Should I create a new ticket to cover #859 (comment) |
https://devblogs.microsoft.com/dotnet/net-core-is-the-future-of-net/ points out that .NET Framework is supported as part of Windows, and significant parts of Windows itself depend on it. |
.NET Framework isn't going anywhere, but it is going to get harder and harder to get nuget packages that work with it. The nuget packages you depend on will move on and leave you behind. My latest nuget project JsonSrcGen requires Span so it is .Net Standard 2.1 Because of this it will never support .NET framework. If you can get off .NET Framework you should. |
No, that wasn't my intent. From my post:
As @svick said: .NET 5 is the successor of .NET Standard 2.1. And the guidance is the same as before: target the lowest version you can. If you must use features that only exist in .NET 5, then you upgrade to .NET 5. If you can get away with targeting .NET Standard 2.0 then you absolutely should because it gives you much more reach. |
It's part of Scott Hunter's original announcement:
It doesn't say forever, but it says as long as Windows is supported which for all intents and purposes is the same thing. |
Eventually that is likely a very true statement. But I don't see a mass exodus that quickly. .NET Framework is installed on 1.8 billion machines and there is a lot of code running on top of it that won't move any time soon. Different library authors have different target audiences. Web and mobile developers can leave .NET Framework behind today already. For desktop applications and WCF services that's a different equation, so YMMV.
Strictly speaking you don't have to drop .NET Standard 2.0 for span. You can install System.Memory which will give you |
@terrajobst Sorry, I didn't see a reply about #859 (comment) As far as supporting .NET Standard 2.0, I don't know, man. You guys made it really hard by having so many things in C# 8.0 and tying C# 8.0 to .NET Standard 2.1. Supporting .NET Standard 2.0 is pretty challenging when you consider how much simpler .NET Standard 2.1 makes Async All The Way. I might seem like a great engineer, but I just put my head down and work hard to push out solutions I personally love. I'm nowhere near the Big Brain you and Dan are. So, when confronted with .NET Standard 2.0 and .NET Standard 2.1, it will get squeezed out, especially as I'm at the phase of life where I'm starting a family. But... solving the scenario I pose in #859 (comment) would seriously cut down on support requests I get for two nuget packages each with over 1M downloads. I don't know where these packages rank among open source projects, but they must be very high up there. Like, I love you guys and what you all do for us consumers of .NET, you give me a job indirectly, and for that I am very thankful. But issues like this one I pose in #859 (comment) are just tough to deal with and hard to explain to beginners. Meanwhile, I can see some prominent Microsoft employees on Twitter complain about Node.JS modules taking forever to download and each Node.JS project having 10,000 modules and how .NET Core is so much better and faster, but they miss the point about why people in Node.JS land never have to deal with this time sink called Assembly Load Exception.. I don't know if you've ever read Gilad Bracha's academic paper, "Modules as Objects", but he nailed it. This is what Dart + Flutter does (Google hired him and he got to re-implement that vision in Dart and Flutter, and it;s at the very core of what makes FLutter awesome), this is what JavaScript 6 EcmaScript committee nailed - you can go and read the mailing list and even Allen Wirfs-Brock is on there talking about how to keep JavaScript modules simple and just objects, because you get so much for free with that. I realize you guys were probably optimizing for something else with .NET Core, and I think you achieved that... but the whole world runs on modularity these days. In many ways, I think .NET Core needs to tidy this up. Otherwise, you'll be third place behind JavaScript/TypeScript, Java (which has OSGI and Peter Krien's BND, and may be a useful source of inspiration for how to plug the holes in .NET's module system). |
It's just mind boggling that it won't support netstandard 2.1... I'm stuck in a solution where we have a common framework used by Xamarin and a full server app in .net Framework 4.8 and we can't migrate anything to support net core 3+ with netstandard 2.1 in the framework because the framework won't be referenceable by the server app... This is really bad. What should I do? Multi target? Have multiple nuget pacakges? It's for the same app! The goal was to have a center framework that would be useful to every part. |
There is currently no mention here about which platforms will be supported apart from .net core. So adding this issue to track the framework support.
Netstandard is a good way to target all the major .net platforms. As such it should continue to support the .Net Framework which is still very much used.
The text was updated successfully, but these errors were encountered: