Closed EWSoftware closed 4 years ago
We have a similar problem where we need Microsoft.Build.Engine.dll to be included in the list. For the other 2 assemblies, I'm assuming that's related to https://github.com/microsoft/MSBuildLocator/issues/95. We were able to use binding redirects as a work around for now.
In my case the two System assemblies aren't part of my project so there's nothing to redirect to. I didn't feel I should have to add them to my project as they are already part of the MSBuild file set and it can find them there so I added them to the build locator.
For completeness, the workaround is to copy the relevant <dependentAssembly>
tags from MSBuild.exe.config to the config file of the application hosting MSBuild. It has the same downsides as this fix, i.e. it is not future-proof.
@ladipro Copying the binding redirects only work when the consuming application also ships those assemblies, and the correct versions of them.
If I have an application that consumes Microsoft.Build.* but does not include System.Runtime.CompilerServices.Unsafe or System.Numerics.Vectors, then adding a binding redirect achieves nothing.
This will become more of a problem as Microsoft.Build continues to expands its dependency tree, as you have identified.
Requiring manual management of these redirects or redistributing these dependencies breaks the core contracts of MSBuildLocator, which is that the consumer can simply reference Microsoft.Build without redistributing it.
This PR is a very good interim fix, and though it doesn't fix the ever-expanding scope problem, is necessary right now, as MSBuildLocator current is broken for consumers that have VS2019 v16.7 installed.
If you want to solve the bigger problem, by all means do so - we will need to tackle it eventually - but for now we need something that gets users back up and running, and this PR does exactly that.
For completeness, the workaround is to copy the relevant
<dependentAssembly>
tags from MSBuild.exe.config to the config file of the application hosting MSBuild. It has the same downsides as this fix, i.e. it is not future-proof.
The binding redirects will work even if you don't ship the MSBuild assemblies, but only if you know what version of MSBuild you'll be using at runtime, which defeats the purpose of using MSBuildLocator. So I would argue that the binding redirects solution has more downsides than the solution proposed in this PR. While the solution in this PR may not be future-proof, it's the best solution currently available.
Wondering what others think, thanks!
I think modularity in .NET is a dumpster fire. It doesn't stop with MSBuild. The whole idea that this is an MSBuild issue is a joke. Why is MSBuild solving modularity problems?
The PROBLEM is that in .NET Core, Microsoft decided the best way to deal with nuget package transitive references was to auto-generate a deps.json file and add the best way to deal with runtime hotfixes was with a RollForward flag that is cooked into runtimeSettings.json. This creates a very uncohesive world for ANY plug-ins that DON'T get determined at compile time. Which means ANY application that has ANY sort of plug-in model.
Note that https://nickcraver.com/blog/2020/02/11/binding-redirects/#the-best-fix says (emphasis mine):
The best fix
The best fix is “go to .NET Core”. Since .NET Framework (e.g. 4.5, 4.8, etc.) has a heavy backward compatibility burden, meaning that the assembly loader itself is basically made of unstable plutonium with a hair trigger coated in flesh eating bacteria behind a gate made of unobtanium above a moat of napalm filled with those jellyfish that kill you…that won’t ever really be fixed.
However, .NET Core’s simplified assembly loading means it just works. I’m not saying a migration to .NET Core is trivial, that depends on your situation, but it is generally the best long-term play. We’re almost done porting Stack Overflow to .NET Core, and this kind of pain is one of the things we’re very much looking forward to not fighting ever again.
The problem is that the assembly loading just works, except when it doesn't. And nobody can figure out why because it's all a run-time thing.
The binding redirects will work even if you don't ship the MSBuild assemblies, but only if you know what version of MSBuild you'll be using at runtime, which defeats the purpose of using MSBuildLocator. So I would argue that the binding redirects solution has more downsides than the solution proposed in this PR. While the solution in this PR may not be future-proof, it's the best solution currently available.
That's a good point. I agree with this assessment and am in favor of taking this fix for now.
Thanks @rainersigwald!
Could you please publish a new release with this change to NuGet?
Having System.Runtime.CompilerServices.Unsafe
and System.Numerics.Vector
in the array makes the locator say that MSBuild assemblies are already loaded if any of these two, completely unrelated, assemblies are loaded in the process.
I'd rather not see a build with this change.
@powercode that's a great point now tracked by #102.
Added Microsoft.Build.Engine and two supporting assemblies to the set that can be loaded. These needed to be included in order for my project to work properly with the build locator.