2

I have two API projects within the same solution (one in which is mine, and another in which I need to reference and should not be changing). Both of these API projects add reference to the Ninject and Ninject.Web.Common package. Here is how the packages are setup:

Ninject.Web.Common In Web Api A - \packages\Ninject.Web.Common.3.3.2\lib\net45\Ninject.Web.Common.dll
Ninject.Web.Common in Web Api B - \packages\Ninject.Web.Common.3.2.3.0\lib\net45-full

(note the versions are different 3.3.2 and 3.2.3)

What's happening is when I try to run my solution I get

Could not load type 'Ninject.Web.Common.OnePerRequestHttpModule' from assembly 'Ninject.Web.Common, Version=3.3.2.0, Culture=neutral, PublicKeyToken=c7192dc5380945e7'.

on my Web Api B project (note it's trying to reference the 3.3.2 version from my Web Api A project).

How can I keep both projects the same and have them reference their own respective version of Ninject?

AxelEckenberger
  • 16,628
  • 3
  • 48
  • 70
845614720
  • 756
  • 1
  • 7
  • 22

3 Answers3

2

You can try one of these approaches:

  1. Create post build step which register the multi-versioned assemblies into the GAC. The CLR will look in the GAC before checking the output folder. Since both assemblies are installed in the GAC, the runtime will find and load the correct versions.
  2. Install both assemblies to the GAC with gacutil.exe. However, it's not very practical for development environments as the installation has to be repeated on every machine. Once installed, set the references` CopyLocal property to False, since there’s no need for them to be in the output folder.
  3. Perform custom resolution via AppDomain.AssemblyResolve event.
  4. Copy assemblies to different folders and specify codebase element. By editing a web application configuration file, you can point the application to the appropriate DLL versions even if they're not directly in the bin folder.
     <configuration>
              <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
                <dependentAssembly>
                  <assemblyIdentity name="SomeStrongNameLib" culture="neutral" publicKeyToken="6a770f8bdf3d476a" />
                  <codeBase version="1.0.0.0" href="StrongNameLibV10/SomeStrongNameLib.dll"/>
                  <codeBase version="1.1.0.0" href="StrongNameLibV11/SomeStrongNameLib.dll"/>
                </dependentAssembly>
              </assemblyBinding>
          </runtime>
        </configuration>
  1. Use binding redirects, but I think that this is not suitable in your case.
  2. Use extern Nuget aliases.

Reference:
Using two different versions of same the nuget package
https://michaelscodingspot.com/how-to-resolve-net-reference-and-nuget-package-version-conflicts/
https://devnet.kentico.com/articles/referencing-multiple-versions-of-the-same-assembly-in-a-single-application

K. B.
  • 3,342
  • 3
  • 19
  • 32
1

You can typically only resolve one version of a given dependency in your dependency graph (nuget restore is mainly for calculating which version to use given your dependency graph).

This is usually fine, but your problem is that OnePerRequestHttpModule was removed between versions 3.2.3 and 3.3.2 of Ninject.Web.Common https://www.fuget.org/packages/Ninject.Web.Common/3.3.2/lib/netstandard2.0/diff/3.2.3/ and WebApiB wanted to use it.

Your options here are to modify WebApiB so it doesn't use OnePerRequestHttpModule any more, or to downgrade the version of Ninject.Web.Common in WebApiA to 3.2.3

rbennett485
  • 1,907
  • 15
  • 24
  • Thank you for your answer, unfortunately I cannot downgrade my current project and I cannot upgrade the other project... I need more of a work around. There *has* to be a way. – 845614720 Mar 21 '21 at 20:53
  • A possible workaround is to reimplement and replace the class missing in the new version and upgrade. Another is separate solutions and DLL references instead of project references for your APIs – Richard Barker Mar 21 '21 at 21:00
  • What Richard said, or instead of reimplementing you can rewrite one of the assemblies so it has a different name and different namespaces with a tool like https://github.com/nullean/assembly-rewriter. These are all nasty solutions though which will almost certainly cause you problems in the future, you're much better off fixing this properly even if it's painful in the short term – rbennett485 Mar 22 '21 at 20:19
-1

I see you are on 4.5 FW but:

If you are already on the newer csproj format or you can upgrade to it (this is just to change the format of csproj, the project itself will still target what it was targeting)

https://natemcmaster.com/blog/2017/03/09/vs2015-to-vs2017-upgrade/

then you could stop the dependecies flowing to the top (the link is for dotnet core, but if the project format is the newer one from above, then the suggestion is still valid):

The way to change the default behavior is to add

<PrivateAssets>all</PrivateAssets>

for each package/project dependency inclusion.

https://curia.me/net-core-transitive-references-and-how-to-block-them/

this should work also on some Full .Net FW pojects.

Once you managed to stop the flowing of dependencjes you can add to your project your reference to the needed version of your dependency

david-ao
  • 3,000
  • 5
  • 12