在运行期间下载最新的NuGet

问题描述 投票:-4回答:1

在运行时,我想使用.NET Core从NuGet库下载最新的DLL并将其加载到容器中。

我正在看一个场景,当一组依赖项被更改并且新的软件包版本发布到nuget.org之后,我将不得不下载最新的软件包并运行一些测试。每次应用程序将验证它是否具有最新的软件包版本,并在必要时下载并动态加载新的软件包而不停止应用程序。

c# .net-core dependencies nuget runtime
1个回答
0
投票

我会开始说这听起来不是一个好主意。你没有解释你为什么要这样做的场景,所以我们没有办法建议更好的方法。如果它是一个您不希望停机的Web应用程序,更好的方法可能是拥有负载均衡器,当您发布新版本的Web应用程序时,配置负载均衡器以将所有新请求发送到new包含/ version而旧版本上的现有连接耗尽。

如果您的应用是队列侦听器,则根本不需要热插拔。只需要一个应用程序,在源代码上创建一个拉取请求,以便在可用时更新nuget包版本号,让CI自动构建更改,如果测试通过,您可以自动批准/合并PR,那么您的CD可以自动部署并停用以前的版本。这比自动加载新版本风险小,因为您冒着新版本存在错误或不兼容二进制文件的风险,现在您的应用程序将崩溃。

无论如何,如果你确实有充分的理由热重新加载程序集,在.NET Core上你需要使用AssemblyLoadContext。然而,这是一个非常不寻常的情况需要这个,我找不到任何关于如何使用它的现实例子。我见过的所有“例子”都使用AssemblyLoadContext.Default,我认为它与使用单个上下文无关,因此不会让你加载同一个程序集的不同版本。所以,如果你想走这条路,你可能不得不自己解决这个问题。大量的试验和错误,调试和可能读取coreclr源代码。正如您提到的一些评论者提到的那样,您还需要处理一个程序集是针对一个依赖项版本编译的情况,但您现在要加载一个不同的版本。在.NET Framework中使用称为程序集绑定重定向的东西。大多数人使用它的方式是使用app.config或web.config文件,但这对你不起作用,因为它会在运行时更改。我确信有一个API以编程方式处理它,你还需要弄清楚。我不确定.NET Core中的绑定重定向与.NET Framework相比是如何/不同的,所以这是你需要弄清楚的另一件事,但我确信谷歌上的一些好搜索会给出你回答这个问题。

一旦你进行装配热重装工作,你可以阅读NuGet server API并实现自己的客户端,或者你可以使用NuGet client SDK。但NuGet客户团队的主要关注点是工具(Visual Studio集成,dotnet cli,nuget.exe),他们只是为了方便而发布包(另外作为一种与dotnet cli和mono共享库的方式),所以没有有关使用SDK的文档。另请注意,虽然NuGet客户端团队尝试不破坏程序包二进制API,但在需要实现工具的功能和错误修复时,这是次要问题。 NuGet客户端SDK跟踪Visual Studio版本号,它不使用语义版本控制,因此当您尝试更新到较新的NuGet客户端软件包时,您可能会发现需要在不希望的情况下更改代码。这是非常罕见的,但我通常推荐“端口和适配器”模式,这是一个很好的例子,它什么时候特别有用。至少在NuGet客户端软件包中,有一些博客帖子来自那些想出来的人,并分享了他们如何做任何他们需要的东西。否则,由于NuGet本身就是开源,你可以查看NuGet的代码,看看它如何在内部使用这些包,并将其用作指南,帮助你弄清楚你想要做什么。如果沿着这条路走下去,你需要完成nuget工具的大部分工作:

  1. 查询NuGet提要以查找可用的软件包版本,然后选择要使用的版本并检查是否已下载该版本。
  2. 下载并解压缩包。
  3. 资产选择。特别是当一个包具有多个TFM的库时,您需要根据项目的TFM知道要使用哪个TFM
  4. 此阶段的NuGet客户端要么编写.NET SDK使用的project.assets.json文件,要么编辑packages.config和csproj文件,具体取决于项目是使用PackageReference还是packages.config。在您的情况下,这是您与程序集热重新加载集成的位置。

请注意,在一般情况下,上面的过程,或者取决于您如何实现它的一个步骤,可能是递归的,因为包可以具有依赖性。因此,还需要检索依赖项,但是根据选择的TFM,包可以具有不同的依赖关系,因此您需要弄清楚是否要下载所有依赖项,甚至是在资产选择后永远不会使用的依赖项,或者您是否希望首先进行资产选择以最小化您下载的软件包。此外,当多个程序包依赖于单个程序包的不同版本时,您需要决定要使用的程序包版本。

所以,这是你需要实现的高级算法。正如我所提到的,大部分内容都没有API文档,其中包含有关如何实现它的示例,并且互联网上存在的示例很少(如果有)。就像我在第一段写的那样,我认为这不是一个好主意。自动化CI / CD管道可能更容易,如果需要,可以自动更改负载均衡器的配置,而不是制作如此复杂的应用程序。有时编排一堆简单的应用程序比制作复杂的应用程序更容易。

© www.soinside.com 2019 - 2024. All rights reserved.