一、库的地狱

库可以在多个应用程序中重用代码。在Windows中,库有很长的历史,而构建原则通过更新的技术走向了不同的方向。在.NET之前,动态链接库(Dynamic Link Library,DLL)可以在不同的应用程序之间共享。这些DLL已安装在共享目录中。这些库在同一个系统上不可能有多个版本,但它们应该是向上兼容的。当然,情况并非总是如此。此外,应用程序的安装也存在一些问题,例如没有关注指导方针,用旧版本替代共享库。这就是DLL地狱。

.NET试图用程序集解决这个问题。程序集是可以共享的库。除了正常的DLL之外,程序集还包含可扩展的元数据,以及关于库和版本号的信息,并且可以在全局程序集缓存中并排安装多个版本。微软试图解决版本问题,但这又增加了一层复杂性。

假设使用的是应用程序X中的库A和库B。应用程序X引用库A的1.1版本和库B的1.0版本,问题是库B也引用了库A,但是它引用了另一个版本——1.0。一个进程只能加载库的一个版本。那么,在进程中加载哪个版本的库A?如果库B在库A之前使用,那么版本1.0就会胜出。当应用程序X需要使用库A时,这就是一个大问题。

为了避免这个问题,可以配置程序集重定向。可以为应用程序X定义一个程序集重定向,以便加载库A的版本1.1,然后库B需要使用库A的版本1.1。如果库A是向上兼容的,这就不应该有问题。

当然,兼容性并不总是存在的,问题可能更复杂。组件的发布者可以创建一个发布者策略来定义库本身的重定向。这个重定向可以由应用程序重写。这里面有很多复杂的东西,导致了程序集的地狱。

注:在.NET Core中,并没有像.NET Framework那样的程序集全局共享。只有.NET运行库可以在不同的应用程序之间共享。

.NuGet包在库中添加了另一个抽象层。NuGet包可以包含一个或多个程序集的多个版本,以及其他内容,例如程序集重定向的自动配置。

不需要等待新的.NET Framework版本,而可以通过NuGet包添加功能,这样可以更快的更新包。NuGet包是一款很棒的运载工具。一些库,例如Entity Framework,已切换到Nuget上,它提供的更新比.NET Framework更快。

然而,NuGet也存在一些问题。经常在项目中添加NuGet包会失败。NuGet包可能与项目不兼容。当添加包成功时,包可能会在项目中进行一些不正确的配置,例如错误的绑定重定向。这就导致了"NuGet包地狱"。DLL的问题转移到不同的抽象层,并且确实是不同的。在NuGet的新版本和升级版本中,微软尝试用NuGet解决问题。

.NET Core体系结构中的方向也发生了变化。对于.NET Core,包的粒度更细。例如,在.NET Framework中,Console类位于mscorlib程序集中,这是每个.NET Framework应用程序都需要的程序集。当然,并不是每个.NET应用程序都需要Console类。在.NET Core 1.0中有一个单独的包System.Console,其中包含Console类和一些相关类。其目标是使更新更容易,并选择真正需要的包。在.NET Core 1.0的一些Beta版本中,项目文件包含了大量的包,这并没有使开发变得更容易。在.NET Core 1.0发布之前,微软引入了元包(或称为引用包)。元包不包括代码,而包括其他包的列表。

.Net Core 2.0包含了另一种简化。用.NET Core 1.1创建"Hello, World!"控制台应用程序时,生成的project.asset.json文件的大小为313KB。这个文件(在obj目录中)显示了依赖树。在.NET Core 2.0中,由于包更大,引用却较少,文件大小减少到33KB。

本章将介绍程序集和NuGet包的细节。解释如何使用.NET标准库共享代码,并解释与Windows运行库组件的不同之处。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值