C# NuGet依赖策略

C# NuGet依赖策略,c#,nuget,nuget-package,nuspec,C#,Nuget,Nuget Package,Nuspec,我正在将我的许多应用程序模型和接口拆分为自己的nuGet包 问题是:在创建有关依赖项定义的nuGet包时,是否有任何良好的实践推荐策略 有时包a依赖于包B。如果我没有在我的包a的nuspec上声明特定的包B版本,那么当我稍后在任何解决方案中导入包anuGet包时,它可能会在运行时失败,因为子依赖项不可用 有时依赖关系树甚至更深。但如果我显式地将依赖项添加到每个nuspec文件中,那么以后可能会发现版本冲突 问题是:如果一切都在我的控制之下,建议采取什么策略来处理这些事情?我是否应该仅在依赖关系对

我正在将我的许多应用程序模型和接口拆分为自己的nuGet包

问题是:在创建有关依赖项定义的nuGet包时,是否有任何良好的实践推荐策略

有时
包a
依赖于
包B
。如果我没有在我的
包a
的nuspec上声明特定的
包B
版本,那么当我稍后在任何解决方案中导入
包a
nuGet包时,它可能会在运行时失败,因为子依赖项不可用

有时依赖关系树甚至更深。但如果我显式地将依赖项添加到每个nuspec文件中,那么以后可能会发现版本冲突

问题是:如果一切都在我的控制之下,建议采取什么策略来处理这些事情?我是否应该仅在依赖关系对于项目来说“不明显”时指定依赖关系(例如:项目在运行时导入nuGet包装器时需要的第三方库,但不直接使用)?我是否应该一直这样做,然后以不同的方式处理版本冲突?任何关于这方面的好的信息来源都会非常感激,因为我发现了几个例子,但不是某种做事方式的建议

附件: 我创建nuGet包的方法是包含一个我手动编辑的nuspec文件。例如,如果我有以下解决方案结构:

ToolBelt.CityContracts.sln
-ToolBelt.CityContracts.NuGet
--ToolBelt.CityContracts.NuGet.nuspec
-ToolBelt.CityContractsOne
-ToolBelt.CityContractsTwo
ToolBelt.CityContractsOne
ToolBelt.CityContractsTwo
中,我有我的c源文件。从
ToolBelt.CityContracts.NuGet
project中,我添加了对
ToolBelt.CityContractsOne
ToolBelt.CityContractsTwo的引用,以确保nuspec“知道”源文件的位置

然后nuspec看起来像这样:


工具带。城市合同
1.0.0
伊比利奥德夫
假的
共享合同
在这里之前,一切都很标准

然后,我使用nuget命令工具在名为
nupkgs
的文件夹中使用以下命令生成nuget包:

nuget pack ToolBelt.CityContracts.NuGet.nuspec -Version $VERSION -OutputDirectory nupkgs -Prop Configuration=Release -NoDefaultExcludes -Verbosity detailed
更新1: 目前我的策略如下

  • 如果
    包A
    在其公共API中公开属于
    包B
    的类/接口,则
    包A
    不会在其nuspec中向
    包B
    添加依赖项。因此,添加
    包A
    的项目也必须明确添加
    包B
  • 如果
    包A
    未在其公共API中公开属于
    包B
    的类/接口,但在内部使用它们,则
    包A
    必须在其nuspec中向
    包B
    添加依赖项,这样,添加
    包A
    的项目也将自动安装
    包B
    ,避免运行时异常风险
  • 其思想是:如果代码编译,它应该在没有运行时异常的情况下运行,因为不存在依赖关系


    这对我来说是有意义的,但我找不到任何可靠的来源来证实这是一条可行的道路。

    因为您的目标是netstandard2.0,创建包的一个更简单的方法是使用,而不是自己创建nuspec并使用
    nuget pack
    dotnetpack
    msbuild/t:pack
    将从csproj中提取元数据,并自动将任何PackageReference作为依赖项添加到包中。如果您不希望包的用户获得构建时依赖项,那么可以使用

    最好的做法是将所有运行时依赖项作为依赖项添加到包中,这样只引用包的任何人的程序都不会因为缺少DLL而在运行时崩溃。当不同的软件包请求不同的版本时,NuGet restore会自动处理依赖项版本的选择,因此您通常不应该花太多时间担心这一点,尽管坚持语义版本控制会有所帮助


    另一方面,我个人的观点是,包裹越少越好。接口的实现可能位于与接口定义不同的程序集/包中,这有绝对重要的原因。但是,除非您有充分的理由证明它是正确的,否则我建议将接口和实现保持在同一个程序集/包中。我过去工作过的一个代码库在多个存储库的多个包中包含代码,因为团队认为一些通用代码可能对其他项目有用。但是bug修复意味着您必须创建依赖项的新版本,然后更新已部署应用程序中的引用,并且调试依赖项很困难。当我们不得不处理依赖项包时,这大大降低了开发速度,最终没有其他人使用它,因此拆分它确实没有任何好处。

    关于
    dotnet-pack
    的有趣之处,但是使用多个包的解决方案会怎么样?我可以看出,您只能将一个项目传递给
    dotnet包
    。如果您要打包另一个独立项目,该怎么办?如果您有sln文件,它将尝试打包解决方案中的每个项目。您有MSBuild属性来防止打包(从内存IsPackable),因此如果确实不希望打包某些项目,可以避免打包它们。或者,还有一个MSBuild属性GeneratePackageOnBuild,以便在生成时自动创建nupkg。不需要单独运行pack。我在这里阅读了
    dotnetpack
    文档,似乎唯一允许的参数是要打包的项目。没有指定解决方案的选项。您是否有使用
    dotnet pack
    打包多项目解决方案并自定义nuGet Id的示例/链接?(我是通过定义nuspec mys来做到这一点的