本文由陈计节翻译自 Pro NuGet 一书中的 “The Big Picture” 一节,有删节。

 

对软件库和组件使用包管理系统的想法实际上是源自在操作系统层面使用包管理工具来安装软件包和库的概念。基于 Linux 和其他类 Unix 系统中,由成百上千的软件包构成,因此构建一个包管理系统确实非常必要。不过在 Windows 上的 .NET 运行时依赖动态链接库技术,以及 GAC 全局程序集缓存,可以有效防止 DLL 深坑。作为共享程序集的存储库,GAC 自然也成为应用程序查找依赖,以及安装公共程序集的位置。
在软件开发领域,一个包管理工具负责在解决方案范围内以一致的方式对软件包安装、更新、配置以及移除等过程进行自动化。一般情况下,此工具也能够解析包的元信息,比如版本信息、依赖的其他包等信息,可用于防止版本冲突或者不满足安装要求等情况。

在这里我们主要谈论应用程序级别的包管理。

你可能奇怪,为什么我们讨论包管理而不是依赖管理。那是因为“包”与“依赖”之间是有区别的。除了目标项目所依赖的库之外,包还可以包含源代码,配置文件,以及诸如图片、脚本等其他种类的文件。如果讨论依赖,就会将我们限制在包的一部分功用上。

包管理器与安装程序的概念也很容易混淆,主要是因为它们的术语和功能上的类似。安装程序通常是与一个具体的产品相关。换句话说,一个特定的产品通常有特定于自己的安装程序。结果就是安装程序与要安装的产品紧密联系在了一起,与产品相关的选项和安装步骤等因素让重用安装程序变得很难甚至不可能。事实上,也确实有不少安装程序提供商,这又导致了不同格式的安装程序大量的运用。这与包管理工具有很大的不同:包管理工具只是包的安装程序,而包则需要是包管理器能够理解的特定格式。

包管理工具主要处理包的版本和依赖管理,它能聪明地检测潜在的冲突。它还可以在必要的时候添加 binding redirect,如果在安装过程中发现版本冲突,它会向你发出通知。
这让包的安装和依赖冲突管理更方便,尤其是它能够检测并且解决 binding redirect 的问题;在出现问题时,它也可以明确地告诉你具体的问题之后,取消包的安装。因为包的格式是有具体的规范来限制的,而包管理工具对所有的包也是相同的,所以在这方面,你可以有统一而独立的开发环境。

现在,你只需要依赖两个方面:包管理工具,以及包的发布者。包管理工具是“单一点故障点”,不过,你可以相信它是经过良好的测试的,能够像期待的方式那样工作。所以它基本不会出什么问题。包发布者这边,却是一个未知的第三方,它可能包含着普通的错误。不过,这与没有包管理时依赖第三方组件也没有什么区别;你只能假设组件,或包,是经过良好测试、工作正常的。如果条件允许,在使用第三方组件之前,试图找找其开发人员为组件编写的单元测试,或其他类型的测试;他们是否有好的资金来继续支持这个组件的开发?包内容的结构,是由包规范根据包管理工具的理解来定义的。包发布者唯一能够人为产生的错误就是版本号格式了。