为什么我会陷入 DotNet 依赖地狱,我该怎么做才能摆脱困境?

Why am I in DotNet dependency hell and what can I do to get out?

我有一个带有 MVC 和 WebAPI 的 DotNet 4.6.1 应用程序。 MVC 端有 GlobalConfiguration.Configuration 并且 WebAPI 依赖于 Assembly1

显然 System.Web.Http 中的 GlobalConfiguration.Configuration 依赖于 "Newtonsoft.Json, Version=6.0.0.0",而 Assembly1 依赖于 "Newtonsoft.Json",Version=7.0.1.

我准确地放置了这些引文,因为它们是精确的依赖关系: 当我尝试 运行 对我的 WebApi 执行 ping 操作时,我得到:

"Could not load file or assembly 'Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' or one of its dependencies"

我的 web.config 是由 NuGet 添加并由 Microsoft 创建的,所以直到现在我还没有接触过它,它是为我构建的。 web.config 的结构是:

<!--Personal Comment: See how configuration has no namespace-->
<configuration>
    <runtime>
        <!--Personal Comment: See how assemblyBinding DOES have namespace-->
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
            <!--Left out all of the other dependentAssemblies for brevity-->
            <dependentAssembly>
                <!--Personal Comment: Take note the upper/lowercase of attributes-->
                <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral">
                    <bindingRedirect oldVersion="0.0.0.0-7.0.0.0 newVersion="7.0.0.0" />
                </assemblyIdentity>
            </dependentAssembly>
        </assemblyBinding>
    </runtime>
</configuration>

奇怪的是,如果我转到 VSCode 中的 .csproj 并将引用更改为 Include="Newtonsoft.Json" 并删除 Version=7.0.0.0 等...那么什么也得不到固定的。但是,如果我将 Version=7.0.0.0 更改为 Version=6.0.0.0 并将提示路径指向 7.0.1,那么我的解决方案就有效了!

这似乎是一种糟糕的生活方式和编程方式,除非我必须处理它,否则我不喜欢它。根据我在网上阅读的每一篇文章,每一个问题,每一个答案,他们都说 "use bindingRedirect" 并且他们按照我尝试的方式使用它。我的假设是 bindingRedirect 不适用于我的代码,我需要知道为什么,或者我能否以某种方式在我的引用中引用 Newtonsoft.Json 两次并告诉编译器使用 7.0.0.0 代码(如果它不是第三方代码)项目?

如果所有依赖项都使用 NuGet 管理,您可以打开 Manage NuGet Packages for Solution 并将每个项目升级到最新版本的包(在本例中为 NewtonSoft.JSON)。一旦不再引用旧包版本,将被卸载。

我前段时间遇到过类似的问题。试试这个:

  • 删除任何使用它的项目中的 Json 依赖项。
  • 关闭解决方案。
  • 删除SUO文件。它与您的解决方案同名,扩展名为 .SUO。
  • 重新启动解决方案。
  • 清洗溶液。
  • 将所需的 Json 依赖项添加到需要它的项目中。
  • 重建解决方案。
  • 运行验证。

原因是 Visual Studio 出现在 "cache" SUO 文件中的引用。

如果仍然不正常,请将编译器设置为详细并重新生成。它应该告诉您输出中不匹配的确切来源。