.NET的依赖管理——做得对

依赖管理的问题既不是新的也不是原始的,它存在于所有的开发平台中,. net也不例外。
让我们来看看不同的解决方案,看看它们的表现如何。我将在这里列出它们,没有特别的顺序。

在源代码控制中保持依赖关系
这是一个非常流行的解决方案,这是有原因的。好处是显而易见的。以下是其中的一些:

  • 没有设置。您已经有了源代码控制(,我希望你能!)添加bin目录,就可以了。
  • 没有学习曲线。开发人员习惯于使用源代码控制。
  • 共享。整个团队都得到变化以及来自服务器的更新。
  • Enterprisy(以一种好的方式)软件经过验证,备份,DRP完成。

听起来不错,不是吗?那么,它有什么问题呢?只有一件事——源控制系统是用来控制源的。作为这样的他们不是很擅长控制二进制文件。这些都是我们在使用版本控制系统来处理依赖关系时所遇到的缺点:

  • 它不是代理。VCS无法下载所需的依赖项当您需要一个中央存储库时。您需要手动下载并添加到VCS中。历史记录从这里开始-您只是丢失了到原始文件的链接。所以,你努力工作,最重要的是失去了信息;这重复本身对于每个新的依赖项。
  • 版本控制不匹配。源文件如下版本化通过它们的内容。人来说知道如何diff并理解是什么改变了。另一方面,通常是二进制版本化通过他们的名字。从风投点它们是不同的条目,每个条目都没有任何版本历史记录。
  • 一些非常流行的vcs(比如Subversion)不能删除文件。这意味着-一旦文件被添加,它保持永远在存储库中。对于小的源文件来说,这不是什么大问题,但是对于过时的大型二进制文件来说,这就很麻烦了。
  • 源代码控制知道如何搜索源代码。当然,最重要的搜索类型是按内容搜索。搜索二进制文件是不同的:重要的是位置、文件名的结构,如果是存档工件,则是文件的内容存档
  • 权限vcs的方案是量身定制的版本控制来源(!)。例如,没有重写权限。这是因为重写源是我们一直在做的事情diff(在VCS中用于)——它的安全级别与添加一个新的源文件相同。对于二进制文件,情况是非常不同的。虽然添加新的二进制文件是可以的,但不应该重写已发布的二进制文件,应该有一个特殊的许可为它。
  • 分布式vcs本身非常棒,但特别不适合处理大的二进制文件。将远程存储库克隆到把所有文件的历史记录都带来了吗。现在想想那些巨大的二进制……

如你所见,结论很简单——我们可以做得更好。让我们尝试一些专门用于二进制文件的东西。

GAC和WebGAC
全局程序集缓存与VCS是矛盾的为存储二进制文件而定制。它可以理解版本,防止冲突,并且通常可以很好地充当本地依赖项存储。GAC的主要问题是本地化,这意味着每个开发人员都应该从某处获取二进制文件并将其安装在本地GAC中。你看到了那套装置带来的麻烦,不是吗?WebGAC在这里救援。它本质上是WebDAV共享的GAC,允许客户端从服务器获取依赖项,从而简化了操作依赖关系团队管理。我们来算一下利弊。的好处:

  • GAC是一个好的、标准的、经过验证的二进制文件管理解决方案。它很好地处理了版本。
  • WebGAC是团队的中央二进制文件存储库。每个团队成员都与它同步。
  • WebDAV是流行的知名HTTP扩展具有锁定、安全管理等功能。使用Apache WebDAV模块通常很简单。

让我们看看这个解决方案有什么不太管用的:

  • 它不是代理。WebGAC无法下载所需的依赖项当您需要一个中央存储库时。您需要手动下载它,将其添加到WebGAC中,然后才能对团队可用。您不仅必须为所需的每个依赖项的每个版本工作,而且还会丢失指向原始文件的链接。
  • 没有包的概念。GAC含有单dll。一个接一个地安装。想想NUnit的例子。它包含大约12个dll以及各种XML和配置文件。你怎么安装它广汽
  • 安全问题很麻烦。您需要配置Apache Server的安全性,即使这样,它也不够灵活,无法在两者之间做出决定部署人员(可以发布私有依赖的用户)和促进者(可以将依赖从私有存储库移动到公共存储库的用户)。
  • 搜索是最基本的。WebDAV本身只知道文件。它不关心结构文件名,或强名称的存在。

看来我们还是没找到要找的东西,然后…

NuGet来了
这是另一回事。NuGet旨在成为“面向。net平台的开发人员的包管理系统”,旨在简化将第三方库合并到. NET应用程序”。这正是我们所需要的。让我们看看它有多棒:

  • 管理包,而不是dll
  • 提供了NuGet画廊-几乎有4.5K(在撰写本文时)的软件包可供您使用,以满足您的所有开发需求。
  • 支持二进制版本控制
  • 与Visual Studio集成。
  • 与您的构建集成。
  • 与构建服务器集成(仅限)TeamCity在撰写本文时)。

这个工具就像梦想成真。那么,我能提到哪些缺点呢?大多数都是缺点NuGet画廊的,不是NuGet本身。该画廊是一个年轻且相对较小的项目(仅为了比较,Maven Central已有6年历史,包含超过290K件文物),因此,它有其缺点:

  • 提交给画廊的内容(几乎)未经核实。每个人都可以注册,获得API密钥,并开始上传他们喜欢的任何东西。很可怕,不是吗?(是的非常可怕)。
  • NuGet Gallery是公开的,不能用于团队间交换。私有远程提要是推荐的解决方案。接下来我们将看看它是否足够好。

使用NuGet远程feed
远程提要NuGet 1.4中引入的特性是任何开发团队的关键需求。它有两个目的:它允许分享3日派对套餐不能在画廊(或者甚至为那些不信任它的人取代Gallery),它作为内部部署的目标——既用于团队协作,也用于其他用途,如向QA提供包,甚至向外部世界的客户提供包(通过使用巧克力色,例如)。如果这是对的,那错在哪里?这就是:

  • 你预见到了它的到来:它不是一个代理。你现在知道比分了。
  • 它不能聚集。的NuGet远程饲料暴露一个单片存储库:您机器上的存储库。它不能从远程存储库聚合NuGet包,也不能公开数量本地存储库(例如,出于安全原因而分离)。
  • 您不能附加自己的元数据。假设您想用兼容性信息注释某个包(例如。作品使用某些浏览器)。不,不行。
  • 该存储库非常简单。它不提供任何web界面;它只能从客户端浏览和搜索——无论是Visual Studio还是命令行界面(本身就很基本)。
  • 即使是VS的搜索界面也是非常基本的(你所拥有的只是任意排序和自由文本搜索)。这应该足够了先发,但缺少对包裹内部的搜索通过属性(从前面的子弹)最终会咬你一口。
  • 安全方案甚至不简单。一次对所有用户的部署/删除进行身份验证所需要的只是一个API密钥。职责分离呢?一些用户应该只能阅读,其他用户只能用元数据进行注释(在我前面的例子中测试兼容性的QA团队),并且只有一小部分用户可以部署。全有或全无的方案显然是不够的。
  • 存储格式不理想:
    • 包以朴素的简单格式存储在文件系统上。适用于小型储存库但随着业务的增长,您会期望存储对二进制文件进行更优化。
    • 元数据没有被索引。再说一遍,没问题小回购在美国,当涉及到规模时,可以预见会遇到麻烦。

那么,是否有一个好的替代NuGet远程Feed作为你内部的NuGet包库呢?我们,骄傲的制造者Artifactory我相信有:

满足Artifactory
Artifactory是一个企业级二进制存储库它集中了管理软件二进制文件的所有方面。这意味着我们要解决上面提到的所有问题。我们正在开发自2006年开始制造。被数百万用户用于存储、共享和管理二进制文件,我们从用户那里收集了大量的反馈。
这就是我们所学到的:

  • 二进制包与源包不同(大且二进制),需要智能存储。
  • 二进制包通常档案(不管是罐子,拉链,rpmnupkgs)。它们应该是可浏览和搜索的,而不需要将它们下载到本地开发人员的机器
  • 网络上存在大型公共存储库,这是必要的代理聪明地(变化、审计、管理)
  • 用户有不同的口味。它们的权限应该匹配可能的职责(在二进制包的情况下,它们与其他情况不同)。
  • 二进制存储库包含关键信息,它应该坚如磐石、已备份并准备好了DRP。
  • 您的软件最终成为一个包。我们知道如何帮助你……
    • 构建它以一种可再现的方式,与您的构建工具和构建服务器集成。
    • 阶段它保证了最好的质量。
    • 分发是给你的顾客的。

你可以通过观看了解《人工工厂》背后的要点这段2.5分钟的YouTube视频。如果你没有心情看电影(或者爆米花吃完了),这里有快速回顾(点击图片查看完整尺寸):

NuGet毫无价值的

正如你所看到的,开发人员不是使用多个NuGet feed (NuGet Gallery、Orchard Gallery、来自同事和不同团队的远程feed),而是使用一个存储库。简化了安装和日常工作,集中了管理和维护。
这项工作是双向的,用户从Artifactory解析他们的第三方依赖,并将他们创建的包部署到Artifactory中。
现在让我们添加一个构建服务器到图中:

NuGet构建

是的,这次是数字。那么,我们开始吧(点击图片查看完整尺寸):

  1. 开发人员从Visual Studio中的Artifactory中查找并获取新的第三方包。软件包从Artifactory下载到开发人员的机器上。如果软件包不在Artifactory中,它将在远程库/提要中寻找它们。在开发人员机器配置被更新为使用的包列表。
  2. 开发人员提交他们的代码和包配置文件(但不是二进制文件)到VCS。
  3. 构建服务器(正如我已经提到的,TeamCity现在支持NuGet)从VCS获取更改。
  4. 它构建解决方案并将生成的工件打包为NuGet包。
  5. 在构建过程中,它从Artifactory获取所需的包。如果软件包不在Artifactory中,它将在远程库/提要中寻找它们。
  6. 一旦包被构建,它们就被部署到Artifactory。

Artifactory中的构建包可以被其他团队使用(作为他们的第三方依赖)质量保证的运行测试,甚至由最终用户(巧克力色FTW),所有这些都需要细粒度的权限和健壮的提升过程(在具有不同可见性规则的存储库之间移动包)。
你知道吗?它值得专门的入门博客。一旦发表,我会把它链接到这里。

假设你已经读到这一点,你已经收集到,从Artifactory版本2.5.0开始,我们很自豪地为。net世界提供完整的NuGet支持。我们可以代理任何远程NuGet feed(当然是从NuGet Gallery开始),我们可以托管在任何远程NuGet feed上找不到的包,我们可以托管您生成的包,我们可以在单个URL下聚合任意数量的任何类型的存储库。我们为您提供了一个很棒的UI来配置您的存储库,浏览和搜索您的包。我们还提供智能存储功能,可以在二进制文件上附加可搜索的元数据。我们可以做到这一切云带着我们SAAS版本

希望你现在相信了,可能正在我们的网站上寻找下载链接(这是它(顺便说一句,点击“Evalution”)。如果没有,试着玩一下我们的现场演示。看看这个nuget-gallery cache:这就是我们代理NuGet Gallery的方式。你会发现有些软件包保存在本地;一旦您选择了一个包,您将看到关于它的各种信息:它的名称和大小,谁将它部署到Artifactory,它来自哪里(来自NuGet Gallery,因为这是NuGet Gallery缓存),以及您可以在这个包上执行的操作(作为匿名的选择自然是有限的)。单击树状图中的三角形将打开包,让您深入了解其内容,包括从存档中下载特定文件:

浏览nupkg

在JFrog,我们相信Artifactory是健壮、敏捷的。net依赖管理中缺失的一块,它可以使开发过程比其他替代方案更容易。

我们将很高兴收到任何见解,想法和评论的想法在这个博客和/或您的使用经验与…一起NuGet