【问题标题】:declaring nuget packages that depend on each other in one solution在一个解决方案中声明相互依赖的 nuget 包
【发布时间】:2015-03-21 18:00:16
【问题描述】:

我们有很多项目的解决方案以及这些项目之间或多或少复杂的依赖关系图。现在,这些项目中的每一个都应该成为自己的 nuget 包,并且 nuget 包的依赖关系图应该反映项目的 on。

我有两个问题:

  1. 是否可以在将所有项目保持在同一个解决方案中的同时实现这一目标?如果有怎么办?
  2. 建议将所有项目保持在同一个解决方案中吗?对此的常见/“最佳实践”方法是什么?

【问题讨论】:

    标签: nuget nuget-package nuget-spec


    【解决方案1】:

    是的,您可以“可能”完成这项工作。我说可能是因为我没有尝试过,但我会用这样的方法来处理它:https://www.nuget.org/packages/CreateNewNuGetPackageFromProjectAfterEachBuild/ 使用手动 nuspec 定义你的引用会起作用。如果你想变得非常花哨,你可以编写一些构建后的 Roslyn 代码来解析你的项目依赖关系并构建 nuget 依赖关系树。也就是说,不要这样做,在一个非平凡的解决方案中,它几乎可以保证很快变得手动和脆弱。

    最终,最好只分解您的解决方案——为每个 Nuget 包创建一个解决方案,并使用 Nuget 本身引入您的依赖项。假设您有一个构建/CI 服务器,这应该是相当简单的。只需运行您自己的 Nuget 存储库并在构建工件时发布它们——这样您的依赖项目将提取您刚刚构建的最新包。您需要确保每次构建过程都会刷新 Nuget,并且可以使用标准的 nuget spec 命令作为构建后步骤。作为一个很好的奖励,它会迫使每个编写代码的人在进行更改时真正考虑依赖关系。

    【讨论】:

      【解决方案2】:

      我们项目中的情况也是一样的,我们采取了如下做法:

      第一步是创建定义包的 nuspec 文件。我们已将所有这些文件放在名为“.nuspec”的文件夹中,该文件夹位于解决方案的根目录中。 nuspec 文件也会添加到名为“.nuspec”的解决方案文件夹中的解决方案中。

      解决方案本身有一个全局 AssemblyInfo 文件,其中包含版本信息以及一些版权信息 - 简而言之,我们项目之间的所有通用信息。然后每个项目都有自己的程序集信息,添加特定于每个项目的信息。

      nuspec 文件不包含版本。相反,我们在那里使用$(version) 作为占位符:

      <?xml version="1.0" encoding="utf-16"?>
      <package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
        <metadata>
          <id>MyCompany.MyProduct.Server.DataAccess</id>
          <version>$(Version)</version>
          <authors>MyCompany</authors>
          <projectUrl>http://example.com/myProduct.html</projectUrl>
          <iconUrl>http://example.com/myProduct.icon.png</iconUrl>
          <requireLicenseAcceptance>false</requireLicenseAcceptance>
          <description>Some description goes here.</description>
          <summary>The summary goes here</summary>
          <copyright>Copyright © MyCompany 2015</copyright>
          <language>en-US</language>
          <dependencies>
            <dependency id="MyCompany.MyProduct.Common" version="$(Version)" />
            <dependency id="MyCompany.MyProduct.Server" version="$(Version)" />
          </dependencies>
        </metadata>
        <files>
          <file src="path\to\MyCompany.MyProduct.Server.DataAccess.dll" target="lib\net45\MyCompany.MyProduct.Server.DataAccess.dll" />
        </files>
      </package>
      

      (当然依赖关系本身可能有依赖关系。例如,服务器组件可能引用日志组件。)

      最初,我们创建了一个控制台应用程序,从全局 AssemblyInfo 文件中读取解决方案的版本,并在创建和发布包之前将其解析为所有 nuspec 文件。

      控制台应用程序运行良好,但在启用持续集成的 TFS 环境中维护有点乏味。所以我们定义了一个自定义的 TFS 构建模板来完成这项工作。现在,为所有项目创建一组 nuget 包,我们需要做的就是触发 TFS 构建。

      这种方法的优点是所有包都具有相同的版本,因此可以很好地协同工作。 这种方式的缺点是所有包的版本都一样,不能独立发布。

      我们之所以选择这种方法,是因为它阻止了我们生产集成不良组件的企业集团。我们的项目提供了一个小型框架,用于开发非常相似的小型 LOB 应用程序。由于我们在一组不同的包中提供框架,因此开发人员可以选择他们实际需要的包,然后只安装这些包。如果开发人员决定稍后添加缺少的功能,他只需安装与已安装的版本相同的相关包。因此无需担心兼容性问题。

      【讨论】:

      • 很好的答案,谢谢。我们确实遇到了您所描述的那种情况,除了到目前为止我们只构建了一个包含所有库的大包。我们现在需要能够独立地引用不同的位,而不需要在不需要它们的地方拉入所有其他杂乱无章的 / web 文件等。这正是您在最后几段中所描述的 - 非常感谢。
      • 我得到'$(Version)' is not a valid version string. 你在哪里定义这个?
      • @Wilbert 请仔细阅读我的回答。我们最初使用一个小型控制台应用程序替换了 $(Version) 占位符。现在我们使用 TFS 构建来实现这个目标。
      【解决方案3】:

      目前,在 VS 2017 中,您可以在一个解决方案中拥有多个库项目,这些库项目内置在单独的包中,并通过 &lt;ProjectReference&gt; 相互引用。令人惊讶的是,VS 足够聪明,可以在构建解决方案时使用 &lt;ProjectReference&gt; 并为 nuspec 中的引用项目生成正确的包 &lt;dependencies&gt;。换句话说,您可以方便地在一个解决方案中同时处理多个项目,并将它们全部发布为一组相互依赖的包。

      【讨论】:

      • 这很好,但它只在使用新的 csproj 格式时有效。
      • 也许你是对的,我已经很久没有使用旧格式了。
      • 嗯,我使用的是 VS2017,但我从 2015 年导入了项目,并从每个项目的命令行中创建了 .nuspec 文件。现在只有两个项目,但是他们创建了两个包,它们之间没有依赖关系。有没有我可以使用的文档,或者你们知道出了什么问题吗?
      • @MichaelBlackburn 我不是在说命令行工具,我说的是使用 VS 构建和生成包(没有显式创建 nuspec 等,而是使用项目设置),它的工作原理与描述的一样。
      • 这正是我所需要的。任何指向记录在哪里的指针?编辑:不适合我:
        - 如果我使用 PackageReference,它将不会使用更新的代码。 - 如果我使用ProjectReference,它会编译,但是nuget中的依赖是错误的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多