Closed dustinsoftware closed 4 years ago
@dustinsoftware Hey! Working hard on the weekend eh 😃.
Those libraries are netstandard2.0 compatible, so they're compatible with net461. I've created an example net461 console application that works: https://github.com/JeremyTCD/NodeJSNetFXTest.
That said, the binding redirections were generated wrongly initially. In App.config, Microsoft.Extensions.DependencyInjection.Abstractions was redirected to 3.1.1.0 instead of 2.1.0.0:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.Extensions.DependencyInjection.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.1.1.0" newVersion="3.1.1.0" />
</dependentAssembly>
...
</configuration>
This caused the following error:
Unhandled Exception: System.IO.FileLoadException: Could not load file or assembly 'Microsoft.Extensions.DependencyInjection.Abstractions, Version=3.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040) ---> System.IO.FileLoadException: Could not load file or assembly 'Microsoft.Extensions.DependencyInjection.Abstractions, Version=2.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
--- End of inner exception stack trace ---
at NodeJSNetFXTest.Program.Main()
I fixed App.config manually:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.Extensions.DependencyInjection.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.1.0.0" newVersion="2.1.0.0" />
</dependentAssembly>
...
</configuration>
The application runs fine now.
1
Press any key to continue . . .
I'll spend some time later today to try and figure out why the binding redirections are generated wrongly. Also https://github.com/reactjs/React.NET/pull/1021 is interesting, will look at it this week!
Yeah after adding the library to the net461
web app sample I'm working on, some assembly in the dependency graph wants 2.2.0.0
versions of Microsoft.Extensions.FileProviders.Abstractions
and Microsoft.Extensions.Primitives
. Adding binding redirects to 2.1.0.0
seems to get past this error for now. I suspect the Microsoft.AspNetCore.Hosting.Abstractions
reference is pulling in a lot of unnecessary extra assemblies, some of which may have different version ranges...
Did some googling, turns out binding redirects used to be generated at package install time - Nuget would generate App.config as it installed packages - But that method is buggy:
what seems to be happening here, is that you are still using the packages.config model for NuGet references, which is why NuGet is adding the Binding redirects at install time. This logic is faulted in many cases and legacy, and the new way to generate the binding redirects is at build time...
It seems like the way to generate at build time is by enabling the AutoGenerateBindingRedirects property, which has been enabled by default since 4.5.1.
This means App.config is redundant unless you need custom bindings. So I deleted my App.config and rebuilt. The application ran fine. A NodeJSNetFXTest.exe.config file containing generated binding redirects was created in the output folder. Seems like the Nuget-generated App.config is unreliable and unnecessary in most cases.
Does deleting App.config work in your web project?
I double checked why we're depending on it. We're using the Microsoft.AspNetCore.Hosting.Abstractions.IHostingEnvironment
interface:
We're using it to check whether the consuming project is a .Net Core web project. If it is, we're using it to retrieve the content root path. Unfortunately I'm not aware of any other way to accomplish the same things so I think we need Microsoft.AspNetCore.Hosting.Abstractions.
Auto generating the bindings did not work for the ASP.NET MVC project; had to add them manually. This could also be non-desirable for a large legacy app that wants to take a dependency on this library and already has working binding redirects.
I’ll see what I can do to strip out out the Net core package references; it would simplify greatly the dependency graph and reduce the chance of frustrating assembly loading issues like the ones I ran into.
Would you be interested in upstreaming these changes if I get them to work?
On Sat, Feb 1, 2020 at 23:18, JeremyTCD notifications@github.com wrote:
Buggy Binding Redirects
Did some googling, turns out binding redirects used to be generated at package install time - Nuget would generate App.config as it installed packages - But that method is buggy https://github.com/dotnet/runtime/issues/27430#issuecomment-491360204:
what seems to be happening here, is that you are still using the packages.config model for NuGet references, which is why NuGet is adding the Binding redirects at install time. This logic is faulted in many cases and legacy, and the new way to generate the binding redirects is at build time...
It seems like the way to generate at build time is by enabling the AutoGenerateBindingRedirects https://docs.microsoft.com/en-us/dotnet/framework/configure-apps/how-to-enable-and-disable-automatic-binding-redirection property, which has been enabled by default since 4.5.1.
This means App.config is redundant unless you need custom bindings. So I deleted my App.config and rebuilt. The application ran fine. A NodeJSNetFXTest.exe.config file containing generated binding redirects was created in the output folder. Seems like the Nuget-generated App.config is unreliable and unnecessary in most cases.
Does deleting App.config work in your web project? Microsoft.AspNetCore.Hosting.Abstractions
I double checked why we're depending on it. We're using the Microsoft.AspNetCore.Hosting.Abstractions.IHostingEnvironment interface:
We're using it to check whether the consuming project is a .Net Core web project. If it is, we're using it to retrieve the content root path. Unfortunately I'm not aware of any other way to accomplish the same things so I think we need Microsoft.AspNetCore.Hosting.Abstractions.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/JeringTech/Javascript.NodeJS/issues/68?email_source=notifications&email_token=AAHGCFTKY6LR3JGPXCB2RSDRAZXVDA5CNFSM4KOXQQNKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEKRPWVI#issuecomment-581106517, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAHGCFQOQL4IBBIONPD7XADRAZXVDANCNFSM4KOXQQNA .
I agree with your point about having to tinker with binding redirects, it's not ideal. I understand what you're trying to do to solve this - build a lightweight clone without all the extra features like DI and logging so there are fewer dependencies and lower likelihood of binding redirect issues.
Unfortunately, it isn't possible to upstream such changes to this repo because that would break consuming apps that use logging, DI etc. These features were inherited from the recently deprecated Microsoft.AspNetCore.NodeServices that this library is a replacement for; they're widely used in AspNetCore/NetCore apps.
Splitting off a lightweight clone will require some effort. May I suggest that we first attempt to figure out why App.config isn't being generated properly for legacy NetFX projects? If we can fix that so legacy projects don't need extra steps to use this library, then there is less impetus for a lightweight clone. Could I have access to your example Asp.Net MVC project?
Yeah I updated the sample project here: https://github.com/reactjs/React.NET/blob/252041ddcc53a948e7a8ce5593bd8c743d38314a/src/React.Sample.Mvc4/packages.config
A diff:
diff --git a/src/React.Sample.Mvc4/packages.config b/src/React.Sample.Mvc4/packages.config
index 18a9fb9..13b5558 100644
--- a/src/React.Sample.Mvc4/packages.config
+++ b/src/React.Sample.Mvc4/packages.config
@@ -6,12 +6,84 @@
<package id="JavaScriptEngineSwitcher.V8" version="3.1.0" targetFramework="net45" />
<package id="JavaScriptEngineSwitcher.V8.Native.win-x64" version="3.1.0" targetFramework="net45" />
<package id="JavaScriptEngineSwitcher.V8.Native.win-x86" version="3.1.0" targetFramework="net45" />
+ <package id="Jering.IocServices.System.Net.Http" version="0.4.0" targetFramework="net461" />
+ <package id="Jering.Javascript.NodeJS" version="5.3.0" targetFramework="net461" />
<package id="Microsoft.AspNet.Mvc" version="4.0.40804.0" targetFramework="net45" />
<package id="Microsoft.AspNet.Razor" version="2.0.30506.0" targetFramework="net4" />
<package id="Microsoft.AspNet.Web.Optimization" version="1.1.3" targetFramework="net4" />
<package id="Microsoft.AspNet.WebPages" version="2.0.30506.0" targetFramework="net4" />
+ <package id="Microsoft.AspNetCore.Hosting.Abstractions" version="2.1.0" targetFramework="net461" />
+ <package id="Microsoft.AspNetCore.Hosting.Server.Abstractions" version="2.1.0" targetFramework="net461" />
+ <package id="Microsoft.AspNetCore.Http.Abstractions" version="2.1.0" targetFramework="net461" />
+ <package id="Microsoft.AspNetCore.Http.Features" version="2.1.0" targetFramework="net461" />
+ <package id="Microsoft.Bcl.AsyncInterfaces" version="1.0.0" targetFramework="net461" />
+ <package id="Microsoft.Extensions.Configuration" version="2.1.0" targetFramework="net461" />
+ <package id="Microsoft.Extensions.Configuration.Abstractions" version="2.1.0" targetFramework="net461" />
+ <package id="Microsoft.Extensions.Configuration.Binder" version="2.1.0" targetFramework="net461" />
+ <package id="Microsoft.Extensions.DependencyInjection" version="2.1.0" targetFramework="net461" />
+ <package id="Microsoft.Extensions.DependencyInjection.Abstractions" version="2.1.0" targetFramework="net461" />
+ <package id="Microsoft.Extensions.FileProviders.Abstractions" version="2.1.0" targetFramework="net461" />
+ <package id="Microsoft.Extensions.Hosting.Abstractions" version="2.1.0" targetFramework="net461" />
+ <package id="Microsoft.Extensions.Logging" version="2.1.0" targetFramework="net461" />
+ <package id="Microsoft.Extensions.Logging.Abstractions" version="2.1.0" targetFramework="net461" />
+ <package id="Microsoft.Extensions.Options" version="2.1.0" targetFramework="net461" />
+ <package id="Microsoft.Extensions.Primitives" version="2.1.0" targetFramework="net461" />
+ <package id="Microsoft.NETCore.Platforms" version="1.1.0" targetFramework="net461" />
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net4" />
+ <package id="Microsoft.Win32.Primitives" version="4.3.0" targetFramework="net461" />
+ <package id="NETStandard.Library" version="1.6.1" targetFramework="net461" />
<package id="Newtonsoft.Json" version="12.0.1" targetFramework="net45" />
+ <package id="System.AppContext" version="4.3.0" targetFramework="net461" />
+ <package id="System.Buffers" version="4.5.0" targetFramework="net461" />
+ <package id="System.Collections" version="4.3.0" targetFramework="net461" />
+ <package id="System.Collections.Concurrent" version="4.3.0" targetFramework="net461" />
+ <package id="System.Console" version="4.3.0" targetFramework="net461" />
+ <package id="System.Diagnostics.Debug" version="4.3.0" targetFramework="net461" />
+ <package id="System.Diagnostics.DiagnosticSource" version="4.3.0" targetFramework="net461" />
+ <package id="System.Diagnostics.Tools" version="4.3.0" targetFramework="net461" />
+ <package id="System.Diagnostics.Tracing" version="4.3.0" targetFramework="net461" />
+ <package id="System.Globalization" version="4.3.0" targetFramework="net461" />
+ <package id="System.Globalization.Calendars" version="4.3.0" targetFramework="net461" />
+ <package id="System.IO" version="4.3.0" targetFramework="net461" />
+ <package id="System.IO.Compression" version="4.3.0" targetFramework="net461" />
+ <package id="System.IO.Compression.ZipFile" version="4.3.0" targetFramework="net461" />
+ <package id="System.IO.FileSystem" version="4.3.0" targetFramework="net461" />
+ <package id="System.IO.FileSystem.Primitives" version="4.3.0" targetFramework="net461" />
+ <package id="System.Linq" version="4.3.0" targetFramework="net461" />
+ <package id="System.Linq.Expressions" version="4.3.0" targetFramework="net461" />
+ <package id="System.Memory" version="4.5.3" targetFramework="net461" />
+ <package id="System.Net.Http" version="4.3.0" targetFramework="net461" />
+ <package id="System.Net.Primitives" version="4.3.0" targetFramework="net461" />
+ <package id="System.Net.Sockets" version="4.3.0" targetFramework="net461" />
+ <package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net461" />
+ <package id="System.ObjectModel" version="4.3.0" targetFramework="net461" />
+ <package id="System.Reflection" version="4.3.0" targetFramework="net461" />
+ <package id="System.Reflection.Extensions" version="4.3.0" targetFramework="net461" />
+ <package id="System.Reflection.Primitives" version="4.3.0" targetFramework="net461" />
+ <package id="System.Resources.ResourceManager" version="4.3.0" targetFramework="net461" />
+ <package id="System.Runtime" version="4.3.0" targetFramework="net461" />
+ <package id="System.Runtime.CompilerServices.Unsafe" version="4.6.0" targetFramework="net461" />
+ <package id="System.Runtime.Extensions" version="4.3.0" targetFramework="net461" />
+ <package id="System.Runtime.Handles" version="4.3.0" targetFramework="net461" />
+ <package id="System.Runtime.InteropServices" version="4.3.0" targetFramework="net461" />
+ <package id="System.Runtime.InteropServices.RuntimeInformation" version="4.3.0" targetFramework="net461" />
+ <package id="System.Runtime.Numerics" version="4.3.0" targetFramework="net461" />
+ <package id="System.Security.Cryptography.Algorithms" version="4.3.0" targetFramework="net461" />
+ <package id="System.Security.Cryptography.Encoding" version="4.3.0" targetFramework="net461" />
+ <package id="System.Security.Cryptography.Primitives" version="4.3.0" targetFramework="net461" />
+ <package id="System.Security.Cryptography.X509Certificates" version="4.3.0" targetFramework="net461" />
+ <package id="System.Text.Encoding" version="4.3.0" targetFramework="net461" />
+ <package id="System.Text.Encoding.Extensions" version="4.3.0" targetFramework="net461" />
+ <package id="System.Text.Encodings.Web" version="4.6.0" targetFramework="net461" />
+ <package id="System.Text.Json" version="4.6.0" targetFramework="net461" />
+ <package id="System.Text.RegularExpressions" version="4.3.0" targetFramework="net461" />
+ <package id="System.Threading" version="4.3.0" targetFramework="net461" />
+ <package id="System.Threading.Tasks" version="4.3.0" targetFramework="net461" />
+ <package id="System.Threading.Tasks.Extensions" version="4.5.2" targetFramework="net461" />
+ <package id="System.Threading.Timer" version="4.3.0" targetFramework="net461" />
+ <package id="System.ValueTuple" version="4.5.0" targetFramework="net461" />
+ <package id="System.Xml.ReaderWriter" version="4.3.0" targetFramework="net461" />
+ <package id="System.Xml.XDocument" version="4.3.0" targetFramework="net461" />
<package id="WebActivatorEx" version="2.2.0" targetFramework="net45" />
<package id="WebGrease" version="1.6.0" targetFramework="net45" />
</packages>
Noted the large number of assemblies brought in. We can continue discussing that in #70.
After further investigation on my machine, it seems binding redirects are generated fine for new projects. Issues arise when you install packages with the same dependencies but different versions of them - then you often have to manually update binding redirects.
The NuGet team knows there are issues but a fixes aren't a priority for them, instead they're recommending people move to the SDK style projects.
It should also reduce the binding redirect issues. With packages.config projects, NuGet modifies the app.config file with binding redirects on package install, or upgrade,. But there are issues when project references have different versions of the same nuget dependency. With PackageReference, binding redirects are calculated at build time, based on all the assemblies available after compilation, so that it can more accurately use the correct values.
Cutting down the number of dependencies will help. Apart from that I don't think we can fix this problem cleanly on our side.
Closed per linked PR
@dustinsoftware Hey! Working hard on the weekend eh 😃.
Those libraries are netstandard2.0 compatible, so they're compatible with net461. I've created an example net461 console application that works: https://github.com/JeremyTCD/NodeJSNetFXTest.
That said, the binding redirections were generated wrongly initially. In App.config, Microsoft.Extensions.DependencyInjection.Abstractions was redirected to 3.1.1.0 instead of 2.1.0.0:
<?xml version="1.0" encoding="utf-8"?> <configuration> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" /> </startup> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="Microsoft.Extensions.DependencyInjection.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-3.1.1.0" newVersion="3.1.1.0" /> </dependentAssembly> ... </configuration>
This caused the following error:
Unhandled Exception: System.IO.FileLoadException: Could not load file or assembly 'Microsoft.Extensions.DependencyInjection.Abstractions, Version=3.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040) ---> System.IO.FileLoadException: Could not load file or assembly 'Microsoft.Extensions.DependencyInjection.Abstractions, Version=2.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040) --- End of inner exception stack trace --- at NodeJSNetFXTest.Program.Main()
I fixed App.config manually:
<?xml version="1.0" encoding="utf-8"?> <configuration> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" /> </startup> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="Microsoft.Extensions.DependencyInjection.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-2.1.0.0" newVersion="2.1.0.0" /> </dependentAssembly> ... </configuration>
The application runs fine now.
1 Press any key to continue . . .
I'll spend some time later today to try and figure out why the binding redirections are generated wrongly. Also reactjs/React.NET#1021 is interesting, will look at it this week!
Is there any way to know which version of the correct binding redirection should be? How do I know that 3.1.1.0 is the wrong version and 2.1.0.0 is the right one
@Smartisa apologies for the slow response.
I don't remember the details of this issue, but from scanning through the above comments I think multiple assemblies referenced different versions of the same dependency and 2.1.0.0 just happened to be the version that satisfied all references.
Feel free to open a new issue if you have any other questions.
First of all, thanks for shipping this project!
I'm working on pulling it in to React.NET here: https://github.com/reactjs/React.NET/pull/1021
I observed that the nuget package targeting net461 pulls in a few .NET Core dependencies, such as:
As well as a few .NET Standard dependencies which appear to be .NET Core related, but upon further inspection might just work in a Net Framework application:
Is there a sample somewhere for how to get this working in a .NET Framework application? In the meantime I've cloned the project locally and going to dig further...