.NET: 谈谈共享项目 (Shared Project) 的使用
从 Visual Studio 2015 起,共享项目 (Shared Project) 作为新的一种项目类型被添加到项目模板列表中,它的主要目的是使多个不同类型的项目之间可以共享代码或资源。相比它的前任 PCL(Portable Class Library),它要灵活得多。因为 Shared Project 共享的是代码或资源,并且不会创建单独的程序集;而 PCL 则是共享程序集,需要单独编译,且会生成单独的程序集。
在项目中,使用 Shared Project 可以帮助我们很容易地解决一些难题。本文主要讨论,在开发过程中,我们如何使用它以及它具体能够帮助我们解决哪些问题。在这之前,首先来看如何创建与使用 Shared Project。
创建与使用
前面说过,Shared Project 是一种项目模板类型,因此我们可以在现有的解决方案中创建一个新项目,然后在项目模板列表中选择 Shared Project:

在这个 Shared Project 中我们可以添加所有需要与其它项目共享的代码或资源(如图片、Html文件、JS 文件等)。另外,为了保持它与现有项目命名空间一致,可以在“解决方案管理器"中右击它,选择”属性“,更改其 Root namespace。
接着,要在那些需要引用它的项目中对其添加引用,如下:

当引用后,所有在 Shared Project 中代码和资源能够在这些项目中正常使用。
此外,Shared Project 自己无法编译,我们需要通过编译引用它的项目来生成 exe 或 dll 等程序集。并且 Shared Project 本身不会输出为程序集。
使用场景
场景一:输出针对不同 .NET Framework 版本的类库
如果你正在开发一个类库或框架,而且最终要发布它,好让别人能够使用,所以你的类库可能需要满足多个 .NET Framework 版本,如 2.0/3.5/4.0/4.5 等,由于更高版本的 Framework 加入了更多的 API 以及更多的语法,使得在代码编写时更容易,比如 LINQ 等,然而低版本却不支持,因此在类库中的代码就需要对不同的版本有区分。
对于这种情况,借助于 Shared Project 和条件编译符号 (Conditional compilation symbols),就可以解决上述问题。我们可以这样做:
1. 创建一个 Shared Project 项目;
2. 再分别创建多个类库 (Class Library) 项目,它们的目标框架 (Target framework) 分别指定不同的 Framework 版本;
3. 为每个类库类目设置不同的条件编译符号(在项目属性中的“编译”选项卡里设置),如 NET2_0/NET4_0/NET4_5 等;
4. 然后,在 Shared Project 中就可以使用这些符号来判断 Framework 版本,并写出针对不同版本的代码,例如下面的代码(注意其中加粗部分):
this.windowChrome = new WindowChrome
{
#if NET4_5
ResizeBorderThickness = SystemParameters.WindowResizeBorderThickness,
#else
ResizeBorderThickness = SystemParameters2.Current.WindowResizeBorderThickness,
#endif
CaptionHeight = ,
CornerRadius = new CornerRadius(),
GlassFrameThickness = new Thickness(),
UseAeroCaptionButtons = false
};
场景二:输出针对不同 Platform 的类库
如果项目中一个(或多个)类库需要同时支持 x86 与 x64 两个不同的 Platform,以使软件能够在 x86/x64 上都能运行,这时 Shared Project 也可以派上用场。
一个具体的例子是开发 Office 加载项,如果你的加载项是 COM 类型的,则需要分别为 32位与 64位 Office 提供对应的版本。对于32位,程序集的目标平台 (Platform target) 可以是 Any CPU,但对于64位,则应该是 x64。
使用 Shared Project 可以很容易解决这样的问题,具体做法:
1. 针对加载项创建一个 Shared Project,将所有代码与资源文件放到这个项目中;
2. 分别创建两个不同的 Class Library,使它们引用 Shared Project,不同的是,这两个项目的目标平台不一样,一个是 Any CPU,另一个是 x64;
3. 如果用到了第三方库,为两个项目添加同样的引用;
4. 除此以外,你还要修改它们的程序集名称,使它们的输出的程序集名称有区别、且有意义。
最后,需要注意的是,修改项目属性时,无论是设置"条件编译符号",还是修改"目标平台",都要注意它们都与项目的配置 (Debug/Release) 是关联的,也就是说,在 Debug 配置中改了,还要在 Release 配置中改;对于此,一个替代的办法是,从配置下拉列表选择“所有配置”,然后再设置符号或目标平台,则能够对 Debug/Release 都有效。
总结
本文主要讨论了 Shared Project 的使用以及它的实际使用场景,它能够使我们的程序集面向不同 .NET Framework 版本以及不同的 Platform。
其实不难看出,这都是通过修改项目的属性而实现的,这样一来,多个项目就可以达到代码相同、程序集属性却不同,从而解决实际对应的问题。如果你在开发过程中遇到了类似的问题,也可以尝试一下使用 Shared Project 来解决。
延伸阅读:
Developing Libraries with Cross Platform Tools
Additions to the csproj format for .NET Core
.NET: 谈谈共享项目 (Shared Project) 的使用的更多相关文章
- Visual Studio 2015创建Shared Project时出错
今天使用Visual Studio 2015创建共享项目的时候发现如下错误: 网上搜了一下,发现了同样有人问这个问题的问题:Why can't I create Shared Project in V ...
- 在Spring tools suite中使用git 共享项目
我们都在eclipse 和 myeclipse中使用过cvs 和 svn 版本控制工具进行团队开发,今天我学习了另外一种版本控制工具git,下面我演示如何在Spring tools suite中使用g ...
- VSTO 学习笔记(十三)谈谈VSTO项目的部署
原文:VSTO 学习笔记(十三)谈谈VSTO项目的部署 一般客户计算机专业水平不高,但是有一些Office水平相当了得,尤其对Excel的操作非常熟练.因此如果能将产品的一些功能集成在Office中, ...
- 谈谈MVC项目中的缓存功能设计的相关问题
本文收集一些关于项目中为什么需要使用缓存功能,以及怎么使用等,在实际开发中对缓存的设计的考虑 为什么需要讨论缓存呢? 缓存是一个中大型系统所必须考虑的问题.为了避免每次请求都去访问后台的资源(例如数据 ...
- Axure如何建立共享项目、如何编辑共享项目、如何获取共享项目
如果小伙伴是一名编程工作者,我们不可以避免的会和Axure这块软件握手,但是但一个项目需要协同操作的时候,就需要用到项目共享的功能.类似我们的svn,想起机房合作的时候,每天早上来到427的我们,打开 ...
- 错误 : 资产文件“项目\obj\project.assets.json”没有“.NETCoreApp,Version=v2.0”的目标。确保已运行还原,且“netcoreapp2.0”已包含在项目的 TargetFrameworks 中。
升级 vs201715.6.3之后发布出现 错误 : 资产文件“项目\obj\project.assets.json”没有“.NETCoreApp,Version=v2.0”的目标.确保已运行还原,且 ...
- eclipse 中右键项目出现卡死导致无法共享项目的解决办法
亲身经历,这个问题出自于项目中的SVN地址不对,如果要更改SVN地址,可以断掉计算机的网,在eclipse的工作空间中找到该项目,找到隐藏的.svn 文件夹,删除掉之后,打开eclipse,此时就可以 ...
- linux内核剖析(十一)进程间通信之-共享内存Shared Memory
共享内存 共享内存是进程间通信中最简单的方式之一. 共享内存是系统出于多个进程之间通讯的考虑,而预留的的一块内存区. 共享内存允许两个或更多进程访问同一块内存,就如同 malloc() 函数向不同进程 ...
- 结对项目 Pair Project
结对项目 Pair Project 一人编程,一人操作,共同检查. 源码 https://github.com/dpch16303/test/blob/master/%E5%AE%9E%E8%B7%B ...
随机推荐
- [树莓派(raspberry pi)] 02、PI3安装openCV开发环境做图像识别(详细版)
前言 上一篇我们讲了在linux环境下给树莓派安装系统及入门各种资料 ,今天我们更进一步,尝试在PI3上安装openCV开发环境. 博主在做的过程中主要参考一个国外小哥的文章(见最后链接1),不过其教 ...
- replace into 浅析之一
一 介绍 在笔者支持业务过程中,经常遇到开发咨询replace into 的使用场景以及注意事项,这里做个总结.从功能原理,性能和注意事项上做个说明.二 原理2.1 当表中存在主键但是不存在唯一建的 ...
- WebGL多模型光照综合实例
原文地址:WebGL多模型光照综合实例 WebGL是一个非常的接近硬件底层的光栅化API, 从非常类似C/C++风格的API调用方式就可以看出来, 习惯了高级语言的我们会觉得很不友好,觉得特别 ...
- oracle如何导出和导入数据库表
oracle如何导出和导入数据库表 oracle如何将项目中的表导出后在导入自己的数据库中,这是一个完整的操作,对于数据库备份或在本地查看数据验证数据进场用到,一般情况下我都用dos黑窗口进行操作,简 ...
- 微信小程序之自定义toast弹窗
微信小程序里面的自带弹窗icon只有两种,success和loading.有时候用户输入错误的时候想加入一个提醒图标,也可以使用wx.showToast中的image来添加图片达到使用自定义图标的目的 ...
- python文件处理相关函数
用open()创建文件 open('a.txt','wt') 用exists()检查文件是否存在 os.path.exists() 用isfile()检查是否为文件 os.path.isfile(na ...
- java_web学习(十一) 层的概念与应用
一个项目通常分为三层: 所谓三层是表述层(WEB层).业务逻辑层(Business Logic),以及数据访问层(Data Access). ·WEB层:包含JSP和Servlet等与WEB相关的内容 ...
- 1c19b35b005744d55261682b361804fa 如何破解经过 MD5 算法处理的信息?
Md5密文破解(解密)可以说是网络攻击中的一个必不可少的环节,是工具中的一个重要"辅助工具".md5解密主要用于网络攻击,在对网站等进行入侵过程,有可能获得管理员或者其他用户的账号 ...
- Flume(一)Flume原理解析
前言 最近有一点浮躁,遇到了很多不该发生在我身上的事情.没有,忘掉这些.好好的学习,才是正道! 一.Flume简介 flume 作为 cloudera 开发的实时日志收集系统,受到了业界的认可与广泛应 ...
- bzoj:1700: [Usaco2007 Jan]Problem Solving 解题
Description 过去的日子里,农夫John的牛没有任何题目. 可是现在他们有题目,有很多的题目. 精确地说,他们有P (1 <= P <= 300) 道题目要做. 他们还离开了农场 ...