同一解决方案中两个不同项目的相同 Nuget 包

Same Nuget package on two different projects in same solution

我在同一个解决方案中有两个 API 项目(一个是我的,另一个我需要参考并且不应该更改)。这两个 API 项目都添加了对 NinjectNinject.Web.Common 包的引用。以下是软件包的设置方式:

Ninject.Web.Common 在网络中 Api A - \packages\Ninject.Web.Common.3.3.2\lib\net45\Ninject.Web.Common.dll
Ninject.Web.Common 网络 Api B - \packages\Ninject.Web.Common.3.2.3.0\lib\net45-full

(注意版本不同 3.3.23.2.3

当我尝试运行我的解决方案时发生的事情是

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

在我的 Web Api B 项目上(注意它试图引用我的 Web Api A 项目中的 3.3.2 版本)。

如何使两个项目保持相同并让它们引用各自的 Ninject 版本?

您通常只能解析依赖关系图中给定依赖关系的一个版本(nuget restore 主要用于计算给定依赖关系图中要使用的版本)。

这通常没问题,但您的问题是 OnePerRequestHttpModule 在 Ninject.Web.Common https://www.fuget.org/packages/Ninject.Web.Common/3.3.2/lib/netstandard2.0/diff/3.2.3/ 的 3.2.3 和 3.3.2 版本之间被删除,而 WebApiB 想要使用它。

您的选择是修改 WebApiB 使其不再使用 OnePerRequestHttpModule,或者将 WebApiA 中的 Ninject.Web.Common 版本降级到 3.2.3

我看到您使用的是 4.5 FW 但是:

如果您已经在使用较新的 csproj 格式或者可以升级到它(这只是为了更改 csproj 的格式,项目本身仍将针对它的目标)

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

然后你可以停止依赖流到顶部(link 是针对 dotnet core,但如果项目格式是上面的新格式,那么建议仍然有效):

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/

这也适用于一些完整的 .Net FW 项目。

一旦你设法停止了依赖项的流动,你就可以将你对所需依赖项版本的引用添加到你的项目中

您可以尝试以下方法之一:

  1. 创建 post 将多版本程序集注册到 GAC 的构建步骤。 CLR 将在检查输出文件夹之前查看 GAC。由于两个程序集都安装在 GAC 中,运行时将找到并加载正确的版本。
  2. 使用 gacutil.exe 将两个程序集安装到 GAC。然而,这对于开发环境来说不是很实用,因为必须在每台机器上重复安装。 安装后,将引用的 CopyLocal 属性 设置为 False,因为它们不需要位于输出文件夹中。
  3. 通过 AppDomain.AssemblyResolve 事件执行自定义解析。
  4. 将程序集复制到不同的文件夹并指定codebase element。通过编辑 Web 应用程序配置文件,您可以将应用程序指向适当的 DLL 版本,即使它们不直接位于 bin 文件夹中。
     <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. 使用binding redirects,但我认为这不适合你的情况。
  2. 使用 extern Nuget 别名。

参考:

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