dotnet / aspnet-api-versioning

Provides a set of libraries which add service API versioning to ASP.NET Web API, OData with ASP.NET Web API, and ASP.NET Core.
MIT License
3.05k stars 703 forks source link

Not supported using in netstandard 2.1 #696

Closed famda closed 3 years ago

famda commented 3 years ago

Hi, I have a net standard 2.1 library and I'm using version 4.1.0. When I try to update to a more recent version I get an error saying that the version is not compatible with net standard 2.1.

Is it possible to add it, please?

Thanks in advance.

commonsensesoftware commented 3 years ago

Unfortunately, I believe NuGet has led you astray and "The cake is a lie". You didn't say, but I'm going to go out on a limb and say that you're probably targeting ASP.NET 3.0 or above. 3.0 only lived for about a month, so I'm willing to bet that it's 3.1. You also mentioned 4.1.0 and that is the only difference between the 4.0.0 vs 4.1.0 packages.

ASP.NET Core 3.1 only supports .NET 3.1. It does not support .NET Standard 2.0.

I don't know if it's a bug in NuGet or what. This happened to you because the API Versioning package multi-targets. This was to continue supporting changes for OData, which was still on ASP.NET Core 2.2 at the time. This means API Versioning for ASP.NET Core 3.1 only targets netcoreapp3.1 and API Versioning for ASP.NET Core 2.2 only supports netstandard2.0. Exactly how NuGet resolves or allows netstandard2.0 from ASP.NET Core 2.2 when you are targeting ASP.NET Core 3.1 is beyond me, but it's wrong. That is not a supported combination and the fact that it even compiles is a mystery.

I'm sorry to say that there is no path that can rectify this. Your support for .NET Standard, however well-intentioned, is not valid for an ASP.NET Core 3.0+ application or library in this context. I've gone through some pretty lengthy issues discussing this in the past, so you may want to review #591, #617, and #638.

If that still doesn't clarify things for you, I can elaborate more. API Versioning depends on ASP.NET Core, so its TFMs will always match the framework. In terms of effort and strategy, you need only update your TFM to match them. Some library authors have be unsatisfied with that answer, but "This is the way."

commonsensesoftware commented 3 years ago

This thread has long be idle and I presume the answer was satisfactory. Feel free to come back for further discussion or guidance if need be. Thanks.

bh3605 commented 6 months ago

2024 here, if anyone comes looking for why Asp.Versioning.WebApi does not support .net standard 2.0 then you should know you have to also install Asp.Versioning.Abstractions for compatibility w/ .net standard 2.0.

commonsensesoftware commented 6 months ago

@bh3605 I'm not sure I follow. ASP.NET Web API targets .NET 4.5. To reference that package, Asp.Versioning.WebApi cannot use a .NET Standard TFM. Asp.Versioning.Abstractions does target .NET Standard, but that was mainly to support covering Asp.Versioning.WebApi and Asp.Versioning.HttpClient. ASP.NET Core hasn't supported a .NET Standard TFM since 3.0. If you aren't extending Asp.Versioning.Abstractions or Asp.Versioning.HttpClient, there's not a very compelling reason to target .NET Standard.

If there's a specific scenario you're trying to solve, I'm happy to help or elaborate further.

bh3605 commented 6 months ago

Okay, that makes sense. I've been working my way through dll hell and hit the last of our internal packages needing an update and found it's being compiled in both 472 and standard2.0. Saw a bunch of warnings of various libs being resolved to their 4.5 versions and after replacing Microsoft.AspNet.WebApi.Versioning with Asp.Versioning.WebApi I found the standard2.0 version wouldn't compile anymore. Luckily, we never switched to asp.net core and are gruelingly over so probably never converting our services from 472 to .net 7.0.

commonsensesoftware commented 6 months ago

I see. Yes, you are in a bit of a different situation. The following might help you:

Moving from Web API on .NET 4.x to ASP.NET Core will be a big jump. There's some new options for migrating and interop, but you'll have to decide how you want to do things. It's likely going to be cleaner and easier to simply rewrite, but the choice is yours. Only you know what's best.

An approach you can use is put YARP in the front as a reverse proxy. You can have the older versions route to the full .NET Framework implementation while you work on new versions written from scratch in ASP.NET Core and have newer version requests routed there. The client is none the wiser. This type of setup is one of the primary reasons I continue to support Web API and ASP.NET Core. 😉 I'm working with the ASP.NET team to added API Versioning to the Aspire reference application which would be a similar setup with YARP. I have it on my bucket list to create some examples, but none yet. You can start a discussion or issue if you want to start a larger thread.

I've been on the same journey in my own projects. I'm happy to answer or clarify any other showstoppers you might run into.

bh3605 commented 6 months ago

I first gotta say it's extremely refreshing to be hearing something from any maintainer on Github be as responsive and detailed as you are.

Most if not all of our internal libs are compatible w/ .netstandard2.0, but they have some heavy dependencies on StructureMap, bloated extension classes, or EntityFramework. Planning on rewriting them in .net7 (or.net 8) to make better use of IServiceCollection. Generally, if Microsoft figured out a better way to implement something like say for example how they refactored logging then we're taking advantage of it.

Gonna be a pain upgrading each service one at a time from 4.7.2, but we'll get there.

commonsensesoftware commented 6 months ago

"I'm not just the 'president', I'm also a customer."

OSS can certainly be a thankless job, but the community, at least one I've built, keeps me going.

You can use netstandard2.0 and reference it, but you can't (safely/correctly) reference net45 or net472. Your standalone libraries should work just fine. You might also consider multi-targeting. At some point, you may be giving up some features that are not available in .NET Standard. In this phase of your evolution, it probably doesn't matter, but it's something to consider. StructureMap has first class support in ASP.NET Core and the DI extensions.

There's a lot of logging stuff. Out-of-the-box, the Logging Extensions (a la ILogger) is the default. Open Telemetry (OTEL) has become quite popular. You can use either, both, or even mix and match. I don't personally have strong opinions about a direction. I prefer tests over logs. There is a ton of instrumentation baked in by ASP.NET Core and .NET already. You might considering hooking up to log what's already instrumented before deciding which other things you need to add.

Good luck 🍀 with your migration. 😉