NuGet

成为 NuGet 创建者

Clark Sell

在 11 月,Phil Haack 介绍了 NuGet,新的软件包管理生态系统开发人员 (msdn.microsoft.com/magazine/hh547106)。 NuGet 是 Outercurve 基金会,其目标是为微软成为一流的包管理系统的项目。NET 框架。 项目团队大多是由 Microsoft 开发人员与开发人员社区合作组成。 我们发展生态系统的 NuGet 介绍给。一种方法消耗、 创作和发布包的净开发。

乍看,NuGet 可能会显示为开源社区,只是一种工具,但这只是一个较大的故事。 NuGet 是专门设计不仅帮助分发包内开放源代码社区,为企业提供内部防火墙的包。 这意味着您可以使用 NuGet 从开源社区大,以及您自己的内部服务器的安装和更新包从 Microsoft 和多方面方式。

在本文中,我将探讨一下如何才能成为 NuGet 包的作者。 NuGet 纳入您的开发周期并不复杂,和它将产生大量的价值所在。 一旦当你这样做,您的软件包消费、 创造和分布问题将会成为遥远的记忆褪去。 下个月,我将深入探讨一下如何才能承载您自己的包。

生态系统定义

前开始成为一个包作者的征程,让我们简单回顾一下的更大的生态系统。 NuGet,从这点来看包分发服务器,包括几个基本组成部分,主要是一个叫做 NuGet.exe 的命令行实用工具 (nuget.codeplex.com/releases/view/58939) 和服务器主机的包,如官员­之 NuGet 画廊,nuget.org。 上个月的文章表明,您可以与 NuGet 互动三种方式:使用 NuGet.exe,使用 Visual Studio 中的 NuGet (软件包管理器控制台窗口 (查看 |其他窗口),并使用 NuGet 包资源管理器 (npe.codeplex.com)。 与一个或多个 NuGet 的存储库,这些实用程序进行交互。 在另一方面, nuget.org 是公众席上,您可以使用存储、 主机和发布 NuGet 软件包。 Nuget.org 另一个开放源码项目,称为 NuGetGallery,您可以在其中使用生成的 github.com/nuget/nugetgallery。 我将谈谈如何承载您自己 NuGet 画廊中的下一个问题。

作为一个包的作家,您可以将许多不同的软件包发布到 NuGet 的存储库,以及每个软件包可以有多个版本。 Nuget.org 使客户有机会阅读详细信息包,安装包、 包所有者联系和,什么应该是极少数的情况下,报告滥用行为。

作为包的作者,您可以控制项目如版本号、 依赖项和您的软件包的安装方式。

开始设置

若要发布一个软件包,假定您将使用 nuget.orgas 存储库,您需要注册帐户上 NuGet 画廊。 作者变得非常简单:只是浏览到 NuGet 库科有助于 nuget.org/contribute/index ,选择开始。 然后,点击立即注册登记表格,填写必要的信息来创建一个新帐户。 Nuget.org 将发送一封电子邮件,将 URL 可以确认您的电子邮件地址和帐户。

后确认您的帐户,可以登录到网站上,并获取您的访问键,一个独特的标记,将您标识到 nuget.org 存储库,并使您能够自动执行各种软件包管理任务,例如,将更新推送到您的软件包。

这篇文章中,我将演示 NuGet.exe 命令行界面和 NuGet 包资源管理器。 要注意的一点:一旦您下载的命令行版本,您可能要更新您的系统 path 环境变量,包括它的位置。 这使它易于使用的 NuGet,从任何位置对您的系统。

包的解剖

如在文章的最后,NuGet 包是打开包装公约 (OPC) 容器文件。 nupkg 文件扩展名。 包的格式严重依赖公约,在名为 nuspec 的文件的根的清单文件。 示例目录结构最初可能像下面这样:

Root Folder
|   package.manifest
+---lib
+---content
+---tools

正如您所看到的根本有三个文件夹:

  • lib 包含所有被引用的程序集
  • 内容包含文件和目录复制到您的目标项目的根目录
  • 工具是软件包的一个可能在安装您或每次在 Visual Studio 中加载目标项目上运行的自定义 Windows PowerShell 脚本的地方

其中,lib 文件夹是最复杂的。 它包含子文件夹对应于框架的依赖关系,如下所示:

Root
| package.manifest
\---lib
    | MyFirstAssembly.dll
    \---net11
        | MySecondAssembly.dll
    \---net20
         | MySecondAssembly.dll
           \---sl
        | MySecondAssembly.dll
    \---netmf
         | MySecondAssembly.dll
+---content
+---tools

如果您的程序集的所有版本中正常工作。NET 框架 (罕见的确 !),您需要将其包含仅在您的 lib 文件夹的根与 MyFirstAssembly.dll 一样。

鉴于如何难得的这种情形是,NuGet 团队强烈不利于实践。 它是更好地使您的程序集依赖于一个特定的架构版本。 为此,请添加一个文件夹,该框架版本和在该文件夹中包含正确的程序集的版本。 正如您看到的示例文件夹中,MySecondAssembly.dll 具有不同的版本。NET 框架 1.1,2.0,Silverlight 的。网 MicroFramework。 这可以确保 NuGet 安装正确的目标框架的包裹。

当您的客户安装您的软件包时,NuGet 将安装该项目的目标框架基于正确的程序集。 在前面的示例,假设您的客户正在尝试将您的软件包安装到目标版本 4 的一个项目。NET 框架。 因为它不被列为一个框架示例 lib 文件夹中,NuGet 将采取的最接近的框架版本可用,并使用之。 在此示例中,将程序集 net20 文件夹中找到并使用这些。

克隆目标项目的根文件夹中的内容的文件夹。 在该文件夹中找到的任何东西将被复制到目标项目是。 例如,如果您希望将某些图像复制到目标计算机的首先文件夹,您需要在 /content/images 文件夹中包含这些图像。

工具文件夹中包含任何 Windows PowerShell 脚本 NuGet 将调用在软件包安装期间或打开该项目时,或,由客户以后使用时。 一旦将文件夹复制到目标项目,它将添加到 '$ env: 在 Visual Studio 的软件包管理器控制台 Path (路径) 环境变量。

NuGet 已内置工具来自动填充您的软件包的 — — 文件节点。 文件节点是一个方法显式列出要复制到您的包结构时创建的文件。 nupkg 文件。 这可帮助自动化整体包装过程。 该文件元素是简单,src、 目标和排除属性定义的。 您可能已经猜,src 定义的文件,您想要复制 ; 目标定义您希望它将复制到 ; 的目标 和排除定义您不想复制:

<files>
  <file src="bin\Debug\*.dll" target="lib" />
  <file src="bin\Debug\*.pdb" target="lib" />
  <file src="tools\**\*.*" exclude="*.log" />
</files>

如果您有另一个进程,以创建您的软件包,则可以忽略在文件节点。 nuspec 文件。

。 nuspec 文件

Nuspec 文件是您的软件包清单。 它是一个简单的 XML 文件定义您的整体包,包括名称、 版本号、 包引用之类等等。 若要创建您新的清单,NuGet.exe 具有称为规范,您可以使用为起点的命令:

> NuGet.exe spec

Spec 命令创建一个新的文件称为包。 nuspec,一个有效的文件包含示例数据。 图 1 显示创建规范的示例文件。

图 1 示例。 nuspec 文件

<?xml version="1.0"?>
  <package >
    <metadata>
      <id>Package</id>
      <version>1.0</version>
      <authors>csell5</authors>
      <owners>csell5</owners>
      <licenseUrl>http://LICENSE_URL_HERE_OR_DELETE_THIS_LINE</licenseUrl>
      <projectUrl>http://PROJECT_URL_HERE_OR_DELETE_THIS_LINE</projectUrl>
      <iconUrl>http://ICON_URL_HERE_OR_DELETE_THIS_LINE</iconUrl>
      <requireLicenseAcceptance>false</requireLicenseAcceptance>
      <description>Package description</description>
      <copyright>Copyright 2011</copyright>
      <tags>Tag1 Tag2</tags>
      <dependencies>
        <dependency id="SampleDependency" version="1.0" />
      </dependencies>
    </metadata>
  </package>

创建此文件之后,您可以替换示例值。 为最大值的只有你这一次,虽然一些会更经常发生变化。 例如,您的软件包的 id 不应该更改后发布,但版本号会改变每个发行版。

您还可以针对 Visual Studio 项目文件 (例如,.csproj 或.vbproj) 运行 nuget.exe 规范。 在这种情况下,默认值已填充了基于项目文件中的元数据。 这里是一些简单的元素。 nuspec 文件:

  • id 为包的的唯一标识符
  • 包的标题人性化标题
  • 描述长包的说明
  • 摘要的包的简短说明
  • licenseURl 许可的链接
  • 版权版权所有软件包的详细信息

目前有 28 个不同的顶级元素。 虽然。 nuspec 文件是不言自明的您可以查找所有的详情,请致电 bit.ly/lgQ4J4。 现在让我们来看看几个较复杂。 nuspec 元素。

依赖项和引用

我们都知道管理依赖性可能很困难,,依赖关系链变得漫长和混合时,尤其是。 让我们说你已经建立 PackageA。 您的软件包碰巧使用 PackageB,也可以在 NuGet 中找到。 而不是包括在您的包裹内的 PackageB,您只需创建它的"依赖项"。 当一个人开始安装软件包时,NuGet 首先检查您的 nuspec 文件的依赖项。 然后看看每个软件包依赖关系,并等检查及其依赖项,直到它建立图的每个包裹,它需要下载,以满足所有依赖项。 然后下载整个图表的软件包,并安装它们。 这一功能的 NuGet 大大简化了创建程序包和安装。

让我们看看一些软件包依赖关系定义的依赖项节点中所示:

<package>
<metadata>
<dependencies>
<dependency id="SampleDependency" version="1.0" />
  <dependency id="AnotherSampleDependency" version="[1.2,2.5)" />
</dependencies>
</metadata>
</package>

您可以列出你所需要的多依赖项。 在每个案例中,id 属性指示的包,有一个依赖项和该版本属性表示您需要的版本范围。 此处的示例显示一个依赖项 SampleDependency 项目等于版本 1.0 或更高。

NuGet 版本范围说明,可以设置特定的版本,您允许范围的能力。 这看起来像版本 ="[1.2, 2.5)",在方括号定义包含括号定义排除。 本示例指示允许任何包等于或大于 1.2 和小于 2.5。 NuGet 将在该范围找到的最新版本。 有关版本范围说明的详细信息,请访问 bit.ly/qVXWxs

在某些情况下,您的软件包安装的人可能需要针对类型中进行编程。NET 框架程序集。 若要添加适当的参照,添加到 frameworkAssemblies 节点。 nuspec 文件,详细描述程序集所需的框架,列表如下所示:

<package>
  <metadata>
    <frameworkAssemblies>
      <frameworkAssembly assemblyName="System.Something" targetFramework="net40" />
      <frameworkAssembly assemblyName="System.SomethingElse" />
    </frameworkAssemblies>
  </metadata>
</package>

变换

许多项目需要不只是正常工作的程序集引用。 他们可能需要的.config 文件更改,或甚至一些源代码修改 — — NuGet 本机支持这两种情况。 我将重点在这里.config 文件转换。 有关转换的详细信息,请参阅 bit.ly/jqzry2

在您的 NuGet 软件包的安装时,NuGet 将运行添加您新的.config 值转换。 要实现这一点,您需要将一个转换文件添加到您的软件包的内容文件夹。 这是有效的 XML 文件扩展名为"转型,"其文件名匹配的文件,您要应用的变换。 例如,应用到 web.config 文件的转换,您将包括一个名为 web.config.transformation 的文件。

您的转换文件应包括仅在您想要添加到目标文件中的配置文件的节。 假设您要将一个新的模块添加到您的客户的 system.webServer 节。 只添加整个该条转换文件,像这样:

<configuration>
  <system.webServer>
    <modules>
      <add name="NewModule" type="My.NewModule" />
    </modules>
  <system.webServer>
</configuration>

NuGet 不会取代现有的部分,您添加,但不是将它们合并起来的部分。 所以如果你的目标已模块中的一段自己列出的模块,正在安装后合并这两个文件的结果将会看起来像这样:

<configuration>
  <system.webServer>
    <modules>
      <add name="ExistingModule" type="Their.ExistingModule" />
      <add name="NewModule" type="My.NewModule" />
    </modules>
  <system.webServer>
</configuration>

正如您所看到的您的模块将被添加到现有的模块堆栈的结束。 如果用户想要删除您的软件包中,将删除所做的更改 (假定您不进行任何更改,该等条文),其余部分放在第一位。

版本控制

版本控制是什么我们建设的核心。 NuGet 包版本是指包和不一定 (虽然它习惯保持这些同步) 内所载的程序集。 您定义包中的版本号。 nuspec 文件,使用的 N.N.N.N,格式如下所示。

<package>
  <metadata>
    <version>1.2.3.4</version>
  </metadata>
</package>

有几个属性中的。 nuspec 文件,您可以在其中使用的替换符号,而不是只是静态的字符串。 版本元素是其中之一。 这样的定义如 1.2.3.4 静态字符串,而不是您可以插入一个令牌,[版本$ $],稍后将替换为 NuGet.exe。 目前该令牌,该程序集的 AssemblyVersionAttribute 中指定的版本将进行。 nuspec 文件:

<package>
  <metadata>
    <version>$version$</version>
  </metadata>
</package>

如果你想保持的软件包和版本虽然有很多理由,为什么你不可能会选择这样做同步,,这是很好的选择。

包装包

如前所述,NuGet 包是用 OPC 文件。 nupkg 文件扩展名。 从命令行创建包您只调用 NuGet.exe 与包命令,通过它你。 nuspec 文件:

> NuGet.exe Pack YourPackage.
nuspec

作为与规范,您可以运行包以及您的项目文件。 NuGet 将生成完整的 NuGet 包 (。 nupkg 文件) 纯粹基于发现.csproj 或.vbproj 文件中的元数据。 如果您已经创建。 nuspec 文件,包会用的。 nuspec 文件:

> NuGet.exe pack [path]\MyProject.csproj

您刚才创建您的第一个 NuGet 软件包,恭喜你 !

符号支持

Visual Studio 拥有强大的功能,允许开发人员单步执行源代码上的需求。 NuGet 支持这给包作者创建和发布符号包的能力。 要创建符号的包,请使用 –symbols 选项,使用包时:

> NuGet.exe pack MyProject.
nuspec -symbols
> NuGet.exe pack MyProject.csproj –symbols

包将生成两个。 nupkg 软件包,MyProject。 nupkg 和 MyProject.Symbols。 nupkg。 .Symbols。 nupkg 以后可以推送到 SymbolSource.org,使用 NuGet.exe 命令的推动。 有关使用 NuGet 创建符号包的详细信息,请参阅 bit.ly/jqzry2

发布到 NuGet.org

您创建的软件包,它现在是时候把它推。 推为您的软件包发布到服务器的 NuGet 命令,它用于像最现代的源代码管理系统。 不像以前提到过的命令,推动采用的参数的数目:

> NuGet.exe push <package path> [API key] [options]
  • 包路径的路径,您的软件包
    C:\MyPackge\MyPackage.1.0 示例。 nupkg
  • API 关键你独特的访问令牌
    示例: ABFC2E12-40B3-41A1-A7CC-8FC9AB3A71E0
    可以使用 NuGet.exe setApiKey 命令来设置可选,
  • -源 (src) 服务器软件包的去向。
    示例:-源 http://packages。 nuget.org/v1/
    可选的除非你推到其他的地方
  • -CreateOnly (co) 将包推送到库,但不发布
    可选,默认为 false

下面的示例命令将推送到 NuGet 的 MyPackage 软件包:

> NuGet.exe push MyPackage.1.0.
nupkg ABFC2E12-40B3-41A1-A7CC-8FC9AB3A71E0

您也可以使用 NuGet 包资源管理器中,如图所示,在图 2

Publishing with the NuGet Package Explorer
图 2 使用 NuGet 包浏览器的发布

如果生成了一个符号的包,NuGet 会自动找到它,并把它推到资料库、 nuget.org 和 symbolsource.org。 如果目标机器设置为使用 symbolsource.org 作为符号源,开发人员现在可以步入您包的源文件在 Visual Studio 中的需求。

您正在发布 ! 如果这是您的包裹的第二个版本,该版本将成为默认版本。 解释在上个月的文章中,当有人搜索包更新,您的软件包现在将与更新一并列出。

接近尾声了

可能是您的开发团队拥有一些种构建和部署过程的地方。 如果你像我一样,你现在开始思考如何融入这一进程的 NuGet。 显然您可以包装所有的命令,我在这里为您生成过程,但如果您已经在使用团队基础服务器 (TFS),有一个更容易的方法。

TFS NuGetter (nugetter.codeplex.com) 是一个开放源码项目延伸到 TFS 2010 年的生成过程中可自定义和可重复的方式,其核心 NuGet 执行所有必要的版本控制、 打包和部署功能。 您的软件包的目标,而不管的 TFS NuGetter 将节省你大量的时间。

NuGet 并不是一个新的概念,对本港的工业,但为。网络开发者它好似乎奠基。 NuGet 提供了急需的软件包管理工具,有用,每个人都从车库开发大型企业。 它为您提供不仅发布您的包裹的地方,而且客户发现你工作的地方。 将您的包裹发布到 NuGet,找到 !

您可以找到所有的链接,在这篇文章,并在更多使用 on.csell.net/BeANuGetAuthor

Clark Sell 担任高级 Web 福音的 Microsoft 以外的芝加哥。在他的博客 csell.net,在播客 DeveloperSmackdown.com ,可以发现在 Twitter 上 twitter.com/csell5

多亏了以下技术专家,检讨这篇文章: David EbboPhil HaackMark NicholsBrandon Satrom