C# 在运行时下载最新的NuGet

C# 在运行时下载最新的NuGet,c#,.net-core,dependencies,nuget,runtime,C#,.net Core,Dependencies,Nuget,Runtime,在运行期间,我想使用.NETCore从NuGet库下载最新的DLL,并将其加载到容器中 我正在看一个场景,当一组依赖项被更改,新的包版本被发布到nuget.org,之后我将不得不下载最新的包并运行一些测试。每次应用程序都会验证它是否有最新的软件包版本,如果需要,下载并动态加载新的程序集,而应用程序不会停止。我首先要说,这听起来不是一个好主意。你没有解释你为什么要这样做,所以我们没有办法建议更好的方法。如果是您不希望停机的web应用程序,更好的方法可能是使用负载平衡器,当您发布新版本的web应用程

在运行期间,我想使用.NETCore从NuGet库下载最新的DLL,并将其加载到容器中


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

我首先要说,这听起来不是一个好主意。你没有解释你为什么要这样做,所以我们没有办法建议更好的方法。如果是您不希望停机的web应用程序,更好的方法可能是使用负载平衡器,当您发布新版本的web应用程序时,配置负载平衡器将所有新请求发送到新的contains/版本,同时旧版本上的现有连接将耗尽

如果你的应用程序是一个队列侦听器,你根本不需要热加载。只要有一个应用程序,它可以在源代码上创建一个pull请求,以便在nuget软件包版本号可用时更新这些版本号,让CI自动生成更改,如果测试通过,您可以自动批准/合并PR,那么您的CD可以自动部署和停用以前的版本。这比自动加载新版本的风险要小,因为新版本有漏洞或二进制不兼容的风险,现在你的应用程序将崩溃

无论如何,如果您确实有充分的理由热重新加载程序集,那么您需要在.NETCore上使用。然而,这是一个如此罕见的情况下需要这个,我找不到任何现实的例子如何使用它。我看到的所有“示例”都使用
AssemblyLoadContext.Default
,我假设它等同于使用单个上下文,因此不允许加载同一程序集的不同版本。所以,如果你想沿着这条路走下去,你可能必须自己去想办法。大量的尝试和错误,调试和可能阅读coreclr源代码。正如您的问题的一些评论者所提到的,您还需要处理这样一种情况,即程序集是根据依赖项的一个版本编译的,但是您现在要加载另一个版本。在.NET Framework中,is使用称为程序集绑定重定向的东西。大多数人使用app.config或web.config文件的方式是这样的,但这对您不起作用,因为它会在运行时更改。我确信有一个API可以通过编程来处理它,您还需要弄清楚这一点。我不确定与.NET Framework相比,.NET Core中的绑定重定向是否有什么不同,所以这是另一件你需要弄清楚的事情,但我相信谷歌上的一些好搜索会给你一个答案

一旦程序集热重新加载开始工作,您可以读取并实现自己的客户端,也可以使用。但是NuGet客户端团队的主要关注点是工具(Visual Studio集成、dotnet cli、NuGet.exe),它们只是为了方便而发布软件包(另外还可以与dotnet cli和mono共享库),因此没有关于使用SDK的文档。还要注意的是,尽管NuGet客户端团队试图不破坏二进制API包,但在需要为工具实现功能和bug修复时,这是次要的问题。NuGet client SDK跟踪Visual Studio版本号,它不使用语义版本控制,因此当您尝试更新到较新的NuGet client软件包时,您可能会发现您需要更改代码,否则您可能无法预料。这是非常罕见的,但我通常推荐“端口和适配器”模式,这是一个非常好的例子,说明它何时特别有用。至少在NuGet客户端软件包中,有一些人的博客帖子,他们发现了这一点,并分享了他们是如何做任何他们需要的事情的。否则,由于NuGet本身是开源的,您可以查看NuGet的代码,了解它如何在内部使用这些包,并以此作为指导,帮助您了解您想要做什么。如果沿着这条路走下去,您将需要执行nuget工具的大部分功能:

  • 查询NuGet提要以查找包的可用版本,然后选择要使用的版本并检查该版本是否已下载
  • 下载并解压缩包
  • 资产选择。特别是当一个包有多个TFM库时,您需要根据项目的TFM知道要使用哪个库
  • 此阶段的NuGet客户端要么编写.NET SDK使用的
    project.assets.json
    文件,要么编辑packages.config和csproj文件,具体取决于项目是使用
    packagesreference
    还是
    packages.config
    。在您的案例中,这是与部件热重新加载集成的地方
  • 请注意,在一般情况下,上面的过程,或者取决于单个步骤的实现方式,可能是递归的,因为包可能具有依赖性。因此,也需要检索依赖项,但包可能具有不同的依赖项,具体取决于选择了哪个TFM,因此您需要弄清楚是要下载所有依赖项,甚至是在资产选择后永远不会使用的依赖项,还是要先进行资产选择以最小化下载的包。另外,当多个包依赖于单个包的不同版本时,您需要决定要使用哪个版本的包

    所以,这是您需要实现的高级算法。正如我所提到的,其中大多数都没有API文档,其中没有关于如何实现它的示例,并且很少有示例(如果有的话)出现在internet上。就像我在第一段写的,我认为这不是一个好主意。自动化CI/CD管道可能更容易,而且