.net core 正确管理解决方案之间的私有nuget包依赖关系

.net core 正确管理解决方案之间的私有nuget包依赖关系,.net-core,nuget,nuget-package,.net Core,Nuget,Nuget Package,我们有两种解决方案 SolutionA是一种内部解决方案,我们在产品中使用可重用代码 为了解决这个问题,它只有两个项目NugetProjectA和NugetProjectB,其中有一个对NugetProjectA的项目引用 SolutionB是一种通过nuget对SolutionA进行包引用的解决方案 麻烦的是: 在NugetProjectA中添加新方法 在使用以前方法的NugetProjectB项目中添加新方法 发布NugetProjectB的新版本 更新SolutionA项目的nuget参考

我们有两种解决方案

SolutionA是一种内部解决方案,我们在产品中使用可重用代码 为了解决这个问题,它只有两个项目NugetProjectA和NugetProjectB,其中有一个对NugetProjectA的项目引用

SolutionB是一种通过nuget对SolutionA进行包引用的解决方案

麻烦的是:

在NugetProjectA中添加新方法 在使用以前方法的NugetProjectB项目中添加新方法 发布NugetProjectB的新版本 更新SolutionA项目的nuget参考资料 在项目中执行NugetProjectB新增的方法 因为我们没有发布NugetProjectA更新版本,所以描述的最后一步将失败

这似乎是一个容易解决的问题。但是想象一下,在SolutionB和SolutionA中有更多的项目


你的问题含糊不清,没有明确的答案。老实说,它很可能是一个多帖子的博客系列,甚至是一本短小的书。我将尝试给出一些一般性的建议,但我不会详细讨论,以免回答太长时间

单一回购与多重回购 就像几年前的微服务热潮一样,你应该先问问自己是否需要它。将所有源代码放在一个存储库和解决方案中可能会让人感觉像是遗留问题,而且在签入一行错误修复时,3分钟构建一个组件似乎比30分钟构建整个系统更好。但是,您在问题中列出的问题是否值得缩短CI构建时间

另一个极端是,谷歌可能以在单个存储库中运行几乎所有内容而闻名,但他们的团队除了管理他们的mono repo和构建系统外什么都不做,因为在单个repo上工作的大量开发人员有不同的问题。这些工程师不负责客户应用程序。如果他们的工作让其他团队更有效率,那么这是值得的

您需要找出最适合您的方案,但鉴于您在问题中描述的问题,可能您的回购/解决方案太多,如果您稍加整合,您的流程可能会更快,错误更少

自动化 下一个最好的方法就是使用好的工程实践。尽可能实现自动化以降低人为错误的风险,包括自动化流程,以验证是否正确遵循手动流程

使用CI或CD管道推送包,这样您就不会忘记推送依赖项,如您的示例中所示。 有一些工具会根据自签入版本控制配置文件以来的提交次数自动从git历史生成版本号。这可以防止您在签入对包的更改时忘记增加包版本。 在推包之前进行测试以确保包工作正常。您可以简单地确保依赖关系的存在,但也可以更进一步,让测试程序运行,使用该包来确保向后兼容性不会被破坏,并且新功能实际上可以按预期工作。在推送包之前运行这些测试,这样如果测试失败,就不会推送坏包。 您可以拥有一个管道,当发布某个包的新版本时,该管道将自动在使用该包的解决方案上创建请求。您甚至可以自动合并它,但您需要确保有真正良好的测试,以避免错误包层叠成一团,特别是如果您在成功的构建上进行自动部署。 要有创意,并考虑其他方法,使流程自动化,使自己和团队的工作更轻松。 但在自动化方面要务实。花一周的时间来自动化那些每月只需要5分钟就可以手动完成的事情是没有意义的。但是,如果手动过程有时出错,需要花费数小时或数天的时间来修复,那么自动化过程就更有价值了

使用现代特征 自从.NET核心发布以来,在过去的2-3年中,.NET生态系统发生了很大的变化。现在,使用MSBuild打包dotnet pack或MSBuild-t:pack创建包比创建.nuspec文件更容易,并确保您做了正确的事情来将项目依赖项打包为nuget依赖项,将所有文件打包到正确的位置,等等。如果您的类库使用SDK样式的项目,则无需额外操作。如果项目是传统项目,则需要对NuGet依赖项使用PackageReference,或在项目文件中将PackageReference指定为MSBuild属性,然后引用NuGet.Build.Tasks.Pack包

应用程序的版本,而不是每个包 与mono-repo与multiple-repo点类似,考虑对applic中的所有包进行版本控制 使用单个版本号进行版本化,而不是单独对每个包进行版本化。是的,这意味着您有时或可能经常发布一个新版本的包,该包对以前的版本没有任何代码更改,但它大大简化了发布过程。结合上一节中的MSBuild打包,您可以在存储库根目录中创建Directory.Build.props文件,并将属性设置为应用程序版本,repo中的所有项目都将具有相同的版本。因此,当您准备发布时,将版本添加到单个文件中,每个项目和每个NuGet包都将具有相同的版本

总结 在理想情况下,每个组件都可以在不同的应用程序中重用,在单独的源代码存储库中,每个包都使用语义版本控制进行单独的版本控制。但在现实世界中,这增加了很多开发时间的复杂性。您的客户可能更乐意更快地获得bug修复和新功能,即使软件包的版本号没有那么有意义。因此,做出数据驱动的决策。如果您经常遇到依赖项版本问题,请减少依赖项,以减少出错的情况


别误会,拥有多个项目、多个解决方案、多个存储库有很多很好的理由。只要确保你这样做的原因是因为这有助于你的团队/公司提高生产力,而不是因为理想主义的原因,因为理想主义的原因会让你慢下来或导致错误。

你的问题是模糊的、开放的,因此没有简单、简洁的答案。老实说,它很可能是一个多帖子的博客系列,甚至是一本短小的书。我将尝试给出一些一般性的建议,但我不会详细讨论,以免回答太长时间

单一回购与多重回购 就像几年前的微服务热潮一样,你应该先问问自己是否需要它。将所有源代码放在一个存储库和解决方案中可能会让人感觉像是遗留问题,而且在签入一行错误修复时,3分钟构建一个组件似乎比30分钟构建整个系统更好。但是,您在问题中列出的问题是否值得缩短CI构建时间

另一个极端是,谷歌可能以在单个存储库中运行几乎所有内容而闻名,但他们的团队除了管理他们的mono repo和构建系统外什么都不做,因为在单个repo上工作的大量开发人员有不同的问题。这些工程师不负责客户应用程序。如果他们的工作让其他团队更有效率,那么这是值得的

您需要找出最适合您的方案,但鉴于您在问题中描述的问题,可能您的回购/解决方案太多,如果您稍加整合,您的流程可能会更快,错误更少

自动化 下一个最好的方法就是使用好的工程实践。尽可能实现自动化以降低人为错误的风险,包括自动化流程,以验证是否正确遵循手动流程

使用CI或CD管道推送包,这样您就不会忘记推送依赖项,如您的示例中所示。 有一些工具会根据自签入版本控制配置文件以来的提交次数自动从git历史生成版本号。这可以防止您在签入对包的更改时忘记增加包版本。 在推包之前进行测试以确保包工作正常。您可以简单地确保依赖关系的存在,但也可以更进一步,让测试程序运行,使用该包来确保向后兼容性不会被破坏,并且新功能实际上可以按预期工作。在推送包之前运行这些测试,这样如果测试失败,就不会推送坏包。 您可以拥有一个管道,当发布某个包的新版本时,该管道将自动在使用该包的解决方案上创建请求。您甚至可以自动合并它,但您需要确保有真正良好的测试,以避免错误包层叠成一团,特别是如果您在成功的构建上进行自动部署。 要有创意,并考虑其他方法,使流程自动化,使自己和团队的工作更轻松。 但在自动化方面要务实。花一周的时间来自动化那些每月只需要5分钟就可以手动完成的事情是没有意义的。但是,如果手动过程有时出错,需要花费数小时或数天的时间来修复,那么自动化过程就更有价值了

使用现代特征 自从.NET核心发布以来,在过去的2-3年中,.NET生态系统发生了很大的变化。现在,使用MSBuild打包dotnet pack或MSBuild-t:pack比创建.nuspec文件并确保 您做了正确的事情,将项目依赖项打包为nuget依赖项,将所有文件放在正确的位置,等等。如果您的类库使用SDK样式的项目,那么就没有什么额外的事情要做了。如果项目是传统项目,则需要对NuGet依赖项使用PackageReference,或在项目文件中将PackageReference指定为MSBuild属性,然后引用NuGet.Build.Tasks.Pack包

应用程序的版本,而不是每个包 与mono-repo和multiple-repo点类似,考虑使用单个版本号对应用程序中的所有包进行版本控制,而不是单独对每个包进行版本控制。是的,这意味着您有时或可能经常发布一个新版本的包,该包对以前的版本没有任何代码更改,但它大大简化了发布过程。结合上一节中的MSBuild打包,您可以在存储库根目录中创建Directory.Build.props文件,并将属性设置为应用程序版本,repo中的所有项目都将具有相同的版本。因此,当您准备发布时,将版本添加到单个文件中,每个项目和每个NuGet包都将具有相同的版本

总结 在理想情况下,每个组件都可以在不同的应用程序中重用,在单独的源代码存储库中,每个包都使用语义版本控制进行单独的版本控制。但在现实世界中,这增加了很多开发时间的复杂性。您的客户可能更乐意更快地获得bug修复和新功能,即使软件包的版本号没有那么有意义。因此,做出数据驱动的决策。如果您经常遇到依赖项版本问题,请减少依赖项,以减少出错的情况


别误会,拥有多个项目、多个解决方案、多个存储库有很多很好的理由。只需确保您这样做的原因是因为它有助于您的团队/公司提高生产效率,而不是因为理想主义的原因,这些原因会减慢您的速度或导致错误。

为什么不在对NuGetProjectA进行更改后发布它,特别是在修改NuGetProjectB以依赖这些更改并发布NuGetProjectB之后?发布那个软件包不会解决你的问题吗?是的,我们现在就是这么做的。但是,正如我所说,这是真实场景的简化全景。假设SolutionA有14个项目和许多依赖项,为什么不在对其进行更改后发布NuGetProjectA,特别是在修改NuGetProjectB以依赖这些更改并发布NuGetProjectB之后?发布那个软件包不会解决你的问题吗?是的,我们现在就是这么做的。但是,正如我所说,这是真实场景的简化全景。想象一下SolutionA有14个项目和许多依赖项。