Visual studio: Can't load 2 versions of Json.NET and using aliases

Viewed 224

M-Files VAF requires json.net version =10.0.3 only, not >=10.0.3. This crashed with Microsoft.PowerBI.API as this does not support this exact dependency in any its versions. It goes from 7.0 -> 11.xx

I have been struggling with this for a day now. I have been following this guide: How to use two versions of the same DLL in the same project

I couldn't even add the second version of json.net from VS.

Then I tried it manually in *.proj file, and app.config like this:

<Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
  <HintPath>..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
  <Aliases>NewJson</Aliases>
</Reference>
<Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
  <HintPath>..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
  <Aliases>OldJson</Aliases>     
</Reference>

App.config

<dependentAssembly>
    <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
    <codeBase version="7.0.0.0" href="FILE:///../packages/Newtonsoft.Json.7.0.1/lib/net45/Newtonsoft.Json.dll" />
    <codeBase version="10.0.0.0" href="FILE:///../packages/Newtonsoft.Json.10.0.3/lib/net45/Newtonsoft.Json.dll" />       
</dependentAssembly>

Does this even work? Or does it look in the GAC first anyway? Can I install version 7 and 10 in the gac?

Either way, referencing the old via ../packages or via the local folder, gives me yellow exclamation sign in VS. VS says as soon as I hit run:
System.IO.FileNotFoundException: Could not load file or assembly 'Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' or one of its dependencies. The system cannot find the file specified.

I did add: extern alias OldJson; and using OldJson::Newtonsoft.Json;

this worked for the NewJson alias.

I have looked at this: .NET: Load two version of the same DLL. I would prefer not to do this in runtime, or is it the best approach? What is the best if I am to later push this to azure service?

Anyone care to share some light on this predicament?

Update: I'm actually using this version of powerbi now: Version 2.0.12. which doesnt require any json.net. But still it errors on loading json.net. Here is cutout from fuslog.

=== Pre-bind state information ===
LOG: DisplayName = Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed
(Fully-specified)
LOG: Appbase = file:///C:/Program Files/M-Files/20.8.9339.3/Bin/x64/
LOG: Initial PrivatePath = NULL
Calling assembly : Microsoft.PowerBI.Api, Version=2.0.12.18114, Culture=neutral, PublicKeyToken=31bf3856ad364e35.
===
LOG: This bind starts in LoadFrom load context.
WRN: Native image will not be probed in LoadFrom context. Native image will only be probed in default load context, like with Assembly.Load().
LOG: Using application configuration file: C:\Program Files\M-Files\20.8.9339.3\Bin\x64\mfappplatform.exe.Config
LOG: Using host configuration file: 
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework64\v4.0.30319\config\machine.config.
LOG: Post-policy reference: Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed
LOG: Attempting download of new URL file:///C:/Program Files/M-Files/20.8.9339.3/Bin/x64/Newtonsoft.Json.DLL.
LOG: Attempting download of new URL file:///C:/Program Files/M-Files/20.8.9339.3/Bin/x64/Newtonsoft.Json/Newtonsoft.Json.DLL.
LOG: Attempting download of new URL file:///C:/Program Files/M-Files/20.8.9339.3/Bin/x64/Newtonsoft.Json.EXE.
LOG: Attempting download of new URL file:///C:/Program Files/M-Files/20.8.9339.3/Bin/x64/Newtonsoft.Json/Newtonsoft.Json.EXE.
LOG: Attempting download of new URL file:///C:/Program Files/M-Files/20.8.9339.3/Server/Data/Apps/{508AA001-0DF6-4396-A440-6985D9C46A7E}/{9DC357E6-D62A-4A53-A8D4-747B23826B2E}-hVIg9CF9YxhkXsvwapj2HCgrFD1Yi6XZhBsR7WU0Be0=/Newtonsoft.Json.DLL.
WRN: Comparing the assembly name resulted in the mismatch: Major Version
LOG: Attempting download of new URL file:///C:/Program Files/M-Files/20.8.9339.3/Server/Data/Apps/{508AA001-0DF6-4396-A440-6985D9C46A7E}/{9DC357E6-D62A-4A53-A8D4-747B23826B2E}-hVIg9CF9YxhkXsvwapj2HCgrFD1Yi6XZhBsR7WU0Be0=/Newtonsoft.Json/Newtonsoft.Json.DLL.
LOG: Attempting download of new URL file:///C:/Program Files/M-Files/20.8.9339.3/Server/Data/Apps/{508AA001-0DF6-4396-A440-6985D9C46A7E}/{9DC357E6-D62A-4A53-A8D4-747B23826B2E}-hVIg9CF9YxhkXsvwapj2HCgrFD1Yi6XZhBsR7WU0Be0=/Newtonsoft.Json.EXE.
LOG: Attempting download of new URL file:///C:/Program Files/M-Files/20.8.9339.3/Server/Data/Apps/{508AA001-0DF6-4396-A440-6985D9C46A7E}/{9DC357E6-D62A-4A53-A8D4-747B23826B2E}-hVIg9CF9YxhkXsvwapj2HCgrFD1Yi6XZhBsR7WU0Be0=/Newtonsoft.Json/Newtonsoft.Json.EXE.

If I use any other version than 10.0.3 of M-Files VAF, it wont even compile.

VS Warning:

VS Warning

Nuget Info lacking JSON.NET 7.0 dependency

Nuget Info

CodeReflect Microsoft.PowerBI.Api.2.0.14 References.

PowerBI References

1 Answers

The Problem Called "Dependency Hell":

enter image description here

Possible Solutions:

There are more ways of loading multiple versions of the same assembly into a single application domain. All of them require the assemblies to be strong-named to avoid identity conflicts.

  • Install Assembly to Global Assembly Cache - an easy way, only to be recommended for production environments. We don't need to touch the application at all because it'll automatically look up the assemblies in the GAC. However, it's not really handy for development environments as the installation has to be repeated on every machine.

  • Perform Custom Resolution via AppDomain.AssemblyResolve event - the most powerful option, especially useful when the loading logic is to be more complex or parameterized.

  • Specify code base - by editing a (web) application configuration file, we can easily point the application to the appropriate DLL versions even if they're not directly in the bin folder.

    <configuration>
      <runtime>
          <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
              <dependentAssembly>
                  <assemblyIdentity name="Some.API" publicKeyToken="12ab3cd4e5f6abcd"
                    culture="neutral" />
                  <codeBase version="1.0.0.0" href="v1\Some.API.dll" />
                  <codeBase version="2.0.0.0" href="v2\Some.API.dll" />
                  <!-- INFO: The version attribute represents an assembly 
                             version which doesn't always have to match the 
                             NuGet package version.
                             The codebase attribute can be anywhere on 
                             the local intranet or the Internet. -->
              </dependentAssembly>
          </assemblyBinding>
      </runtime>
    </configuration>
    

Note: You shouldn't change contents of the CMSDependencies folder. Doing so might break your upgrade path as the folder is meant to contain dependencies of Kentico exclusively.

Helpful Links:

Related