首页 > 解决方案 > 强制 nuget 子 nuget 版本

问题描述

是否可以在同一个 netcore 项目中访问相同的 nuget 包但不同版本?

我有一个记录到 elasticsearch 的网络核心 api。它使用包:Serilog.Sinks.Elasticsearch - 6.5.0,它有 Elasticsearch.Net - 6.0.0 作为自己的参考。

一切正常,并且已经这样做了几个月。但是现在,当我为另一个功能手动添加 Elasticsearch.Net - 7.0.0-alpha2 到项目时,Serilog.Sinks.Elasticsearch 的 subnuget 也被升级,这破坏了功能。

不过,基于 Elasticsearch.Net - 7.0.0-alpha2 的新代码运行良好。

有什么方法可以强制使用 Serilog.Sinks.Elasticsearch 的 nuget 引用,使其使用 Elasticsearch.Net - 6.0.0 而我自己的新代码使用 Elasticsearch.Net - 7.0.0-alpha2?

新代码之前的 Nugets:

在此处输入图像描述

带有新代码的 Nugets:

在此处输入图像描述

标签: c#.net-corenuget

解决方案


大多数情况下没有,但有一点是。这取决于 :)

构建系统(NuGet、.NET SDK、msbuild)在一个目录中创建包含所有 dll 的构建输出。如果您需要elasticsearch.dll来自两个不同版本的包,这将如何工作?显然你不能有两个文件只有一个名称,因此至少需要重命名一个文件,但是当 CLR 需要加载时elasticsearch.dll,它怎么知道它有不同的名称,它又怎么知道新名字是?

因此,使用构建系统中的内置功能是不可能的。

但是,.NET Framework 确实支持加载不同版本的 dll,您只需要复制文件并告诉它不同版本的位置即可。使用 app.config 文件中的codebase元素,您可以告诉它 dll 在哪里。您可以在%userprofile%\AppData\Local\Microsoft\VisualStudio\{your vs version folder}\devenv.exe.config. 该文件的绝大多数内容是绑定重定向和 codeBase 元素。您将需要更高级的构建脚本,这些脚本只是运行dotnet publish才能将所有 dll 放在所需的位置。它可能会阻止您从 VS 启动调试会话,但您始终可以将 VS 作为调试器附加到正在运行的进程,因此仍然可以调试,只是更难。

这可能只是 .NET Framework。如果它在 .NET Core 上不起作用,您可以查看AssemblyLoadContext,但除了仅使用默认上下文的实现之外,我从未见过完整的示例,no-op但我认为这可能会阻止同时加载多个版本.

在 .NET Framework 上的同一进程中加载​​程序集的多个版本的另一个示例是使用应用程序域。但这绝对只是 .NET Framework,以防您需要支持 .NET Core 或未来的 One.NET (.NET 5)。AssemblyLoadContext是 .NET Core 中最接近应用程序域的东西,但不是一回事。

据我所知,Mono 不支持同时加载程序集的多个版本,但我的猜测是,一旦 .NET 5 发布,这将改变。但这是一个缺乏任何证据或内部知识的猜测。


推荐阅读