We have a solution with 100+ projects (part of a big ugly .Net Framework Monolith app). Now we are pushing to move as much code as possible as NuGet packages to our internal repo. But now we are in a dependency hell, because even though all of our code is unsigned, most of the 3rd party NuGets are signed. As well as all the Microsoft packages.
This hell got worse since we migrated from packages.config to PackageReference, because many dependencies became implicit (being transitive). On one hand we want to use PackageReference, because:
But on the other hand it is hellish to sort through all these binding redirects. And the worst thing - it is not consistent from msbuild to VS IDE, see Why does console build generate radically different project.assets.json than that generated with VS IDE build?
I want to get rid of them once and for all. My idea is:
I wonder if anyone has tried this approach. Cannot be that we are the only ones that are struggling with the binding redirects, this device of torture inflicted upon us undoubtfully for the sin of programming .Net rather than Java.
I have a concrete question - has anyone succeeded in replacing all the config time assembly binding redirects with a logic at runtime? I want to suppress all of the binding redirect related warnings and forget about them once and for all while staying in .Net Framework (not Core) realm.
Edit 1
So, there is a desire to see a sample of concrete binding redirect warnings that we have. Alright:
MSB3247: Found conflicts between different versions of the same dependent assembly. In Visual Studio, double-click this warning (or select it and press Enter) to fix the conflicts; otherwise, add the following binding redirects to the "runtime" node in the application configuration file: <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"><dependentAssembly><assemblyIdentity name="System.Buffers" culture="neutral" publicKeyToken="cc7b13ffcd2ddd51" /><bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" /></dependentAssembly></assemblyBinding><assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"><dependentAssembly><assemblyIdentity name="System.Diagnostics.DiagnosticSource" culture="neutral" publicKeyToken="cc7b13ffcd2ddd51" /><bindingRedirect oldVersion="0.0.0.0-4.0.3.1" newVersion="4.0.3.1" /></dependentAssembly></assemblyBinding><assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"><dependentAssembly><assemblyIdentity name="System.Memory" culture="neutral" publicKeyToken="cc7b13ffcd2ddd51" /><bindingRedirect oldVersion="0.0.0.0-4.0.1.1" newVersion="4.0.1.1" /></dependentAssembly></assemblyBinding><assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"><dependentAssembly><assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" /><bindingRedirect oldVersion="0.0.0.0-4.0.6.0" newVersion="4.0.6.0" /></dependentAssembly></assemblyBinding> [C:\xyz\tip\Services\Platform\WBDataSvc\TestServices\TestServices.csproj]
MSB3247: Found conflicts between different versions of the same dependent assembly. In Visual Studio, double-click this warning (or select it and press Enter) to fix the conflicts; otherwise, add the following binding redirects to the "runtime" node in the application configuration file: <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"><dependentAssembly><assemblyIdentity name="System.Buffers" culture="neutral" publicKeyToken="cc7b13ffcd2ddd51" /><bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" /></dependentAssembly></assemblyBinding><assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"><dependentAssembly><assemblyIdentity name="System.Memory" culture="neutral" publicKeyToken="cc7b13ffcd2ddd51" /><bindingRedirect oldVersion="0.0.0.0-4.0.1.1" newVersion="4.0.1.1" /></dependentAssembly></assemblyBinding><assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"><dependentAssembly><assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" /><bindingRedirect oldVersion="0.0.0.0-4.0.6.0" newVersion="4.0.6.0" /></dependentAssembly></assemblyBinding> [C:\xyz\tip\Services\Platform\DeviceServices\DeviceServices.csproj]
MSB3247: Found conflicts between different versions of the same dependent assembly. In Visual Studio, double-click this warning (or select it and press Enter) to fix the conflicts; otherwise, add the following binding redirects to the "runtime" node in the application configuration file: <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"><dependentAssembly><assemblyIdentity name="System.Buffers" culture="neutral" publicKeyToken="cc7b13ffcd2ddd51" /><bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" /></dependentAssembly></assemblyBinding><assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"><dependentAssembly><assemblyIdentity name="System.Memory" culture="neutral" publicKeyToken="cc7b13ffcd2ddd51" /><bindingRedirect oldVersion="0.0.0.0-4.0.1.1" newVersion="4.0.1.1" /></dependentAssembly></assemblyBinding><assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"><dependentAssembly><assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" /><bindingRedirect oldVersion="0.0.0.0-4.0.6.0" newVersion="4.0.6.0" /></dependentAssembly></assemblyBinding> [C:\xyz\tip\Services\Platform\WBDataSvc\DataSvc\DataSvc.csproj]
MSB3247: Found conflicts between different versions of the same dependent assembly. In Visual Studio, double-click this warning (or select it and press Enter) to fix the conflicts; otherwise, add the following binding redirects to the "runtime" node in the application configuration file: <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"><dependentAssembly><assemblyIdentity name="System.Buffers" culture="neutral" publicKeyToken="cc7b13ffcd2ddd51" /><bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" /></dependentAssembly></assemblyBinding><assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"><dependentAssembly><assemblyIdentity name="System.Memory" culture="neutral" publicKeyToken="cc7b13ffcd2ddd51" /><bindingRedirect oldVersion="0.0.0.0-4.0.1.1" newVersion="4.0.1.1" /></dependentAssembly></assemblyBinding><assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"><dependentAssembly><assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" /><bindingRedirect oldVersion="0.0.0.0-4.0.6.0" newVersion="4.0.6.0" /></dependentAssembly></assemblyBinding> [C:\xyz\tip\Services\Platform\WBDataSvc\MobileWebService\MobileWebService.csproj]
MSB3277: Found conflicts between different versions of "System.Diagnostics.DiagnosticSource" that could not be resolved. These reference conflicts are listed in the build log when log verbosity is set to detailed. [C:\xyz\tip\ServerJobs\BackgroundJobTests\BackgroundJobTests.csproj]
MSB3277: Found conflicts between different versions of "System.Diagnostics.DiagnosticSource" that could not be resolved. These reference conflicts are listed in the build log when log verbosity is set to detailed. [C:\xyz\tip\ServerJobs\ImportJobsTests\ImportJobsTests.csproj]
MSB3277: Found conflicts between different versions of "System.Diagnostics.DiagnosticSource" that could not be resolved. These reference conflicts are listed in the build log when log verbosity is set to detailed. [C:\xyz\tip\Services\Platform\WBDataSvc\PayrollEngineDALTests\Payroll.Engine.DB.Tests.csproj]
MSB3277: Found conflicts between different versions of "System.Diagnostics.DiagnosticSource" that could not be resolved. These reference conflicts are listed in the build log when log verbosity is set to detailed. [C:\xyz\tip\Services\Platform\WBDataSvc\PayrollEngineTests\Payroll.Engine.Tests.csproj]
MSB3277: Found conflicts between different versions of "System.Diagnostics.DiagnosticSource" that could not be resolved. These reference conflicts are listed in the build log when log verbosity is set to detailed. [C:\xyz\tip\Services\Platform\WBDataSvc\ReportingEngineSupportTests\ReportingEngineSupportTests.csproj]
MSB3277: Found conflicts between different versions of "System.Diagnostics.DiagnosticSource" that could not be resolved. These reference conflicts are listed in the build log when log verbosity is set to detailed. [C:\xyz\tip\Services\Platform\WBDataSvc\RuleEngineTests\RuleEngineTests.csproj]
MSB3277: Found conflicts between different versions of "System.Diagnostics.DiagnosticSource" that could not be resolved. These reference conflicts are listed in the build log when log verbosity is set to detailed. [C:\xyz\tip\Services\Platform\WBDataSvc\WbDbTests\WbDbTests.csproj]
MSB3277: Found conflicts between different versions of "System.Diagnostics.DiagnosticSource" that could not be resolved. These reference conflicts are listed in the build log when log verbosity is set to detailed. [C:\xyz\tip\Test\UnitTests\UnitTests.csproj]
Now sure enough, we can shuffle the missing binding redirects into the config files, but:
It is one big nuisance.
I decided against trying to replace the config time binding redirects with the runtime assembly resolution. The reasons - I do not know how to ensure it reliably given:
Instead I decided to leverage the following aspects of our setup:
This makes it possible to write a tool that could read project.assets.json for the given project (and recursively for all the other projects it depends on) and based on them do two things:
This way the binaries in the bin folder would not depend on the build order of the projects in the solution and we would have a deterministic process to maintain the binding redirects.
This is a work in progress, but it looks promising - https://github.com/MarkKharitonov/GenerateDotNetBindingRedirects