-
Notifications
You must be signed in to change notification settings - Fork 10.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Microsoft.Extensions 3.0 are incompatible with aspnetcore 2.2 #14393
Comments
If you want to support all of ASP.NET Core 2.1, 2.2 and 3.0, then your best bet is to cross-target ASP.NET Core 3.0 only runs on For ASP.NET Core 2.1 and 2.2, you target So you would do it like this: <PropertyGroup>
<TargetFrameworks>netcoreapp3.0;netstandard2.0</TargetFrameworks>
…
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.0'">
<!-- Just reference the full framework -->
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0">
<!-- Reference what you need -->
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.1.0" />
</ItemGroup> For |
Thank you @poke . I'm not 100% sure that works for me, but I might try it. My issue is that my library has nothing at all to do with ASP.NET or WinForms/WPF/UWP/etc. That's why it targets netstandard2.0, because it is entirely platform/runtime neutral. Creating a targeted version seems like a major step backwards. Before netstandard2.0 I was building 11 different versions of the library for all the flavors of .NET. I surely hope we're not headed back to THAT nightmare!! |
@DamianEdwards was looking at writing some guidance for library authors here I believe. |
What @poke says is correct. You have 2 options:
.NET Standard doesn't solve anything here and is unrelated to this specific issue. Library authors will always need to make this choice and this isn't a new problem nor is it unique to .NET. |
Thank you @davidfowl. My concern is partly for me, but also for anyone consuming NuGet packages. What I am hearing is that people who've been focused on getting their old .NET Framework code into netstandard2.0 libraries are now in for a shock, because their libraries just became problematic, and most people will need to start multitargeting. Here's a common scenario:
And let's assume each of those uses some common NuGet packages (in my case they might each reference If I understand you correctly, my new But if I start migrating my web site from 2.x to 3.0, and can't "big bang" migrate, then I'm stuck (as an enterprise dev) multitargeting all my stuff too:
Because if all my DLLs don't target netcore3.0 then I won't get the netcore3.0 versions of the binaries out of the I'm not saying this is good or bad - I'm just trying to figure out how much of a mess everyone is in, and what guidance we need to provide as people consider moving to 3.0 (or not). |
Not really no. You don't need to target netcoreapp3.0 unless you're trying to use new features in netcoreapp3.0 (or if you end up hitting a breaking change between versions). The library author guidance is usually to target the lowest version that satisfies where you need to run. You only end up needing to multi-target when you want to take advantage of new functionality in the newer version or if you run into something truly incompatible between the 2 versions.
That's not true. You don't need to target everything to netcoreapp3.0 to get the netcoreapp3.0 assembly from a single binary. You just need to change the main application (in the above example Web Site) |
Yeah, I'm confused.
Which |
Or given that Which works except that when referenced in an aspnetcore 3.0 project I get warnings that Razor is being downgraded (for example) - I assume because older dependencies are used in business/DAL assemblies and drag back the aspnetcore3.0 project's dependencies? |
Seems like something is missing from the picture. Is Csla.dll in a package? If it is then what target frameworks does it target?
Sure you can skip 3.0 if you want the package to work on 2.x and 3.x without having to multitarget.
Show me the warning, it usually prints out the graph where the conflict occurs. |
I was rather hoping never to have to target a specific platform variant of .NET again, slowly dropping the .NET Framework ones and ending up supporting purely netstandardX.X over time. The primary use of CSLA is to create reusable cross-platform assemblies that contain all business logic. But I do use configuration and dependency injection, which is what got me into this mess, because that seems to have intertwined me with unforseen platform variations of .NET Core 😢 Right now I released CSLA 5 targeting I'll recreate a branch that targets extensions 2.x and get you the warning I was seeing from aspnetcore 3.0. |
That a noble goal and I don't see why you can't do that. You just need to never upgrade your dependencies 😄, that's how you stay compatible. Being netstandard doesn't say anything about the version of your dependencies. The latest version of JSON.NET supports .NET standard but it doesn't mean that it'll work with ASP.NET Core 1.x or 2.x or 3.x. Does that make sense? |
I guess my problem is that I see no way to ever upgrade the dependencies, and that worries me. I'll be trapped at 2.x forever right? Well, until there's a newer version of netstandard I can target, and then maybe I'll be able to update dependencies at that point. This just seems like a slow motion disaster happening in front of my eyes as everyone is trapped in the past or forced to abandon netstandard entirely. Is that the goal? For us just to abandon netstandard and move everything to netcore3.0, netcore5.0, etc? |
Doesn't this put you in a bad spot too? What happens when aspnetcore3.5 (for example) uses So then every assembly targeting netstandard2.0 and using configuration 2.2 (the latest possible) can no longer be used by this updated website? Right now I'm assuming (!!) that all the extensions 3.0 are backward compatible with the 2.2.0 or 2.2.4 versions that exist, so we can host all our pre-existing libraries in an aspnetcore3.0 web project right? At runtime I assume the only version of Or better yet, the DI library - where we assume one services collection, regardless of whether we added our services via the 2.2 API or the 3.0 API or the (future) 3.5 API that is no longer binary compatible? |
As long as the places where you want to run how lower or equal dependencies then no, you can't upgrade.
That's right.
I think you're still missing something. Imagine a world where there is no more netstandard and we just had .NET Core. We'd be having the EXACT same discussion but instead of netstandard versions, we'd be discussing .NET Core versions and which ones CSLA wants to support. |
I can totally imagine it. That was 2-3 years ago when my I guess I'm just at Stage 4 with my grief as I work to reconcile myself to the reality that the past was prologue, and the future is lots of versions of |
Perfect! Then there should be no confusion, that problem is unsolvable, we'll just have less flavors .NET in the mix but there will always be version numbers and you'll always need to decide when you can update your dependencies.
Yes Microsoft.Extensions are mostly backwards compatible but ASP.NET Core decided to constrain the versions of those assemblies because it was tested with 2.x versions. There may be behavior changes that make things work differnetly (after all it is a major version). That creates a dilemma for library authors though, you need to target 2.x if you want to run on ASP.NET Core 2.1, 2.2 and 3.0 (if you want to avoid multi-targeting). |
My dilemma, even if I assume multitargeting, is that I don't see how library consumers (i.e. enterprise developers) resolve the versioning issues. It won't be automatic via NuGet, and that's my fundamental issue here. If I create a
Then there's no way for NuGet to disambiguate between those last two items. So that means I actually need to do this:
But THAT forces everyone who consumes the So again, I come back to the meta-answer here is that netstandard is basically useless going forward. Right? And in the immediate timeframe everyone is forced to multitarget if they use their business assemblies in the web (netcore3) and Xamarin (still netstandard2 afaik). |
Right this isn't a thing.
That's correct.
Why would it force consumers to stop using .NET Standard? Did you mean to say that people using .NET Core 3.0 will get the .NET Core 3.0 version of Csla? If so then yes. It doesn't force people currently using NS 2.0 to have to upgrade anything.
I don't understand why that's the conclusion.
Just don't upgrade your Microsoft.Extensions.* dependencies. |
So is this comment I made earlier invalid then? |
Which comment exactly? Microsoft.Extensons.* is compatible. |
The link should have gone directly to the comment. But the gist is this. If I have the following:
At runtime only the extensions 3.0 will load right? So the ns2 assemblies will use the 2.x API, but will actually be using the 3.0 bits. You are saying that today they are backward compatible, so no issue (except asp.net core 2.2 doesn't trust the 3.0 versions, so that doesn't inspire confidence). Eventually though, won't there be an extensions 5.0 that might not be backward compatible? At which point people won't be able to use Csla.dll (ns2) because it will be stuck back in time until all users are off .NET Core 2 (which I expect will happen in 20 years give or take). |
Yes.
Yes.
Maybe. But what's the point you're trying to make? This is how the library ecosystem works. If a breaking change is made, then dependent packages need to fork. Just don't conflate any of this with netstandard, it's just a general problem that platforms have (it's not even unique to .NET). |
Thank you David, this all makes sense. I'm not intending to conflate it with netstandard as much as NuGet targets. I wish the decision had been made (or will be made) to have a rolling set of NuGet targets that are platform independent, like netstandard, but that roll slowly forward over time. As it is, because the only valid NuGet targets (over time) appear to be ns2, ns2.1, nc3, nc5 (?) and so forth, at least my use of ns2 as a target is rapidly drawing to a close, because ns2 generally equates to .NET Core 2, and there's no ns3 for .NET Core 3. So right, this isn't a netstandard thing. But the lack of viable rolling NuGet targets relegates ns2 to the dustbin of history as of this week, because it isn't very useful when looking at .NET Core 3 support while still supporting .NET Core 2. |
How exactly does this fix things? As I said earlier, imagine a world where .NET Core is the only thing on the planet, we'd be having this same discussion. To be even more specific, because ASP.NET Core depends on these extensions, it ends up being problematic for package authors to take dependencies on newer ones (in older versions of ASP.NET Core). That isn't the issue the problem is that you can't pivot based on dependencies. Today TFM is the only tool you have to pivot single package for "multiple things". Luckily ASP.NET Core targets netcoreapp so you have a way out. Otherwise you only real options are:
This is one of the big reasons we tried our best to get rid of 3rd party packages in the shared framework. The less things you depend on less the chance of conflict. |
From what I can gather, if you build a library/package that takes a dependency on pretty much anything, your targeting compatibility looks like this:
The X means compatible. The '?' means "buyer beware", dependencies might or might not work, even if your code compiles - you won't know about failure until runtime. As a tip, ASP.NET Core 2.2 precludes the use of 3.0 dependencies due to possible issues. So for a short period of time (~2 years?) we've enjoyed ns2 being a nearly universal target. All I'm saying is that I got spoiled, and as the right and bottom of this chart grow we'll have a steady stream of single-X options like we had prior to ns2. I think I've now reconciled myself to that thanks to your help. As long as .NET can avoid fragmenting back into .NET/mono/uwp/silverlight/phone/PCLx/PCLy/etc. again, at least the issue isn't so bad. |
I do hope the tooling resumes helping. Specifically, I'd hope that Nc5 can't reference Nc3 or Ns2 libraries - avoiding the otherwise nearly inevitable dependency conflicts. That was one thing that was simpler back in the .NET 2, 3, 4 days - you couldn't cross the streams because there was no pretense of cross-version compatibility. |
You were kidding, right? Because that would be absolutely terrible 🤣 |
How am I kidding? How is it good to think that a Nc3 project is allowed to reference an Ns2 library, where that library brings in incompatible dependencies? Once netstandard goes out of our vocabulary - which I now suspect will happen rapidly - we'll be back to the simple .NET versioning story where there's no pretense of an assembly from version X working in a version Y app. Nobody expected a .NET 4 project to use a .NET 2 library. That'd be silly. Nobody should expect a Nc5 project to use a Nc3 library. Same scenario. We had this brief dalliance with netstandard, and it has been fun, but that time is over. .NET 5 is unified right? So we no longer need something to span various flavors of .NET because there'll be just one (plus UWP of course - but that affects such a tiny percentage of devs I think it can be ignored). |
Because it would be pretty much like when .NET Core 1.0 was released? Nothing was compatible, the adoption rate was insanely low and many people waited for 2.0 (that reduced the gap between .NET Framework and .NET Core) for that sole reason. So, with your approach, every year, we'd have a new .NET version, that would be completely incompatible with all the existing projects/libs/packages? What a PITA, it would be even more terrible than the existing situation, where you have at least a chance to use a lib written for ASP.NET Core 2.x on 3.x if it doesn't use an API that was removed in 3.x.
Really? Luckily, most libs written and compiled for .NET 2 could be used flawlessly on .NET 4 😕 Against, it's not a TFM/platform issue, it's a dependencies problem, which is something @davidfowl explained clearly. Not sure why you're blaming .NET Standard. The real discussion should be about breaking changes in the |
Everyone hears me blaming .NET Standard. I don't mean to "blame" it, as much as point out that due to the way it integrates with NuGet targeting, it is now obsolete for people like me who have dependencies in our packages. My next step is to create netcore3 versions of my projects and add those assemblies to my NuGet packages, so as people move to netcore3 they'll stop relying on anything to do with netstandard. That's not blame. That's just an observation of reality. I totally agree with you on the Extensions compatibility. I can see where people will be using the 2.2 versions for years - up to the point that host apps (ASP.NET, WPF, etc.) start using a future-and-incompatible version of Extensions. Or maybe not years? Maybe that'll happen with .NET 5. Time will tell - but when Extensions (especially config and DI) become incompatible that'll cause a whole lot of pain for people. Actually - to riff on that a bit - aren't we using semver now? So if 3.0 is backward compatible with 2.x, then why is it 3.0? Isn't this really the core of the problem I'm discussing here? That a totally compatible version was released as a major point version instead of a minor version? If it is compatible then it wasn't breaking, so the major number should have stayed the same. |
You really seem to be confusing the target framework with the version of a dependency. You can ignore .NET Standard and .NET Core in your situation, and you will still have the same problem. Imagine, there is only a single runtime, and that will never need to be update. So everything targets the same thing. Now, if you have M.E.* 23 introduces a breaking change over M.E.* 2 to 22, then there is nothing the target framework will help you with. If you share a dependency in different versions, you will always have this problem. And there is really no way around it for now. M.E.* 3.0 is mostly API compatible to 2.2 (not completely, but if you depend on the That is when you will have to update your library also to enable compatibility with 5.0, likely by updating its dependency version. At that time, your new version of your library will become incompatible to old 2.2 solutions. So those will have to reference the old version of that library until they can update themselves. Cross targeting both netstandard2.0 and netcoreapp3.0 is just a workaround to provide a single library version that runs on all (current) ASP.NET Core versions. But that strategy won’t continue to work forever.
Same with every other dependency. Breaking changes are always a pain which is why there is a huge priority on avoiding them in the first place. But they cannot be avoided forever if you want to move forward. And one way to move forward is bumping the version; another might be changing the name so it can coexist. |
I understand that this is complex @poke - I'm trying to figure out the guidance to provide to people going forward. We've (and by "we" I mean a lot of authors/speakers/etc.) been telling folks to move as much of their code into netstandard2.0 projects as possible, as it was the best option to start the multi-year migration from .NET Framework to .NET Core. (I've been giving a migration talk for the past 18 months, and am giving it again next week - obviously I'm changing the messaging for next weeks' delivery 😄 ) I still think that's good advice. However, as soon as a Microsoft execution environment (such as ASP.NET Core 3) takes a dependency on a non-compatible library (such as
And that is my point. netstandard2 is effectively at end of life as of this week. It was super useful to bridge from .NET Framework/mono/etc. to .NET Core 2, and that's all. Going forward people should clearly be creating netcore3 projects for greenfield. But for the massive numbers of people who are in the middle of migrating from .NET Framework to netstandard2.0 life is a bit more complex as I see it. They still build all their code for net461 or something, plus they are building it for ns2, and now they'll probably also need to build for nc3 - or just ignore .NET Core 3 entirely and continue working toward .NET Core 2. (remember that most of these migrations are 2-5 years in length) I can see too, where if an org has not yet started migrating off .NET Framework, they can totally skip ns2 and just start targeting nc3 - while still building for net461 or whatever. Next year they'll have to start multitargeting nc3 and nc5 of course, so life will still be challenging at that point, but they can skip the ns2 step at least. |
But those libraries are compatible with netstandard2.0 and the .NET Framework. That’s the thing here; this is not something netstandard is there to solve, this is a normal dependency versioning issue that has nothing to do with .NET Standard, .NET Core or a migration from .NET Framework to one of those. The same thing happens as well when you are just using .NET Framework.
You are not ignoring .NET Core 3 when you target .NET Standard. That is just false. If you target .NET Standard, then you are building something that is supposed to run everywhere. It is not limited to .NET Core 2, and it is also not limited to some transitioning phase between .NET Framework and .NET Core. |
I think you are missing the practical reality here, at least given the use of NuGet. If I target ns2 with no dependencies then sure, my code can run everywhere. But as soon as I create a NuGet package with an ns2 assembly that has dependencies then my package is only useful for .NET Core 2 (or 3) because my dependencies have locked me in. Since there's no NuGet target to solve this problem other than platform/version specific targets I have to quit using ns2. I'm not saying this is a problem to solve - or that can be solved! I'm saying that people like me need to provide guidance to enterprise devs on the best strategy for them to use as they navigate multi-year migrations from .NET Framework to the future. |
A .NET Standard library can only reference other .NET Standard libraries, so no, every .NET Standard library will stay useful for all the implementations (.NET Core, .NET Framework) regardless of how many dependencies it has. Again: Your problem is not related to .NET Standard at all. This is just basic versioning hell, which always existed.
Then that guidance is: Stick to the versions you chose, and don’t update too early again. Do one migration at a time, don’t introduce even more migration issues by migrating several overlapping things. |
I'm not saying this is a problem to solve - or that can be solved! I'm saying that people like me need to provide guidance to enterprise devs on the best strategy for them to use as they navigate multi-year migrations from .NET Framework to the future. |
It is worse now because of the faster cadence of releases, and the decoupling of dependencies from major version releases. We've left the "safe" world of .NET in the past, and are getting dangerously close to the utter chaos of JavaScript. |
If that’s really what you think how it was, then I suppose you were living a lie unfortunately. Nothing really changed in that regard. |
Maybe. Things were reasonably manageable from 2005-2015 as long as you stayed away from mono/Silverlight/WP/Xamarin/WinRT - things most enterprise devs did avoid. I chose to dive into all of them, so nothing you are saying is remotely new to me. I've lived the versioning life over the entirety of .NET's existence. I also work very hard to provide guidance and support so most people don't have to suffer the pain some of us choose as our path. |
Describe the bug
I have a netstandard2.0 class library deployed via NuGet. It depends on
Microsoft.Extensions.Configuration
and other Extensions packages. I upgraded the dependency references to 3.0.After this upgrade I can use my class library from aspnetcore 2.1 and aspnetcore 3.0 projects. But I can not use it from aspnetcore 2.2 projects because of version limitations in the
Microsoft.AspNetCore.App
metapackage. Specifically because all dependencies are bounded to 2.3.0 so 3.0.0 is unavailable.Basically, it appears that aspnetcore 2.2 is broken, at least in terms of using the new .NET Core 3.0 dependencies.
As an open source library author I'm not sure what to do? Force my user base to move from 2.2 back to 2.1? Or forward to 3.0?
I don't see a way to create a NuGet package that supports 2.1, 2.2, and 3.0. I can support 2.1 and 3.0, or I can continue to use the pre-3.0 dependencies and support all three versions of aspnetcore (but obviously only sort of supporting 3.0).
Expected behavior
I would expect that there's some way to create a netstandard2.0 library, put it in a NuGet package, and have it support aspnetcore 2.1, 2.2, and 3.0.
At the very least I hope that the product team thought through this problem space and has a recommended workaround or solution so aspnetcore 2.2 projects aren't just totally broken with the release of 3.0.
Possible workaround
On further research and conversation via Slack, there are a couple workarounds for people using aspnetcore 2.2.
Microsoft.AspNetCore.App
reference toMicrosoft.AspNetCore.All
because the ".All" metapackage doesn't have the upper bound version limitsMicrosoft.AspNetCore.App
reference with references to all the packages you are using in your project (far more work, but provides more control)The text was updated successfully, but these errors were encountered: