Search code examples
visual-studiovisual-studio-2017nugetcsprojvsix

System.Text.Json requires two different versions of CompilerServices.Unsafe?


For context, I am making a VSIX for VS2017, and I require System.Text.JSON for serializing/deserializing data.I am using version 6.0.0.0 of System.Text.JSON

If I set CompilerServices.Unsafe to 4.0.4.1 (nuget version 4.5.3) (with appropriate binding redirects (see below)), I get this error:

It wants 6.0.0.0

As you can see, it asks for System.Runtime.CompilerServices.Unsafe version 6.0.0.0. Using ILSpy within the target directory, I can see that the version of System.Runtime.CompilerServices.Unsafe that came bundled was version 4.0.4.1, as expected.

In response, I bump System.Runtime.CompilerServices.Unsafe to 6.0.0.0 (nuget version 6.0.0), I get this error!

It wants 4.0.4.1

That's right - now it wants version 4.0.4.1!

Details

app.config, .csproj, packages.config

...with version 4.0.4.1

When I try with version 4.0.4.1 of CompilerServices.Unsafe, I setup my project like so:

  • I setup app.config with a binding redirect to version 4.0.4.1
<dependentAssembly>
        <assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-4.0.4.1" newVersion="4.0.4.1" />
</dependentAssembly>
  • I add a reference to version 4.0.4.1 on the csproj
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
      <HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.4.5.3\lib\net461\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
</Reference>
  • I set it to 4.5.3 in packages.config.
<package id="System.Runtime.CompilerServices.Unsafe" version="4.5.3" targetFramework="net472" />

...with version 6.0.0.0

Similarly, when I set it to 6.0.0.0, I perform the same steps

  • I setup app.config with a binding redirect to version 4.0.4.1
<dependentAssembly>
        <assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
      </dependentAssembly>
  • I setup the csproj
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
          <HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
</Reference>
  • I setup packages.config
<package id="System.Runtime.CompilerServices.Unsafe" version="6.0.0" targetFramework="net472" />

Fix Attempts

A few things I have tried:

  • clear the local package cache (ie, deleting the folder called "packages" at solution root). Result: No Change.

  • remove bin and obj folders. Result: No Change.

  • upgrading system.text.json to version 6.0.7 (Highest version of major version 6.0.0) . Result: No Change.

  • upgrading system.text.json to version 7.0.2 (Latest). Result: No change.

  • downgrading system.text.json. Result: No change.


Solution

  • Alright, "I" figured it out (credit to @zivkan for pointing me in the right direction 😊). Instead of using app.config style of binding redirects (which doesn't work for VSIX) you can instead use ProvideBindingRedirectionAttribute.

    I this line to my AssemblyInfo.cs:

    [assembly: ProvideBindingRedirection(AssemblyName = "System.Runtime.CompilerServices.Unsafe",
          NewVersion = "6.0.0.0", OldVersionLowerBound = "1.0.0.0",
          OldVersionUpperBound = "4.0.4.2")]
    

    ...and, as if by magic, it just works.

    See also: