5

Closed

NuGet should not generate binding redirects for binaries that are in the current framework

description

We're hitting an issue with Microsoft.Bcl package where NuGet is adding a binding redirect for a binary that is considered part of the framework, this causes the application to crash because the binding redirect refers to assembly version that is not available at runtime.

@Repro:
  1. Create a new Console Application targeting 4.5
  2. Create a new Portable Library targeting .NET Framework 4.5, Silverlight 4, Windows Phone 7.5 and .NET for Windows Store apps
  3. Add a reference to the portable library from the Console Application
  4. Install the Microsoft.Bcl package (1.0.16-rc) to both projects
@Expected: No binding redirect for System.Runtime in the .NET Framework 4.5 project because a later version is part of the target framework (see C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.5\RedistList\FrameworkList.xml)
@Actual: Binding redirect
<dependentAssembly>
    <assemblyIdentity name="System.Runtime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-1.5.11.0" newVersion="1.5.11.0" />
  </dependentAssembly>

You can use the IVsFrameworkMultiTargeting to determine if a given assembly version is available as part of a given target framework.
Closed Jul 19, 2013 at 10:22 PM by deepakverma
verified it's fixed for this case in 2.7

comments

davkean wrote Feb 22, 2013 at 5:32 PM

Make sure when you fix this, that you only skip the binding redirect if a later or same version is available in the framework.

dotnetjunky wrote Feb 26, 2013 at 5:03 PM

We'll do this in 2.4 release.

dotnetjunky wrote Jun 9, 2013 at 2:15 AM

Is IVsFrameworkMultiTargeting.IsReferenceableInTargetFx the method I need to call? What should I pass to pwszAssemblySpec?

davkean wrote Jun 10, 2013 at 5:58 PM

It's the full name of the assembly (mscorlib, Version=[version], PublicKeyToken=[token], Culture=[culture]). It can either contain all the information (key, version, etc), or just the simple name ("mscorlib")

dotnetjunky wrote Jun 12, 2013 at 11:09 PM

So look like I can only check for the same version of the target framework. Can't check for a later version using this method, because I don't know what future versions will be.

davkean wrote Jun 13, 2013 at 4:52 PM

That's fine. That's exactly the behavior we want. For example, System.Runtime didn't ship in 4.0, but did in 4.5. We still want a binding redirect generated for it in 4.0, but not for 4.5.

dotnetjunky wrote Jun 13, 2013 at 11:15 PM

I followed the exact same steps above, but there's no binding redirect added to the Console Application. It's only added to the Portable Library project. Is that the bug?

dotnetjunky wrote Jun 13, 2013 at 11:19 PM

The binding redirects added to the Portable Library project seems to come from the Microsoft.Bcl package itself (from the content folder's app.config.transform file). this looks like a non-bug.

davkean wrote Jun 14, 2013 at 2:15 AM

I'm chasing up the repro with Eric St. John. He walked through the code and figured out where it was broken.

It's the not the app.config.tranform, notice how the net45 content is empty, and hence no transforms. We also marked our transforms with a special marker that indicates that we added the redirects . The binding redirects we were seeing were not coming from us.

dotnetjunky wrote Jun 14, 2013 at 3:08 AM

Are you seeing the binding redirects added to the Console Application or the Portable Library? I don't see binding redirect added to Console Application, only the Portable Library.

davkean wrote Jun 14, 2013 at 3:55 AM

Yes I'm talking about the ConsoleApplication. The binding redirects in the portable library project are expected, and do not affect runtime behavior (as the app.config is ignored and not copied to the app project), and hence can't cause an application to crash.

I've found another repro (NuGet has really weird logic around when it decides to add binding redirects so it was hard to find a repro).

The repro is instead of using the Microsoft.Bcl package, install the Microsoft.Net.Http, 2.2.3-beta package. Make sure you are targeting 4.5 from the ConsoleApplication and the exact platforms that I called out above for portable.

davkean wrote Jun 14, 2013 at 3:59 AM

Also, the ConsoleApplication must be referencing the portable project before installing the package.

dotnetjunky wrote Jun 14, 2013 at 5:13 PM

OK now I can repro

dotnetjunky wrote Jun 14, 2013 at 5:40 PM

OK, I've got a fix now. It no longer adds the binding redirect for System.Runtime.dll, but still adds one for System.Net.Http.Primitives. I guess it's expected, right? Please confirm.
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.Net.Http.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-4.2.3.0" newVersion="4.2.3.0" />
      </dependentAssembly>
    </assemblyBinding>

davkean wrote Jun 14, 2013 at 6:13 PM

Yes that's correct. System.Net.Http.Primitives does not exist in the framework.

dotnetjunky wrote Jun 19, 2013 at 10:56 PM

Fixed in changeset b8d515f6341193b970d2a9d837e580e762d2eb71

theboyknowsclass wrote Aug 9, 2013 at 1:30 PM

i get the same issue with my test project still, runtime being added... if i comment this out the tests run fine... if not i get exceptions thrown from json.net

theboyknowsclass wrote Aug 9, 2013 at 1:31 PM

(or i can change the version up to 4.0.0.0 or something and it works)