runtime: Microsoft.Extensions.PlatformAbstractions broken on .NET Core 3.0 preview 2
I understand that Microsoft.Extensions.PlatformAbstractions is “somewhat deprecated” but I suspect there are plenty of class libraries that still depend on it. (The one I’m interested in is Google.Api.Gax; we use it to report the framework version in HTTP headers.)
The expression in question is:
Microsoft.Extensions.PlatformAbstractions.PlatformServices.Default?.Application?.RuntimeFramework?.Version
This has worked fine with .NET Core until now, but under .NET Core 3.0 preview 2, we get an exception:
Unhandled Exception: System.TypeInitializationException: The type initializer for 'Microsoft.Extensions.PlatformAbstractions.PlatformServices' threw an exception. ---> System.Reflection.TargetParameterCountException: Parameter count mismatch.
at System.Reflection.RuntimeMethodInfo.InvokeArgumentsCheck(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
at Microsoft.Extensions.PlatformAbstractions.ApplicationEnvironment.GetEntryAssembly()
at Microsoft.Extensions.PlatformAbstractions.ApplicationEnvironment..ctor()
at Microsoft.Extensions.PlatformAbstractions.PlatformServices..ctor()
at Microsoft.Extensions.PlatformAbstractions.PlatformServices..cctor()
--- End of inner exception stack trace ---
at Microsoft.Extensions.PlatformAbstractions.PlatformServices.get_Default()
I would expect .NET Core 3.0 to be compatible with older versions of .NET Core - if it’s not, that’s a pretty unfortunate story for class library developers.
I’ve confirmed that I can use System.Reflection.Assembly.GetEntryAssembly().GetCustomAttribute<TargetFrameworkAttribute>().FrameworkName from netstandard1.3 (the .NET Standard version I’m targeting in the class library) - I’ll need to do a bit of parsing, but it’s all feasible. That only helps users who are able to update to a newer version of my library though - it feels to me like it shouldn’t be necessary.
This looks like the code that’s throwing in PlatformAbstractions:
var getEntryAssemblyMethod =
typeof(Assembly).GetMethod("GetEntryAssembly", BindingFlags.Static | BindingFlags.NonPublic) ??
typeof(Assembly).GetMethod("GetEntryAssembly", BindingFlags.Static | BindingFlags.Public);
return getEntryAssemblyMethod.Invoke(obj: null, parameters: Array.Empty<object>()) as Assembly;
Obviously using reflection invites compatibility issues, but is there any reason we can’t preserve a parameterless GetEntryAssembly method for compatibility?
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Comments: 17 (9 by maintainers)
@loop-evgeny: As a workaround, if you add an explicit dependency on Google.Api.Gax.Rest version 2.6.0, that should fix the issue for you. Later releases of Google.Cloud.BigQuery.V2 will have the updated dependency themselves.
While I don’t want this to become precedent, it should be easy enough to change the private method to be named something else, assuming that’s actually the problem.
While that’s entirely reasonable on the face of it, it does seem unfortunate for Microsoft to break their own NuGet package. After all, as a user of that package (which is still listed on NuGet) I don’t know and shouldn’t need to be aware that it uses reflection. I expect a Microsoft package to work with later versions of .NET Core without issues.
Note that the code I quoted before was from the source code of
Microsoft.Extensions.PlatformAbstractions.ApplicationEnvironment. Perhaps it would be best to create a new version of that (a patch bump would probably be most appropriate) so that users can just update their dependencies?+1 for “deprecation on NuGet” in general. There’s no way that we should require general .NET Core developers (who aren’t explicitly even using ASP.NET Core) to follow announcements on https://github.com/aspnet.
I think a clearer distinction between ASP.NET Core and non-ASP.NET-core packages would be welcome as well. While the package source code is in https://github.com/aspnet, there’s nothing obviously ASP.NET-Core-centric about it. I wouldn’t want to speak for other developers, but for me, I’d expect a closer binding between explicitly ASP.NET-Core-centric packages and .NET Core versioning than for more general packages.
Does that mean you can’t update it and build a patch version though?
It’s one thing for Microsoft to say “The way we used to recommend you detect the runtime version in a platform-agnostic way is no longer the recommended way of doing so.” (Not that the package description says that.) It’s another to say “If you used the recommended way before, you now need to change your code if you want it to keep working on .NET Core 3.0.”