强制nuget子nuget版本

时间:2019-05-21 13:52:03

标签: c# .net-core 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的子代也已升级,从而破坏了功能。

基于Elasticsearch.Net-7.0.0-alpha2的新代码运行正常。

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

新代码之前的小节:

enter image description here

带有新代码的小坚果:

enter image description here

2 个答案:

答案 0 :(得分:1)

大多数情况下不,但是是的。这取决于:)

生成系统(NuGet,.NET SDK,msbuild)使用一个目录中的所有dll创建生成输出。如果您需要两个不同版本的软件包中的elasticsearch.dll,该如何工作?显然,您不能使用同一个名称来命名两个文件,因此至少需要重命名一个文件,但是当CLR需要加载elasticsearch.dll时,它将如何知道它具有不同的名称,以及如何它知道新名字是什么吗?

因此,不可能在构建系统中使用内置功能。<​​/ p>

但是,.NET Framework确实支持加载dll的不同版本,您只需要进行复制文件的工作并告诉它不同版本的位置。使用app.config文件中的codebase element,您可以告诉它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的同一过程中加载程序集的多个版本的另一个示例是使用App Domains。但这绝对只是.NET Framework,以防您需要支持.NET Core或将来的One.NET(.NET 5)。 AssemblyLoadContext是.NET Core中最接近应用程序域的东西,但不是一回事。

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

答案 1 :(得分:0)

您遇到的问题被称为“ Dll Hell”,有很多解决方法,例如:

  • 尝试使用强名称库并将其安装到Global Assembly Cache中
  • 在依赖关系之间应用抽象层
  • 将用途封装在不同的context

也许old post也可以为您提供帮助。