Skip to content
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

Support .NET Standard 2.0 directly #407

Closed
zvirja opened this issue Aug 30, 2018 · 20 comments
Closed

Support .NET Standard 2.0 directly #407

zvirja opened this issue Aug 30, 2018 · 20 comments
Milestone

Comments

@zvirja
Copy link
Contributor

zvirja commented Aug 30, 2018

In the twitter guys from MS ask projects to target to netstandard 2.0 directly, so people with new runtime don't need to install set of packages previously installed.

https://twitter.com/davidfowl/status/1025434242832945154

If people target older version of .NET Runtime - they are still fine as we are not removing the old targets.

CC @stakx @blairconrad You might want to do the same with your mocking libraries 😉

@stakx
Copy link
Member

stakx commented Aug 30, 2018

Speaking for DynamicProxy...

  • Given what we learnt in System.Reflection.Emit package has been delisted #374, I'm not convinced that it is a good time right now to make this decision. I still suspect that it might be just as valid, or even better / more honest, to abandon .NET Standard as a target altogether and target .NET Core instead. (That's bound to be an unpopular decision with downstream clients.)

  • Even the fact that Reflection.Emit (or rather, the portion of it supported by .NET Core) might get officially included in .NET Standard 2.1 doesn't convince me yet that .NET Standard is a sound target for DynamicProxy, because they're talking about adding a "capability API" (read: a flag you can check at runtime to find out whether Reflection.Emit is in fact working or not). Wouldn't it be better if the statically declared dependencies guaranteed in advance whether DynamicProxy is going to work at runtime or not?

  • On the other hand, while Castle Core still targets netstandard1.3 and netstandard1.5, it seems like a fairly benign change to just add netstandard2.0 to the list. (This does cause us some work to get more #ifs in place, live with longer compilation times, and bigger NuGet package size.)

I'm undecided, but I'd perhaps vote for "let's wait a little longer and see how Microsoft's plans for Reflection.Emit develop".

@stakx
Copy link
Member

stakx commented Aug 30, 2018

Speaking for Moq 4, also undecided at this point (see devlooped/moq#630). We'll probably follow DynamicProxy's lead.

@jonorossi
Copy link
Member

I'm undecided, but I'd perhaps vote for "let's wait a little longer and see how Microsoft's plans for Reflection.Emit develop".

That is exactly my position after #374. I wanted to see how the reflection emit functionality is exposed in .NET Standard before making a decision, that corefx thread seems to have gone quiet for now.

In the twitter guys from MS ask projects to target to netstandard 2.0 directly

The funny part is that at the time of that tweet the official documentation actually said to do the opposite, I haven't checked if it has been updated since though.

@stakx
Copy link
Member

stakx commented Nov 5, 2018

@jonorossi -

I wanted to see how the reflection emit functionality is exposed in .NET Standard before making a decision [...]

.NET Standard 2.1 has been announced today. Here's the relevant quote regarding Reflection Emit:

Reflection emit. [... M]any of you asked for reflection emit to be included in the .NET Standard. Previously, we’ve tried to provide this via a NuGet package but we discovered that we cannot model such a core technology using a package. With .NET Standard 2.1, you’ll have access to Lightweight Code Generation (LCG) as well as Reflection Emit. Of course, you might run on a runtime that doesn’t support running IL via interpretation or compiling it with a JIT, so we also exposed two new capability APIs that allow you to check for the ability to generate code at all (RuntimeFeature.IsDynamicCodeSupported) as well as whether the generated code is interpreted or compiled (RuntimeFeature.IsDynamicCodeCompiled). This will make it much easier to write libraries that can exploit these capabilities in a portable fashion.

Regarding the platforms that support .NET Standard 2.1:

.NET Framework 4.8 will remain on .NET Standard 2.0 rather than implement .NET Standard 2.1. .NET Core 3.0 as well as upcoming versions of Xamarin, Mono, and Unity will be updated to implement .NET Standard 2.1.

@stakx
Copy link
Member

stakx commented Nov 5, 2018

P.S. (but off-topic here), according to the .NET Standard 2.1 vs 2.0 API diff, there still won't be a AssemblyBuilder.Save method. 😞

@jonorossi
Copy link
Member

@stakx I saw that blog post this morning too, great news we can look at moving forward on this and maybe get .NET Standard 2.1 added to Windsor too to reduce the dependences.

I think AssemblyBuilder.Save will still be a while away since the current implementation in .NET Framework isn't what they want for .NET Core.

@jonorossi
Copy link
Member

To keep everyone informed, we are obviously waiting for .NET Standard 2.1 to be released, not sure when that will be.

@stakx
Copy link
Member

stakx commented Mar 12, 2019

Some news & thoughts regarding .NET Standard 2.x support.

netstandard2.1:

  • Using Visual Studio 2019 Preview and .NET Core 3 Preview, it is now possible to target .NET Standard 2.1 Preview and use System.Reflection.Emit without referencing any additional NuGet package.

  • However, we cannot base a Castle.Core on that (even if we wanted to) because AppVeyor (the CI platform we use for this project) does not have a Visual Studio 2019 image.

  • Visual Studio 2019's official release is on April 2nd 2019. .NET Core 3 (and .NET Standard 2.1 along with it) will not be released until after mid-2019.

  • Therefore we cannot get Castle.Core on netstandard2.1 before much later in 2019.

netstandard2.0:

  • There is now a preview version of the System.Reflection.Emit NuGet package with targets it, and judging from this dotnet/corefx issue, that support is "no longer a lie". (The SRE facilities will however throw PlatformNotSupportedException on AOT platforms.)

  • Using that for a Castle.Core release is possible, but basing a stable library release on a preview doesn't seem like a good idea to me.

  • If we do add netstandard2.0, we probably don't want to keep it around once we have netstandard2.1... or would we have to?

  • I'm not positive whether netstandard2.0 would actually help reduce the total amount of package dependencies in upstream projects a lot. At least it wouldn't make things worse.

My personal suggestion (DISCLAIMER: I'm not a multi-targeting guru):

  • I tend to think a netstandard2.0 target wouldn't be a good solution at this time, at least not until the S.R.E. package goes out of its prerelease state.

  • To bridge the time until netstandard2.1, I think we should replace the existing netstandard1.x targets with netcoreappX.Y targets (or at the very least add the latter). More specifically, add netcoreapp2.1. (If we want to support older .NET Core releases despite them being near or past their official End of Life dates, change that to netcoreapp1.0 and netcoreapp2.0).

@thomaslevesque
Copy link
Contributor

  • If we do add netstandard2.0, we probably don't want to keep it around once we have netstandard2.1... or would we have to?

I think you'd have to. netstandard2.1 will only be supported on .NET Core 3.0, so unless you want to drop all older platforms, you'd have to keep netstandard2.0.

  • I tend to think a netstandard2.0 target wouldn't be a good solution at this time, at least not until the S.R.E. package goes out of its prerelease state.

Agreed, waiting for the stable package is better.

@jonorossi
Copy link
Member

Thanks for the detailed research. I too have been watching the announcements waiting for something that looks like what we need to be released out of preview.

I also agree we need a stable package, not much point trying to use a preview here for a library.

With .NET Core 1.0 and 1.1 will reach End of Life on June 27, 2019 the stable release will probably coincide with us dropping .NET Standard 1.x support. Is that what you guys are thinking?

@stakx
Copy link
Member

stakx commented Mar 20, 2019

the stable release will probably coincide with us dropping .NET Standard 1.x support

Yes. I would even feel comfortable dropping our .NET Standard 1.x targets before the official .NET Core 1.x end of life, if we happened to release earlier than June 27th. The sooner we're rid of it, the better, IMHO.

(My main motivation for moving forward here is that the large dependency graphs caused by netstandard1.x are increasingly undesirable to downstream consumers, and AFAIK, even if they target later versions, the dependency graph won't look clean and tidy as long as we don't offer a netstandard2.x or netcoreapp2.x target.)

@jonorossi
Copy link
Member

I would even feel comfortable dropping our .NET Standard 1.x targets before the official .NET Core 1.x end of life, if we happened to release earlier than June 27th. The sooner we're rid of it, the better, IMHO.

Yep, exactly what I meant my words to say if they didn't.

@jonorossi
Copy link
Member

We currently support:

  • net35, net40, net45, netstandard1.3, netstandard1.5

With .NET Standard 2.1 supporting System.Reflection.Emit I think we should add a .NET Standard 2.1 target when .NET Core 3.0 ships. The API surface in .NET Standard 2.1 is not the full API supported by .NET Framework.

We should consider our position for .NET Core 2.x support since .NET Core 1.x is now end of life. Do we just leave things and keep using .NET Standard 1.3/1.5 for now until .NET Core 2.x is end of life?

With .NET Framework never supporting .NET Standard 2.1, I think we should continue to target .NET Framework 4.5 directly, at least dropping .NET Framework 3.5 (that runtime is so old and I doubt our AppVeyor build is actually testing that CLR version anymore).

@Rabadash8820
Copy link

Any updates on this Issue? Direct support of .NET Standard 2.0 and/or 2.1 would be quite handy.

@stakx
Copy link
Member

stakx commented Mar 10, 2020

I think we should go with the following targets:

  • net45
  • netstandard2.1

And netstandard2.0 iff .NET Core 2.x support is sufficiently important to keep it. My vote goes against it though, that target doesn't officially support System.Reflection.Emit in an honest way, and .NET Core is fast-moving anyway so let people upgrade from .NET Core 2 to 3 if they want to profit from the latest library.

@thomaslevesque
Copy link
Contributor

.NET Core is fast-moving anyway

It's true, but .NET Core 2.1 is still going to be supported for some time (August 2021).
Targeting only netstandard2.1 means that libraries depending on Castle.Core will have to make the same choice if they want to benefit from the latest features. Speaking for FakeItEasy, I don't see us dropping support for netstandard2.0 any time soon. Two years from now, the situation might be different, but today, dropping it probably means leaving behind a majority of users.

@stakx
Copy link
Member

stakx commented Mar 11, 2020

@thomaslevesque - I understand that... your argument is the realistic one, while I'm pushing for a more idealistic goal. Realistically, while we all rely on System.Reflection.Emit, noone really cares that netstandard2.0 doesn't actually support System.Reflection.Emit as long as it "just works" (despite the official statements). Ideally, we (this project and all its dependents) would force ourselves to admit the truth and update to a target that does officially support what we all need.

Another option might be to add an explicit netcoreapp2.0 target, but my NuGet resolution algorithm-fu isn't good enough to judge whether that would actually achieve anything — it suspect it wouldn't help at all.

P.S.: To make my position on this clear: I'm OK with netstandard2.0 if that's what the majority wants and needs (we live in the real world after all, not in some ivory tower), I just think it isn't ideal.

@jonorossi
Copy link
Member

jonorossi commented Apr 28, 2020

@stakx I'm starting to agree that likely no one really cares that .NET Standard 2.0 doesn't really support reflection emit, and we should just drop .NET Standard 1.x support and add .NET Standard 2.0 to get rid of all the cruft of every BCL package being listed. At the same time add .NET Standard 2.1 because that is the target we want people to use, as we'll drop .NET Standard 2.0 in a couple of years.

We should still keep explicit .NET 4.5 for now because there are some features we've got in .NET 4.5 target that are conditionally compiled in, and this is the only platform we can perform IL verification (until we investigate the ILVerify tool).

What I think we should do:

  • Remove net35 and net40
  • Keep net45
  • Remove netstandard1.3 and netstandard1.5
  • Add netstandard2.0 and netstandard2.1

Thoughts?

@stakx
Copy link
Member

stakx commented Apr 28, 2020

Sounds great to me!

@stakx
Copy link
Member

stakx commented May 13, 2020

I think we can close this issue, now that #485 has been merged. 🎆

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants