共享就是关爱:在ASP.NET中使用共享项目
作为软件开发人员,复制粘贴一些代码或一些文件并将其放在多个地方总是很臭。有几种不同的途径可以避免这种冗余,但这篇文章将重点关注一个似乎不常被谈论的途径:共享项目。
通过链接避免冗余
在介绍共享项目之前,我将简要介绍为什么要引入共享项目本身,以及在它们发布之前您是如何完成类似行为的。
随着Visual Studio在过去几年中提出的跨平台的主要倡议,出现了一个问题,即如何组织可以跨多个平台访问的代码,而不只是疯狂地进行复制粘贴。对此的答案是传说中的“添加为链接”选项:
您只需单击一个项目,选择“添加现有文件”选项,然后选择对话框中出现的“添加为链接”选项。这将创建一个指向原始文件的指针,该指针将出现在两个项目中。
这个问题——太乏味了。你一次只能选择一个文件,想象一下,如果你必须在多个平台上引用多个文件?一想到这就足以让你的手腕感到刺痛。
只需要有一个更好的方法,以及拟议的解决方案:共享项目。
什么是共享项目?
共享项目的概念是在Visual Studio 2013 RC 2中引入的,简而言之,它允许您引用整个项目,而不是像使用类库那样只引用一个程序集。
现在这是怎么工作的?一个项目中包含了我可能不想使用的所有类型的东西?如何处理共享项目中的引用?那些东西呢?
需要注意的是,术语“共享项目”也可以是“共享代码桶”,因为它更像是一个占位符项目,您可以将所有代码和其他文件(如资源)存储在其中。在编译时,任何引用此共享项目的项目都会将所有文件(包括文件夹结构等)合并到其中,然后进行编译,或者换句话说:
共享项目不会单独编译,而是将项目中的代码合并到引用它的每个程序集中,并在其中进行编译。
现在您已经对什么是共享项目有了一个相当不错的想法,让我们看看如何在应用程序中使用它。
使用共享项目
共享项目和其他任何文件或文件夹一样容易创建,通常只需要点击几下即可启动和运行。
要将共享项目添加到现有解决方案中,请右键单击该解决方案并选择“添加项目”,然后从Visual C#选项卡中选择“共享项目”:
您将看到共享项目出现在解决方案资源管理器中,从这一点开始,您可以开始向其中添加要使用的任何类型的文件。在本例中,我们将创建一个类,该类将公开我们希望在其他两个项目中可访问的函数。
对于这个例子,我们将创建一个新文件,尝试添加,但不是很好:
接下来,我们将希望在另一个项目中添加对此的引用。这与您过去习惯于添加引用的方式类似。右键单击要在其中使用共享项目的项目,选择“添加引用”,然后在左侧显示的“共享项目”选项卡下选择共享项目:
将其添加为引用后,您现在可以简单地使用以下方法在目标项目中访问此方法:
var result = Common.Math.DefunctAdd(3, 7);
这里没什么特别的。这是你一直都能做到的。好吧,让我们通过应用条件编译属性来让函数根据目标平台的不同表现来增加趣味性:
public static int DefunctAdd(int x, int y) { #if NETCOREAPP1_1 return (x + y) + 3; #else return (x + y) + 13; #endif }
由于此文件将由引用它的每个项目独立编译,因此我们可以在两个独立的应用程序中引用共享项目,并产生以下结果:
// .NET Core 1.1 Common.DefunctAdd(3, 7); // returns 13 // .NET Core 1.0 Common.DefunctAdd(3, 7); // returns 23
这是一个相当简单的例子,但如果您正在构建一个跨平台应用程序或需要在它们之间共享资源(即图像、CSS、XAML等),那么用例会扩展很多。
现在你可能会问自己,我为什么要做这一切?我就不能用一个可移植的类库来完成这个吗?是的,你绝对可以,但这是解决你问题的最佳方法吗?
与软件世界中的惯例一样,这取决于情况,在下一节中,我们将比较这两种方法,看看它们有什么不同。
共享项目 | 可移植类库 | |
代码重用级别 | 源代码(即引用包含所有要使用的源代码的项目) | 程序集(即引用YourLibrary.dll文件) |
编译时会发生什么? | 共享项目中的所有源代码都被复制到每个引用的项目中,并在其中编译。 | 这里没有什么新内容,它是按预期编译的 |
Visual Studio的支持 | 自从Visual Studio 2013 Update 2以来 | 一开始就支持 |
#IFDEF支持 | 完全支持 | 不支持(因为每个平台都是单独编译的,必须通过IoC完成) |
.NET Framework 支持 | 完全支持 | 有限(功能将基于目标平台的子集) |
共享项目与可移植类库
关键的区别在于如何编译这些实体,以及如何重用它们:
- 可移植类库是按照您所了解和期望的方式编译的,重用单元是它的程序集(即您在其他项目中引用YourLibrary.dll)。
- 共享项目本身不进行编译,而是在编译之前将项目中包含的代码合并到引用共享项目的每个程序集中。因此,共享项目中的重用单元实际上是源代码本身(即,您引用的是要包含在另一个项目中的代码“容器”)。
现在,共享项目的一个常见用例是必须构建一个针对多个平台的应用程序的场景。通常,您可能会考虑构建可移植类库(PCL),但让我们看看这与共享项目相比如何:
我为什么要使用另一个呢?
在构建跨平台应用程序时,通常会遇到共享项目和可移植类库,这是理所当然的。
跨多个项目以及潜在的不同平台和体系结构共享代码的想法非常吸引人。当您考虑将其不仅扩展到代码,还扩展到资源、XAML,甚至Javascript、CSS和其他客户端文件时,它确实展示了这些概念的威力。
虽然这两种机制都可以用来避免冗余,但偏好将归结为项目所需的特定重用级别(以及何时需要重用内容)。
由于共享项目涵盖了大多数通常涉及可移植类库的场景,因此在使用可移植类库之前,需要考虑以下几点:
- 组装在您的场景中重要吗?如果这就是你需要分享的全部内容,那么PCL就可以了。
- 您是否需要共享一些C#代码以外的东西,如Javascript或其他资源?共享项目将是理想的选择。
- 您是否需要多个应用程序以不同的方式(通过不同的引用程序集或通过指令)编译相同的代码?只有通过共享项目才能真正做到这一点。
- 你知道你要针对的框架的具体版本吗?如果是这样,那么可以使用可移植类库。
- 需要代码分区,而不是简单地共享所有内容?对于共享项目,要么全有要么全无(至少不需要进行大量的修改来忽略一些事情),因此可移植类库将允许您只共享您需要的内容。
- 需要对所有内容进行单元测试吗?可移植类库将更好地用于单元测试,因为共享项目将在多个项目中编译给定的文件(这可能会导致不同的结果)。
所以,就像构建应用程序时的大多数事情一样,这取决于具体情况。
关于共享项目的结束思考
选项卡还是空格?反应还是角度?共享项目还是可移植类库?所有这些都是在构建应用程序或做出与之相关的决策时进行的常见讨论,每个人都有自己的意见,认为哪一个是正确的。
就我个人而言,我是共享项目的忠实粉丝,在我看来,共享项目比PCL更通用,当你可以使用它们时,可以快速添加新的特定于平台的功能,而不会有太多不必要的复杂性。
然而,这确实是有代价的,尤其是当你不只是共享代码,而是针对多个平台时。条件编译指令可能会使代码难以测试,这反过来又会引入一些错误,直到您真正编译完应用程序后才会知道这些错误。
因此,如果您只需要在业务应用程序中共享一些核心类,或者需要在多个平台上共享功能,您可以尝试对共享项目进行调整。正如本文多次指出的那样,它们并不总是适用于每个人或每个场景,但当它们合适时,我发现它们可以让你的生活更轻松。
原文地址:https://rion.io/2017/03/22/sharing-is-caring-using-shared-projects-in-asp-net/
posted on 2023-04-10 00:00 drewwestlhq 阅读(127) 评论(0) 编辑 收藏 举报