声明在一个解决方案中相互依赖的nuget包

时间:2015-01-22 19:44:41

标签: nuget nuget-package nuget-spec

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

我有两个问题:

  1. 是否有可能在保持所有项目在同一解决方案中的同时实现这一目标?如果是这样的话?
  2. 是否建议将所有项目保留在同一解决方案中?对此有什么共同/“最佳实践”方法?

3 个答案:

答案 0 :(得分:7)

我们项目的情况是一样的,我们采取了以下方法:

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

解决方案本身有一个全局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应用程序。由于我们在一组不同的包中提供框架,开发人员可以选择他们实际需要的包,然后只安装那些包。如果开发人员决定稍后添加缺少的功能,他只需安装与已安装版本相同的相关软件包。因此,无需担心兼容性。

答案 1 :(得分:2)

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

最终,仅仅打破你的解决方案更为可取 - 为每个Nuget包创建一个解决方案,并使用Nuget本身提取你的依赖关系。假设您有一个构建/ CI服务器,这应该是相当简单的。只需运行你自己的Nuget repo并在构建时发布构建工件 - 这样你的依赖项目就可以获取你刚刚构建的最新包。您希望确保每次构建过程都刷新Nuget,并且可以使用标准nuget spec命令作为构建后步骤。作为一个很好的奖励,它会强制每个处理代码的人在进行更改时真正考虑依赖关系。

答案 2 :(得分:2)

目前,在VS 2017中,您可以在解决方案中拥有多个库项目,这些项目构建在单独的包中,并且还通过<ProjectReference>相互引用。令人惊讶的是,VS非常聪明,可以在构建解决方案时使用<ProjectReference>并为nuspec中的引用项目生成正确的包<dependencies>。换句话说,您可以方便地在一个解决方案中同时处理许多项目,并将它们全部作为一组包相互发布。