Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Binding Redirect being added to every app.config

I have 20 projects in a solution file. 1 of the projects is a standard library project that all the the projects reference.

About a year ago we added a new nuget package, we'll call it Package A Version 5.0.0.0. It had a bunch of files that it would transfer all over when we compiled but we eventually dealt with it. We added the package to our standard library project (the one the other 19 reference).

I am new to Nuget (so maybe I did something wrong) so I made a new package to serve as a helper for Package A. I had set everything up so that the helper has a dependency on Package A version 3.0.0.0 to 5.0.0.0 (So it works for others who have a lower version than us). Lets call this new package Package A helper

I install Package A helper and everything is working as it should. I go to do a pull request and every single app.config in our solution now has

<runtime>
      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
              <dependentAssembly>
                      <assemblyIdentity name="Package.A" publicKeyToken="8FC3CCAD86" culture="neutral"/>
                      <bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0"/>
              </dependentAssembly>
      </assemblyBinding>
</runtime>

It will compile fine without it, but visual studio complains and gives a warning. What gives? My manager won't let me merge my code now because it adds too much noise into app.config and depends too much on Package A.

why did adding a nuget package that depended on Package A then have to have this new bindingRedirect when the main dependency was already met before we installed Package A Helper?

And why does it say 0.0.0.0-5.0.0.0 when I specified 3.0.0.0-5.0.0.0 in the nuget package and package.config

Update:

When I build Package A helper with references to Package A version 5.0.0.0 then all the bindingRedirects don't get auto-populated in every app.config but instead warnings are generated. I had originally built it with 3.0.0.0 because I figured it was best to build it with the lowest dependency. The problem still exists because visual studio is still warning and suggesting bindingRedirects are created.

No way to resolve conflict between "Package A, Version=5.0.0.0, Culture=neutral, PublicKeyToken=83hfhsd33" and "Package A, Version=3.0.0.0, Culture=neutral, PublicKeyToken=83hfhsd33". Choosing "Package A, Version=5.0.0.0, Culture=neutral, PublicKeyToken=83hfhsd33" arbitrarily.
Consider app.config remapping of assembly "Package A, Culture=neutral, PublicKeyToken=83hfhsd33" from Version "3.0.0.0" [] to Version "5.0.0.0" [path to Package A dll] to solve conflict and get rid of warning.

Is the solution just to change my nuget package dependency from 3.0.0.0 to 5.0.0.0 and just allow 5.0.0.0 and get rid of my allowedVersions="[3,6)" in me packages.config? I don't want to reduce the helpfulness and backwards compatiblity of my nuget package but at the same time I want no warnings or bindingRedirects required for my main solution.

Update 2: So setting Copy Local in the reference properties to False actually solved my issues, but I don't understand why.

like image 631
LearningJrDev Avatar asked Mar 30 '16 21:03

LearningJrDev


1 Answers

I had originally built it with 3.0.0.0 because I figured it was best ...

That is where the problem started. Your solution now depends on two distinct versions of A.dll, one is going to overwrite the other. Which version of A.dll ends up getting copied into bin\Debug is random. Whatever project was built last.

This can not come to good end, the solution is doomed to fail to execute. If will either be the code in A-helper.dll, it will fail when version 5.0.0.0 ends up getting copied. Or it will be the code in whatever other project uses A.dll, it will fail when version 3.0.0.0 gets copied. End result is that the solution will always fail.

So you are seeing the build system doing something about it. It notices the discrepancy and elects one of the versions to win. It picks 5.0.0.0, that was the correct choice. And it also modifies app.config, adding the bindingRedirect so code that asks for the 3.0.0.0 version to be loaded will actually get 5.0.0.0. That could work if you made version 5 compatible enough with version 3. Or not, two increments in the major version number usually spells trouble. You'll find out when you test.

So setting Copy Local in the reference properties to False actually solved my issues

That did not solve an issue, you merely prevented the build system from assuming that it should solve this problem for you. Since it no longer had to copy the DLL, it guesses that you'll install the assemblies in the GAC so that both versions can co-exist. Maybe you did, it is not common and in general very unwise to do so on a dev machine. Very unlikely that your boss and team members will like this solution given the extra install step.


So there are two basic things you can do:

  • Let the build system sort this out. As it did, it solved the problem correctly and your solution will work. If version 5 is compatible enough with version 3 then the code in A-helper.dll will even execute correctly. If the boss doesn't like it then you'll of course have to scratch this and do:

  • Change the reference in the A-helper project to A version 5.0.0.0. Now there no longer is any incompatibility, the one-and-only A.dll is good for all the code. Given your requirement, this is the only solution your boss will like.

like image 127
Hans Passant Avatar answered Nov 01 '22 10:11

Hans Passant