.
NET应用程序体系结构本章要点回顾.
NET的历史理解.
NETFramework4.
6和.
NETCore1.
0之间的差异程序集和NuGet包公共语言运行库Windows运行库的特性编写"Hello,World!
"程序通用Windows平台创建Windows应用程序的技术创建Web应用程序的技术本章源代码下载:打开网页www.
wrox.
com/go/professionalcsharp6,单击DownloadCode选项卡即可下载本章源代码.
本章代码分为以下几个主要的示例文件:DotnetHelloWorldHelloWorldApp(.
NETCore)1.
1选择技术近年来,.
NET已经成为在Windows平台上创建任意类型的应用程序的巨大生态系统.
有了.
NET,可以创建Windows应用程序、Web服务、Web应用程序以及用于MicrosoftPhone的应用程序.
.
NET的最新版本对上一版进行了很大的修改——也许是.
NET自问世以来最大的修改.
.
NET的大部分代码已开放,还可以为其他平台创建应用程序.
.
NET的新版本(.
NETCore)和NuGet包允许微软公司以更短的更新周期提供新特性.
应该使用什么技术来创建应用程序并不容易决定.
本章将1第章第1章.
NET应用程序体系结构3提供这方面的帮助.
其中包含用于创建Windows、Web应用程序和服务的不同技术的信息,指导选择什么技术进行数据库访问,凸显了.
NET和.
NETCore之间的差异.
1.
2回顾.
NET历史要更好地理解.
NET和C#的可用功能,最好先了解它的历史.
表1-1显示了.
NET的版本、对应的公共语言运行库(CommonLanguageRuntime,CLR)的版本、C#的版本和VisualStudio的版本,并指出相应版本的发布年份.
除了知道使用什么技术之外,最好也知道不推荐使用什么技术,因为这些技术会被代替.
表1-1.
NETCLRC#VisualStudio1.
01.
01.
020021.
11.
11.
220032.
02.
02.
020053.
02.
02.
02005+扩展版3.
52.
03.
020084.
04.
04.
020104.
54.
05.
020124.
5.
14.
05.
020134.
64.
062015.
NETCore1.
0CoreCLR62015+扩展版下面各小节详细介绍表1-1,以及C#和.
NET的发展.
1.
2.
1C#1.
0——一种新语言C#1.
0是一种全新的编程语言,用于.
NETFramework.
开发它时,.
NETFramework由大约3000个类和CLR组成.
(创建Java的Sun公司申请)法庭判决不允许微软公司更改Java代码后,AndersHejlsberg设计了C#.
Hejlsberg为微软公司工作之前,在Borland公司设计了Delphi编程语言(一种ObjectPascal语言).
Hejlsberg在微软公司负责J++(Java编程语言的微软版本).
鉴于Hejlsberg的背景,C#编程语言主要受到C++、Java和Pascal的影响.
因为C#的创建晚于Java和C++,所以微软公司分析了其他语言中典型的编程错误,完成了一些不同的工作来避免这些错误.
这些不同的工作包括:在if语句中,布尔(Boolean)表达式是必须的(C++也允许在这里使用整数值).
允许使用struct和class关键字创建值类型和引用类型(Java只允许创建自定义引用类型;在C++中,struct和class之间的区别只是访问修饰符的默认值不同).
允许使用虚拟方法和非虚拟方法(这类似于C++,Java总是创建虚拟方法).
当然,阅读本书,你会看到更多的变化.
第Ⅰ部分C#语言4现在,C#是一种纯粹的面向对象编程语言,具备继承、封装和多态性等特性.
C#也提供了基于组件的编程改进,如委托和事件.
在.
NET和CLR推出之前,每种编程语言都有自己的运行库.
在C++中,C++运行库与每个C++程序链接起来.
VisualBasic6有自己的运行库VBRun.
Java的运行库是Java虚拟机(JavaVirtualMachine,JVC)——可以与CLR相媲美.
CLR是每种.
NET编程语言都使用的运行库.
推出CLR时,微软公司提供了JScript.
NET、VisualBasic.
NET、ManagedC++和C#.
JScript.
NET是微软公司的JavaScript编译器,与CLR和.
NET类一起使用.
VisualBasic.
NET是提供.
NET支持的VisualBasic.
现在再次简称为VisualBasic.
ManagedC++是混合了本地C++代码与Managed.
NET代码的语言.
今天与.
NET一起使用的新C++语言是C++/CLR.
.
NET编程语言的编译器生成中间语言(IntermediateLanguage,IL)代码.
IL代码看起来像面向对象的机器码,使用工具ildasm.
exe可以打开包含.
NET代码的DLL或EXE文件来检查IL代码.
CLR包含一个即时(Just-In-Time,JIT)编译器,当程序开始运行时,JIT编译器会从IL代码生成本地代码.
CLR的其他部分是垃圾回收器(GC)、调试器扩展和线程实用工具.
垃圾回收器负责清理不再引用的托管内存,这个安全机制使用代码访问安全性来验证允许代码做什么;调试器扩展允许在不同的编程语言之间启动调试会话(例如,在VisualBasic中启动调试会话,在C#库内继续调试);线程实用工具负责在底层平台上创建线程.
.
NETFramework的第1版已经很大了.
类在名称空间内组织,以便于导航可用的3000个类.
名称空间用来组织类,允许在不同的名称空间中有相同的类名,以解决冲突.
.
NETFramework的第1版允许使用WindowsForms(名称空间System.
Windows.
Forms)创建Windows桌面应用程序,使用ASP.
NETWebForms(System.
Web)创建Web应用程序,使用ASP.
NETWebServices与应用程序和Web服务通信,使用.
NETRemoting在.
NET应用程序之间更迅速地通信,使用EnterpriseServices创建运行在应用程序服务器上的COM+组件.
ASP.
NETWebForms是创建Web应用程序的技术,其目标是开发人员不需要了解HTML和JavaScript.
服务器端控件会创建HTML和JavaScript,这些控件的工作方式类似于WindowsForms本身.
C#1.
2和.
NET1.
1主要是错误修复版本,改进较小.
注意:IL代码也称为托管代码.
注意:继承在第4章中讨论,委托和事件在第9章中讨论.
注意:.
NET的每个新版本都有ProfessionalC#图书的新版本.
对于.
NET1.
0,这本书已经是第2版了,因为第1版是以.
NET1.
0的Beta2为基础出版的.
目前,本书是第10版.
第1章.
NET应用程序体系结构51.
2.
2带有泛型的C#2和.
NET2C#2和.
NET2是一个巨大的更新.
在这个版本中,改变了C#编程语言,建立了IL代码,所以需要新的CLR来支持IL代码的增加.
一个大的变化是泛型.
泛型允许创建类型,而不需要知道使用什么内部类型.
所使用的内部类型在实例化(即创建实例)时定义.
C#编程语言中的这个改进也导致了Framework中多了许多新类型,例如System.
Collections.
Generic名称空间中新的泛型集合类.
有了这个类,1.
0版本定义的旧集合类就很少用在新应用程序中了.
当然,旧类现在仍然在工作,甚至在新的.
NETCore版本中也是如此.
1.
2.
3.
NET3.
0——WindowsPresentationFoundation发布.
NET3.
0时,不需要新版本的C#.
3.
0版本只提供了新的库,但它发布了大量新的类型和名称空间.
WindowsPresentationFoundation(WPF)可能是新框架最大的一部分,用于创建Windows桌面应用程序.
WindowsForms包括本地Windows控件,且基于像素;而WPF基于DirectX,独立绘制每个控件.
WPF中的矢量图形允许无缝地调整任何窗体的大小.
WPF中的模板还允许完全自定义外观.
例如,用于苏黎世机场的应用程序可以包含看起来像一架飞机的按钮.
因此,应用程序的外观可以与之前开发的传统Windows应用程序非常不同.
System.
Windows名称空间下的所有内容都属于WPF,但System.
Windows.
Forms除外.
有了WPF,用户界面可以使用XML语法设计XAML(XMLforApplicationsMarkupLanguage).
.
NET3.
0推出之前,ASP.
NETWebServices和.
NETRemoting用于应用程序之间的通信.
MessageQueuing是用于通信的另一个选择.
各种技术有不同的优点和缺点,它们都用不同的API进行编程.
典型的企业应用程序必须使用一个以上的通信API,因此必须学习其中的几项技术.
WCF(WindowsCommunicationFoundation)解决了这个问题.
WCF把其他API的所有选项结合到一个API中.
然而,为了支持WCF提供的所有功能,需要配置WCF.
.
NET3.
0版本的第三大部分是WindowsWF(WorkflowFoundation)和名称空间System.
Workflow.
微软公司不是为几个不同的应用程序创建自定义的工作流引擎(微软公司本身为不同的产品创建了几个工作流引擎),而是把工作流引擎用作.
NET的一部分.
有了.
NET3.
0,Framework的类从.
NET2.
0的8000个增加到约12000个.
1.
2.
4C#3和.
NET3.
5——LINQ.
NET3.
5和新版本C#3一起发布.
主要改进是使用C#定义的查询语法,它允许使用相同的语法来过滤和排序对象列表、XML文件和数据库.
语言增强不需要对IL代码进行任何改变,因为这里使用的C#特性只是语法糖.
所有的增强也可以用旧的语法实现,只是需要编写更多的代码.
C#语言很容易进行这些查询.
有了LINQ和lambda表达式,就可以使用相同的查询语法来访问对象集注意:本书一直在使用泛型,详见第6章.
第11章介绍了泛型集合类.
注意:在本书中,WPF参见第29、30、31、34、35和36章.
WCF详见第44章.
第Ⅰ部分C#语言6合、数据库和XML文件.
为了访问数据库并创建LINQ查询,LINQtoSQL发布为.
NET3.
5的一部分.
在.
NET3.
5的第一个更新中,发布了EntityFramework的第一个版本.
LINQtoSQL和EntityFramework都提供了从层次结构到数据库关系的映射和LINQ提供程序.
EntityFramework更强大,但LINQtoSQL更简单.
随着时间的推移,LINQtoSQL的特性在EntityFramework中实现了,并且EntityFramework会一直保留这些特性(现在它看起来与第一个版本非常不同).
另一种引入为.
NET3.
5一部分的技术是System.
AddIn名称空间,它提供了插件模型.
这个模型提供了甚至在过程外部运行插件的强大功能,但它使用起来也很复杂.
1.
2.
5C#4和.
NET4.
0——dynamic和TPLC#4的主题是动态集成脚本语言,使其更容易使用COM集成.
C#语法扩展为使用dynamic关键字、命名参数和可选参数,以及用泛型增强的协变和逆变.
其他改进在.
NETFramework中进行.
有了多核CPU,并行编程就变得越来越重要.
任务并行库(TaskParallelLibrary,TPL)使用Task类和Parallel类抽象出线程,更容易创建并行运行的代码.
因为用.
NET3.
0创建的工作流引擎没有履行自己的诺言,所以全新的WindowsWorkflowFoundation成为.
NET4.
0的一部分.
为了避免与旧工作流引擎冲突,新的工作流引擎是在System.
Activity名称空间中定义的.
C#4的增强还需要一个新版本的运行库.
运行库从版本2跳到版本4.
发布VisualStudio2010时,附带了一项创建Web应用程序的新技术:ASP.
NETMVC2.
0.
与ASP.
NETWebForms不同,这项技术需要编写HTML和JavaScript,并使用C#和.
NET的服务器端功能.
ASP.
NETMVC是定期更新的.
1.
2.
6C#5和异步编程C#5只有两个新的关键字:async和await.
然而,它大大简化了异步方法的编程.
在Windows8中,触摸变得更加重要,不阻塞UI线程也变得更加重要.
用户使用鼠标,习惯于花些时间滚动屏幕.
然而,在触摸界面上使用手势时,反应不及时很不好.
Windows8还为WindowsStore应用程序(也称为Modern应用程序、Metro应用程序、通用Windows应用程序,最近称为Windows应用程序)引入了一个新的编程接口:Windows运行库.
这是一个本地运行库,看起来像是使用语言投射的.
NET.
许多WPF控件都为新的运行库重写了,.
NETFramework的一个子集可以使用这样的应用程序.
注意:LINQ详见第13章,EntityFramework的最新版本与.
NET3.
5版本有很大差别,参见第38章.
注意:C#4的dynamic关键字参见第16章.
任务并行库参见第21章.
ASP.
NET5和ASP.
NETMVC6参见第40和41章.
第1章.
NET应用程序体系结构7System.
AddIn框架过于复杂、缓慢,所以用.
NET4.
5创建了一个新的合成框架:ManagedExtensibilityFramework和名称空间System.
Composition.
独立于平台的通信的新版本是由ASP.
NETWebAPI提供的.
WCF提供有状态和无状态的服务,以及许多不同的网络协议,而ASP.
NETWebAPI则简单得多,它是基于RepresentationalStateTransfer(REST)软件架构风格的.
1.
2.
7C#6和.
NETCoreC#6没有由泛型、LINQ和异步带来的巨大改进,但有许多小而实用的语言增强,可以在几个地方减少代码的长度.
很多改进都通过新的编译器引擎Roslyn来实现.
完整的.
NETFramework并不是近年来使用的唯一.
NETFramework.
有些场景需要较小的框架.
2007年,发布了MicrosoftSilverlight的第一个版本(代码名为WPF/E,即WPFEverywhere).
Silverlight是一个Web浏览器插件,支持动态内容.
Silverlight的第一个版本只支持通过JavaScript编程.
第2个版本包含.
NETFramework的子集.
当然,不需要服务器端库,因为Silverlight总是在客户端运行,但附带Silverlight的框架Framework也删除了核心特性中的类和方法,使其更简洁,便于移植到其他平台.
用于桌面的Silverlight最新版本(第5版)在2011年12月发布.
Silverlight也用于WindowsPhone的编程.
Silverlight8.
1进入WindowsPhone8.
1,但这个版本的Silverlight也不同于桌面版本.
在Windows桌面上,有如此巨大的.
NET框架,需要更快的开发节奏,也需要较大的改进.
在DevOps中,开发人员和操作员一起工作,甚至是同一个人不断地给用户提供应用程序和新特性,需要使新特性快速可用.
由于框架巨大,且有许多依赖关系,创建新的特性或修复缺陷是一项不容易完成的任务.
有了几个较小的.
NETFramework(如Silverlight、用于WindowsPhone的Silverlight),在.
NET的桌面版本和较小版本之间共享代码就很重要.
在不同.
NET版本之间共享代码的一项技术是可移植库.
随着时间的推移,有了许多不同的.
NETFramework和版本,可移植库的管理已成为一场噩梦.
为了解决所有这些问题,需要.
NET的新版本(是的,的确需要解决这些问题).
Framework的新版本命名为.
NETCore.
.
NETCore较小,带有模块化的NuGet包以及分布给每个应用程序的运行库是开源的,不仅可用于Windows的桌面版,也可用于许多不同的Windows设备,以及Linux和OSX.
为了创建Web应用程序,完全重写了ASP.
NETCore1.
0.
这个版本不完全向后兼容老版本,需要对现有的ASP.
NETMVC(和ASP.
NETMVC6)代码进行一些修改.
然而,与旧版本相比,它也有注意:C#5的async和await关键字在第15章中详细讨论.
其中也介绍.
NET在不同时期使用的不同异步模式.
MEF参见第26章.
Windows应用程序参见第29~33章,ASP.
NETWebAPI参见第42章.
注意:Roslyn参见第18章.
第Ⅰ部分C#语言8很多优点,例如每一个网络请求的开销较低,性能更好,也可以在Linux上运行.
ASP.
NETWebForms不包含在这个版本中,因为ASP.
NETWebForms不是专为最佳性能而设计的,它基于WindowsForms应用程序开发人员熟悉的模式来提高开发人员的友好性.
当然,并不是所有的应用程序都很容易改为使用.
NETCore.
所以这个巨大的框架也会进行改进——即使这些改进的完成速度没有.
NETCore那么快,也是要改进的.
.
NETFramework完整的新版本是4.
6.
ASP.
NETWebForms的小更新包在完整的.
NET上可用.
1.
2.
8选择技术,继续前进知道框架内技术相互竞争的原因后,就更容易选择用于编写应用程序的技术.
例如,如果创建新的Windows应用程序,使用WindowsForms就不好.
而应该使用基于XAML的技术,例如Windows应用程序,或者使用WPF的Windows桌面应用程序.
如果创建Web应用程序,肯定应使用ASP.
NETCore与ASP.
NETMVC6.
做这个选择时要排除ASP.
NETWebForms.
如果访问数据库,就应该使用EntityFramework而不是LINQtoSQL,应该选择ManagedExtensibilityFramework而不是System.
AddIn.
旧应用程序仍在使用WindowsForms、ASP.
NETWebForms和其他一些旧技术.
只为改变现有的应用程序而使用新技术是没有意义的.
进行修改必须有巨大的优势,例如,维护代码已经是一个噩梦,需要大量的重构以缩短客户要求的发布周期,或者使用一项新技术可以减少更新包的编码时间.
根据旧有应用程序的类型,使用新技术可能不值得.
可以允许应用程序仍使用旧技术,因为在未来的许多年仍将支持WindowsForms和ASP.
NETWebForms.
本书的内容以新技术为基础,展示创建新应用程序的最佳技术.
如果仍然需要维护旧应用程序,可以参考本书的老版本,其中介绍了ASP.
NETWebForms、WindowsForms、System.
AddIn和其他仍然在.
NETFramework中可用的旧技术.
1.
3.
NET2015.
NET2015是所有.
NET技术的总称.
图1-1给出了这些技术的总图.
左边代表.
NETFramework4.
6技术,如WPF和ASP.
NET4.
ASP.
NETCore1.
0也可以在.
NETFramework4.
6上运行.
右边代表新的.
NETCore技术.
ASP.
NETCore1.
0和UWP运行在.
NETCore上.
还可以创建在.
NETCore上运行的控制台应用程序.
.
NETCore的一个组成部分是一个新的运行库CoreCLR.
这个运行库从ASP.
NETCore1.
0开始使用.
不使用CoreCLR运行库,.
NET也可以编译为本地代码.
UWP自动利用这个特性,这些.
NET应用程序编译为本地代码之后,在WindowsStore中提供.
也可以把其他.
NETCore应用程序以及运注意:Roslyn参见第18章.
C#语言的变化参见第Ⅰ部分中所有的语言章节,例如,只读属性参见第3章,nameof运算符和空值传播参见第8章,字符串插值参见第10章,异常过滤器参见第14章.
本书尽可能使用.
NETCore.
.
NETCore和NuGet包的更多信息参见本章后面的内容.
第1章.
NET应用程序体系结构9行在Linux上的应用程序编译为本地代码.
通用Windows应用程序共享运行库组件库编译器和图1-1在图1-1的下方,.
NETFramework4.
6和.
NETCore1.
0之间还有一些共享的内容.
运行库组件是共享的,如垃圾回收器的代码和RyuJIT(这是一个新的JIT编译器,把IL代码编译为本地代码).
垃圾回收器由CLR、CoreCLR和.
NETNative使用.
RyuJIT即时编译器由CLR和CoreCLR使用.
库可以在基于.
NETFramework4.
6和.
NETCore1.
0的应用程序之间共享.
NuGet包的概念帮助把这些库放在一个在所有.
NET平台上都可用的公共包上.
当然,所有这些技术都使用新的.
NET编译器平台.
1.
3.
1.
NETFramework4.
6.
NETFramework4.
6是.
NETFramework在过去10年不断增强的结果.
1.
2节讨论的许多技术都基于这个框架.
这个框架用于创建WindowsForms和WPF应用程序.
此外,ASP.
NET5可以在.
NETCore上运行,也可以在.
NETFramework4.
6上运行.
如果希望继续使用ASP.
NETWebForms,就应选择ASP.
NET4.
6和.
NETFramework4.
6.
ASP.
NET4.
6与4.
5版本相比,也有新特性,比如支持HTTP2(HTTP协议的一个新版本,参见第25章),用Roslyn编译器编译,以及异步模型绑定.
然而,不能把ASP.
NETWebForms切换到.
NETCore.
在目录%windows%\Microsoft.
NET\Framework\v4.
0.
30319下可以找到框架的库以及CLR.
可用于.
NETFramework的类组织在System名称空间中.
表1-2描述的名称空间提供了层次结构的思路.
表1-2名称空间说明System.
Collections这是集合的根名称空间.
子名称空间也包含集合,如System.
Collections.
Concurrent和System.
Collections.
GenericSystem.
Data这是访问数据库的名称空间.
System.
Data.
SqlClient包含访问SQLServer的类System.
Diagnostics这是诊断信息的根名称空间,如事件记录和跟踪(在System.
Diagnostics.
Tracing名称空间中)System.
Globalization该名称空间包含的类用于全球化和本地化应用程序System.
IO这是文件IO的名称空间,其中的类访问文件和目录,包括读取器、写入器和流System.
Net这是核心网络的名称空间,比如访问DNS服务器,用System.
Net.
Sockets创建套接字System.
Threading这是线程和任务的根名称空间.
任务在System.
Threading.
Tasks中定义第Ⅰ部分C#语言10(续表)名称空间说明System.
Web这是ASP.
NET的根名称空间.
在这个名称空间下面定义了许多子名称空间,如System.
Web.
UI、System.
Web.
UI.
WebControls和System.
Web.
HostingSystem.
Windows这是用于带有WPF的Windows桌面应用程序的根名称空间.
子名称空间有System.
Windows.
Shapes、System.
Windows.
Data和System.
Windows.
Documents1.
3.
2.
NETCore1.
0.
NETCore1.
0是新的.
NET,所有新技术都使用它,是本书的一大关注点.
这个框架是开源的,可以在http://www.
github.
com/dotnet上找到它.
运行库是CoreCLR库;包含集合类的框架、文件系统访问、控制台和XML等都在CoreFX库中.
.
NETFramework要求必须在系统上安装应用程序需要的特定版本,而在.
NETCore1.
0中,框架(包括运行库)是与应用程序一起交付的.
以前,把ASP.
NETWeb应用程序部署到共享服务器上有时可能有问题,因为提供程序安装了旧版本的.
NET.
这种情况已经一去不复返了.
现在可以同时提交应用程序和运行库,而不依赖服务器上安装的版本.
.
NETCore1.
0以模块化的方式设计.
该框架分成数量很多的NuGet包.
根据应用程序决定需要什么包.
添加新功能时,.
NETFramework就变得越来越大.
删除不再需要的旧功能是不可能的,比如添加了泛型集合类,旧的集合类就是不必要的.
.
NETRemoting被新的通信技术取代,或LINQtoSQL已经更新为EntityFramework.
删除某个功能,会破坏应用程序.
这不适用于.
NETCore,因为应用程序会发布它需要的部分框架.
目前.
NETCore的框架与.
NETFramework4.
6一样庞大.
然而,这可以改变,它可以变得更大,但因为模块化,其增长潜力不是问题.
.
NETCore已经如此之大,本书不可能包括每个类型.
在http://www.
github.
com/dotnet/corefx中可以看到所有的源代码.
例如,旧的非泛型集合类已被包含在.
NETCore中,使旧代码更容易进入新平台.
.
NETCore可以很快更新.
即使更新运行库,也不影响现有的应用程序,因为运行库与应用程序一起安装.
现在,微软公司可以增强.
NETCore,包括运行库,发布周期更短.
注意:一些新的.
NET类使用以Microsoft开头而不是以System开头的名称空间,比如用于EntityFramework的Microsoft.
Data.
Entity,用于新的依赖关系注入框架的Microsoft.
Extensions.
DependencyInjection.
注意:为了使用.
NETCore开发应用程序,微软公司创建了新的命令行实用程序.
NETCoreCommandLine(CLI).
第1章.
NET应用程序体系结构111.
3.
3程序集.
NET程序的库和可执行文件称为程序集(assembly).
程序集是包含编译好的、面向.
NETFramework的代码的逻辑单元.
程序集是完全自描述性的,它是一个逻辑单元而不是物理单元,这意味着它可以存储在多个文件中(动态程序集存储在内存中,而不是存储在文件中).
如果一个程序集存储在多个文件中,其中就会有一个包含入口点的主文件,该文件描述了程序集中的其他文件.
可执行代码和库代码使用相同的程序集结构.
唯一的区别是可执行的程序集包含一个主程序入口点,而库程序集不包含.
程序集的一个重要特征是它们包含的元数据描述了对应代码中定义的类型和方法.
程序集也包含描述程序集本身的程序集元数据,这种程序集元数据包含在一个称为"清单(manifest)"的区域中,可以检查程序集的版本及其完整性.
由于程序集包含程序的元数据,因此调用给定程序集中的代码的应用程序或其他程序集不需要引用注册表或其他数据源就能确定如何使用该程序集.
在.
NETFramework4.
6中,程序集有两种类型:私有程序集和共享程序集.
共享程序集不适用于UWP,因为所有代码都编译到一个本机映像中.
1.
私有程序集私有程序集一般附带在某个软件上,且只能用于该软件.
附带私有程序集的常见情况是,以可执行文件或许多库的方式提供应用程序,这些库包含的代码只能用于该应用程序.
系统可以保证私有程序集不被其他软件使用,因为应用程序只能加载位于主执行文件所在文件夹或其子文件夹中的私有程序集.
用户一般会希望把商用软件安装在它自己的目录下,这样软件包不存在覆盖、修改或在无意间加载另一个软件包的私有程序集的风险.
私有程序集只能用于自己的软件包,这样,用户对什么软件使用它们就有了更大的控制权.
因此,不需要采取安全措施,因为这没有其他商用软件用某个新版本的程序集覆盖原来私有程序集的风险(但软件专门执行怀有恶意的损害性操作的情况除外).
名称也不会有冲突.
如果私有程序集中的类正巧与另一个人的私有程序集中的类同名,是不会有问题的,因为给定的应用程序只能使用它自己的一组私有程序集.
因为私有程序集是完全自包含的,所以部署它的过程就很简单.
只需要把相应的文件放在文件系统的对应文件夹中即可(不需要注册表项),这个过程称为"0影响(xcopy)安装".
2.
共享程序集共享程序集是其他应用程序可以使用的公共库.
因为其他软件可以访问共享程序集,所以需要采取一定的保护措施来防止以下风险:名称冲突,指另一个公司的共享程序集实现的类型与自己的共享程序集中的类型同名.
因为客户端代码理论上可以同时访问这些程序集,所以这是一个严重的问题.
程序集被同一个程序集的不同版本覆盖——新版本与某些已有的客户端代码不兼容.
这些问题的解决方法是把共享程序集放在文件系统的特定子目录树中,称为全局程序集缓存(GlobalAssemblyCache,GAC).
与私有程序集不同,不能简单地把共享程序集复制到对应的文件夹第Ⅰ部分C#语言12中,而需要专门安装到缓存中.
有许多.
NET工具可以完成这个过程,并要求对程序集进行检查,在程序集缓存中设置一个小的文件夹层次结构,以确保程序集的完整性.
为了避免名称冲突,应根据私钥加密法为共享程序集指定一个名称(而对于私有程序集,只需要指定与其主文件名相同的名称即可).
该名称称为强名(strongname),并保证其唯一性,它必须由要引用共享程序集的应用程序来引用.
与覆盖程序集的风险相关的问题,可以通过在程序集清单中指定版本信息来解决,也可以通过同时安装来解决.
1.
3.
4NuGet包在早期,程序集是应用程序的可重用单元.
添加对程序集的一个引用,以使用自己代码中的公共类型和方法,此时,仍可以这样使用(一些程序集必须这样使用).
然而,使用库可能不仅意味着添加一个引用并使用它.
使用库也意味着一些配置更改,或者可以通过脚本来利用的一些特性.
这是在NuGet包中打包程序集的一个原因.
NuGet包是一个zip文件,其中包含程序集(或多个程序集)、配置信息和PowerShell脚本.
使用NuGet包的另一个原因是,它们很容易找到,它们不仅可以从微软公司找到,也可以从第三方找到.
NuGet包很容易在NuGet服务器http://www.
nuget.
org上获得.
在VisualStudio项目的引用中,可以打开NuGet包管理器(NuGetPackageManager,见图1-2),在该管理器中可以搜索包,并将其添加到应用程序中.
这个工具允许搜索还没有发布的包(包括预发布选项),定义应该在哪个NuGet服务器中搜索包.
图1-2第1章.
NET应用程序体系结构13因为.
NETCore是模块化的,所以所有应用程序(除了最简单的应用程序)都需要额外的NuGet包.
为了更容易找到包,本书使用.
NETCore构建的每个示例应用程序都显示了一个表格,列出需要添加的包和名称空间.
1.
3.
5公共语言运行库UWP(通用Windows平台)利用Native.
NET把IL编译成本地代码.
在所有其他场景中,使用.
NETFramework4.
6的应用程序和使用.
NETCore1.
0的应用程序都需要CLR(CommonLanguageRuntime,公共语言运行库).
然而,.
NETCore使用CoreCLR,而.
NETFramework使用CLR.
在CLR执行应用程序之前,编写好的源代码(使用C#或其他语言编写的代码)都需要编译.
在.
NET中,编译分为两个阶段:(1)将源代码编译为Microsoft中间语言(IntermediateLanguage,IL).
(2)CLR把IL编译为平台专用的本地代码.
IL代码在.
NET程序集中可用.
在运行时,JIT编译器编译IL代码,创建特定于平台的本地代码.
新的CLR和CoreCLR包括一个新的JIT编译器RyuJIT.
新的JIT编译器不仅比以前的版本快,还在用VisualStudio调试时更好地支持Edit&Continue特性.
Edit&Continue特性允许在调试时编辑代码,可以继续调试会话,而不需要停止并重新启动过程.
CLR还包括一个带有类型加载器的类型系统,类型加载器负责从程序集中加载类型.
类型系统中的安全基础设施验证是否允许使用某些类型系统结构,如继承.
创建类型的实例后,实例还需要销毁,内存也需要回收.
CLR的另一个功能是垃圾回收器.
垃圾回收器从托管堆中清除不再引用的内存.
第5章解释其工作原理和执行的时间.
CLR还负责线程的处理.
在C#中创建托管的线程不一定来自底层操作系统.
线程的虚拟化和管理由CLR负责.
注意:使用NuGet服务器中的第三方包时,如果一个包以后才能使用,就总是有风险.
还需要检查包的支持可用性.
使用包之前,总要检查项目的链接信息.
对于包的来源,可以选择Microsoftand.
NET,只获得微软公司支持的包.
第三方包也包括在Microsoftand.
NET部分中,但它们是微软公司支持的第三方包.
也可以让开发团队使用自己的NuGet服务器.
可以定义开发团队只允许使用自己服务器中的包.
注意:NuGet包管理器的更多信息参见第17章.
注意:如何在C#中创建和管理线程参见第21章和第22章.
第Ⅰ部分C#语言141.
3.
6.
NETNative.
NETNative是.
NET2015的一个新特性,它将托管程序编译成本地代码.
对于Windows应用程序,这会生成优化的代码,其启动时间可以缩短60%,内存的使用减少15%~20%.
最初,.
NETNative把UWP应用编译为本地代码,以部署到WindowsStore.
现在,.
NETNative将来也可以用于其他.
NETCore应用程序,不过它目前还不能用于.
NETCore1.
0版本中,但可用于.
NETCore的将来版本中.
可以把运行在Windows和Linux上的.
NETCore应用程序编译为本地代码.
当然,在每一个平台上需要不同的本地映像.
在后台.
NETNative共享C++优化器,以生成本地代码.
1.
3.
7Windows运行库从Windows8开始,Windows操作系统提供了另一种框架:Windows运行库(WindowsRuntime).
这个运行库由WUP(WindowsUniversalPlatform,Windows通用平台)使用,Windows8使用第1版,Windows8.
1使用第2版,Windows10使用第3版.
与.
NETFramework不同,这个框架是使用本地代码创建的.
当它用于.
NET应用程序时,所包含的类型和.
NET类似.
在语言投射的帮助下,Windows运行库可以用于JavaScript、C++和.
NET语言,它看起来像编程环境的本地代码.
不仅方法因区分大小写而行为不同;方法和类型也可以根据所处的位置有不同的名称.
Windows运行库提供了一个对象层次结构,它在以Windows开头的名称空间中组织.
这些类没有复制.
NETFramework的很多功能;相反,提供了额外的功能,用于在UWP上运行的应用程序.
如表1-3所示.
表1-3名称空间说明Windows.
ApplicationModel这个名称空间及其子名称空间(如Windows.
ApplicationModel.
Contracts)定义了类,用于管理应用程序的生命周期,与其他应用程序通信Windows.
DataWindows.
Data定义了子名称空间,来处理文本、JSON、PDF和XML数据Windows.
Devices地理位置、智能卡、服务设备点、打印机、扫描仪等设备可以用Windows.
Devices子名称空间访问Windows.
FoundationWindows.
Foundation定义了核心功能.
集合的接口用名称空间Windows.
Foundation.
Collections定义.
这里没有具体的集合类.
相反,.
NET集合类型的接口映射到Windows运行库类型Windows.
MediaWindows.
Media是播放、捕获视频和音频、访问播放列表和语音输出的根名称空间Windows.
Networking这是套接字编程、数据后台传输和推送通知的根名称空间Windows.
SecurityWindows.
Security.
Credentials中的类提供了密码的安全存储区;Windows.
Security.
Credentials.
UI提供了一个选择器,用于从用户处获得凭证Windows.
Services.
Maps这个名称空间包含用于定位服务和路由的类Windows.
Storage有了Windows.
Storage及其子名称空间,就可以访问文件和目录,使用流和压缩Windows.
SystemWindows.
System名称空间及其子名称空间提供了系统和用户的信息,也提供了一个启动其他应用程序的启动器Windows.
UI.
Xaml在这个名称空间中,可以找到很多用于用户界面的类型第1章.
NET应用程序体系结构151.
4Hello,World下面进入编码,创建一个Hello,World应用程序.
自20世纪70年代以来,BrianKernighan和DennisRitchie编写了TheCProgrammingLanguage一书,使用Hello,World应用程序开始学习编程语言就成为一个传统.
有趣的是,自C#发明以来,Hello,World的语法用C#6改变后,这一简单的程序第一次看起来非常不同.
创建第一个示例不借助于VisualStudio,而是使用命令行工具和简单的文本编辑器(如记事本),以便看到后台会发生什么.
之后,就转而使用VisualStudio,因为它便于编程.
在文本编辑器中输入以下源代码,并用.
cs作为扩展名(如HelloWorld.
cs)保存它.
Main()方法是.
NET应用程序的入口点.
CLR在启动时调用一个静态的Main()方法.
Main()方法需要放到一个类中.
这里的类称为Program,但是可以给它指定任何名字.
WriteLine是Console类的一个静态方法.
Console类的所有静态成员都用第一行中的using声明打开.
usingstaticSystem.
Console打开Console类的静态成员,所以不需要输入类名,就可以调用方法WriteLine()(代码文件Dotnet/HelloWorld.
cs):usingstaticSystem.
Console;classProgram{staticvoidMain(){WriteLine("Hello,World!
");}}如前所述,Hello,World的语法用C#6略加改变.
在C#6推出之前,usingstatic并不可用,只能通过using声明打开名称空间.
当然,下面的代码仍然适用于C#6(代码文件Dotnet/HelloWorld2.
cs):usingSystem;classProgram{staticvoidMain(){Console.
WriteLine("Hello,World!
");}}using声明可以减少打开名称空间的代码.
编写Hello,World程序的另一种方式是删除using声明,在调用WriteLine()方法时,给Console类添加System名称空间(代码文件Dotnet/HelloWorld3.
cs):classProgram{staticvoidMain(){System.
Console.
WriteLine("Hello,World!
");}}第Ⅰ部分C#语言16编写源代码之后,需要编译代码来运行它.
1.
5用.
NET4.
6编译对源文件运行C#命令行编译器(csc.
exe),就可以编译这个程序,如下所示:cscHelloWorld.
cs如果想使用csc命令在命令行上编译代码,就应该知道,.
NET命令行工具(包括csc)只有设置了某些环境变量后才可用.
根据安装.
NET(和VisualStudio)的方式,计算机可能设置了这些环境变量,也可能没有设置.
编译代码,生成一个可执行文件HelloWorld.
exe,在命令行上可以运行它.
也可以在Windows资源管理器中运行它,就像运行任何其他可执行文件一样.
试一试:>cscHelloWorld.
csMicrosoft(R)VisualC#Compilerversion1.
1.
0.
51109Copyright(C)MicrosoftCorporation.
Allrightsreserved.
>HelloWorldHelloWorld!
以这种方式编译可执行程序,会生成一个程序集,其中包含IL(中间语言)代码.
程序集可以使用中间语言反汇编程序(IntermediateLanguageDisassembler,ILDASM)工具读取.
如果运行ildasm.
exe,打开HelloWorld.
exe,会发现程序集包含一个Program类型和一个Main()方法,如图1-3所示.
双击树视图中的MANIFEST节点,显示程序集的元数据信息(如图1-4所示).
这个程序集会利用mscorlib程序集(因为Console类位于mscorlib程序集里)、一些配置和HelloWorld程序集的版本.
注意:如果没有设置环境变量,则有3个选择.
第一个选择是在调用csc可执行文件时添加路径.
它位于%ProgramFiles%\MsBuild\14.
0\Bin\csc.
exe.
如果安装了dotnet工具,则csc在%ProgramFiles%\dot.
net\bin\csc.
exe上.
第二个选择是在运行csc前,从命令提示符下运行批处理文件%MicrosoftVisualStudio2015%\Common7\vsvars32.
bat,其中%MicrosoftVisualStudio2015%是安装VisualStudio2015的文件夹.
第三个选择、也是最容易的方式,是使用VisualStudio2015命令提示符代替Windows命令提示符.
要在"开始"菜单中找到VisualStudio2015命令提示符,选择Programs|MicrosoftVisualStudio2015|VisualStudioTools.
VisualStudio2015命令提示符只是一个命令提示符窗口,它打开时会自动运行vsvars32.
bat.
第1章.
NET应用程序体系结构17图1-3图1-4双击Main()方法,显示该方法的IL代码(如图1-5所示).
不管编译Hello,World代码的什么版本,结果都是一样的.
都是调用mscorlib程序集中定义的System.
Console.
WriteLine方法,传递字符串,之后加载字符串Hello,World!
.
CLR的一个特性是JIT编译器.
运行该应用程序时,JIT编译器把IL代码编译为本地代码.
图1-51.
6用.
NETCoreCLI编译如果没有VisualStudio的帮助,使用新的.
NETCoreCLI(CommandLine,命令行)就需要做一些准备,才能编译应用程序.
下面看看编译Hello,World示例应用程序的新工具.
第Ⅰ部分C#语言181.
6.
1设置环境安装了VisualStudio2015和最新的更新包后,就可以立即启动CLI工具.
否则,就需要安装.
NETCore和CLI工具.
Windows、Linux和OSX的下载指令可以从http://dotnet.
github.
io获取.
在Windows上,不同版本的.
NETCore运行库以及NuGet包安装在用户配置文件中.
使用.
NET时,这个文件夹的大小会增加.
随着时间的推移,会创建多个项目,NuGet包不再存储在项目中,而是存储在这个用户专用的文件夹中.
这样做的优势在于,不需要为每个不同的项目下载NuGet包.
这个NuGet包下载后,它就在系统上.
因为不同版本的NuGet包和运行库都是可用的,所有的不同版本都存储在这个文件夹中.
不时地检查这个文件夹,删除不再需要的旧版本,可能很有趣.
安装.
NETCoreCLI工具,要把dotnet工具作为入口点来启动所有这些工具.
开始时:>dotnet会看到,dotnet工具的所有不同选项都可用.
repl(read、eval、print、loop)命令适合于学习和测试简单的C#特性,而无须创建程序.
用dotnet工具启动repl:>dotnetrepl这会启动一个交互式repl会话.
使用一个变量,可以给Hello,World输入以下语句:>usingstaticSystem.
Console;>varhello="Hello,World!
";>WriteLine(hello);输入最后一条语句后,输出就是Hello,World!
字符串.
dotnetrepl命令不可用于dotnet工具的Preview2版本,但在将来可以作为其扩展用于该工具.
1.
6.
2构建应用程序dotnet工具提供了一种简单的方法来创建Hello,World应用程序.
创建一个新的目录HelloWorldApp,用命令提示符进入这个目录.
然后输入如下命令:>dotnetnew这个命令创建一个Program.
cs文件(其中包括Hello,World应用程序的代码)、一个NuGet.
config文件(定义了应该加载NuGet包的NuGet服务器)和新的项目配置文件project.
json.
创建的项目配置文件是project.
json.
这个文件采用JavaScriptObjectNotation(JSON)格式,定义了框架应用程序信息,如版本、描述、作者、标签、依赖的库和应用程序支持的框架.
生成的项目配置文件如下面的代码片段所示(代码文件HelloWorldApp/project.
json):{"version":"1.
0.
0-*","buildOptions":{注意:使用dotnetnew,还可以创建库和ASP.
NETWeb应用程序所需要的初始文件(使用选项--type).
也可以选择其他编程语言,如F#和VisualBasic(使用选项--lang).
第1章.
NET应用程序体系结构19"emitEntryPoint":true},"dependencies":{"NETStandard.
Library":"1.
0.
0-*"},"frameworks":{"netstandardapp1.
5":{"imports":"dnxcore50"}},"runtimes":{"ubuntu.
14.
04-x64":{},"win7-x64":{},"win10-x64":{},"osx.
10.
10-x64":{},"osx.
10.
11-x64":{}}}通过compilationOptions设置来设置emitEntryPoint.
如果把Main()方法创建为程序的入口点,这就是必要的.
这个Main()方法在运行应用程序时调用.
库不需要这个设置.
对于依赖关系部分,可以添加程序的所有依赖项,如需要编译程序的额外NuGet包.
默认情况下,NetStandard.
Library添加为一个依赖项.
NetStandard.
Library是一个引用的NuGet包,这个包引用了其他NuGet包.
有了它,就可以避免添加很多其他的包,如Console类的System.
Console、泛型集合类的System.
Collections等.
NetStandard.
Library1.
0是一个标准,定义了所有.
NET平台必须支持的一组程序集,在网站https://github.
com/dotnet/corefx/blob/master/Documentation/project-docs/standard-platform.
md上,可以找到一长串.
NET1.
0中的程序集及其版本号,以及.
NET标准的1.
1、1.
2、1.
3和1.
4版本中添加的程序集.
NetStandard.
Library1.
0有一个依赖项,可以支持.
NETFramework4.
5.
2及以上版本(对.
NET4、4.
5、4.
5.
1的支持结束于2016年1月)、.
NETCore1.
0、UWP10.
0和其他.
NETFramework,如WindowsPhoneSilverlight8.
0、Mono和Mono/Xamarin.
对1.
3版本的修改有限支持.
NET4.
6、.
NETCore1.
0、UWP10.
0和Mono/Xamarin平台.
1.
4版本有限支持.
NET4.
6.
1、.
NETCore1.
0和Mono/Xamarin平台,但版本越新,可用的程序集列表就越大.
project.
json中的frameworks部分列出了应用程序支持的.
NETFramework.
默认情况下,应用程序只为.
NETCore1.
0构建为netstandardapp1.
5moniker指定的名称.
netstandardapp1.
5与.
NETCore1.
0所构建的应用程序一起使用.
通过库可以使用netstandard1.
0moniker.
这允许在.
NETCore应用程序和使用.
NETFramework的应用程序中使用库.
netstandardapp1.
5内的imports部分引用旧名称dnxcore50,该旧名称映射到新名字上.
这允许使用仍在使用旧名称的包.
.
NETCore是框架的新开源版本,可用于Windows、Linux和OSX.
应该支持的运行库需要添加到runtimes部分.
前面的代码片段显示了对UbuntuLinux发行版、Windows7(也允许在Windows8上运行应用程序)、Windows10和OSX的支持.
第Ⅰ部分C#语言20添加字符串net46,为.
NETFramework4.
6构建程序:"frameworks":{"netstandardapp1.
5":{}"net46":{}}给frameworks部分添加net46,就不再支持非Windows运行库,因此需要删除这些运行库.
还可以添加额外的元数据,比如描述、作者信息、标签、项目和许可URL:"version":"1.
0.
0-*","description":"HelloWorldSampleAppforProfessionalC#","authors":["ChristianNagel"],"tags":["Sample","Hello","Wrox"],"projectUrl":"http://github.
com/professionalCSharp/","licenseUrl":"",给project.
json文件添加多个框架时,可以在frameworks下面的dependencies部分中为每个框架指定专门的依赖项.
dependencies部分中指定的依赖项,若处于frameworks部分所在的层次上,就指定了所有框架共同的依赖项.
有了项目结构后,就可以使用如下命令下载应用程序的所有依赖项:>dotnetrestore此时,命令提示符定位在project.
json文件所在的目录.
这个命令会下载应用程序所需要的所有依赖项,即project.
json文件中定义的项.
指定版本1.
0.
0-*,会得到版本1.
0.
0,*表示可用的最新版本.
在project.
lock.
json文件中,可以看到检索了什么NuGet包的哪个版本,包括依赖项的依赖项.
记住,包存储在用户专门的文件夹中.
要编译应用程序,启动命令dotnetbuild,输出如下——为.
NETCore1.
0和.
NETFramework4.
6编译:>dotnetbuildCompilingHelloWorldAppfor.
NETStandardApp,Version=1.
5"Compilationsucceeded.
0Warning(s)0Error(s)Timeelapsed00:00:02.
6911660CompilingHelloWorldAppfor.
NETFramework,Version=v4.
6Compilationsucceeded.
0Warning(s)0Error(s)Timeelapsed00:00:03.
3735370编译过程的结果是bin/debug/[netstandardapp1.
5|net46]文件夹中包含Program类的IL代码的程序集.
如果比较.
NETCore与.
NET4.
6的编译结果,会发现一个包含IL代码和.
NETCore的DLL,和包含IL代码和.
NET4.
6的EXE.
为.
NETCore生成的程序集有一个对System.
Console程序集的依赖项,而.
NET4.
6程序集在mscorlib程序集中找到Console类.
还可以使用下面的命令行把程序编译成本地代码:第1章.
NET应用程序体系结构21>dotnetbuild--native编译为本地代码,会加快应用程序的启动,消耗更少的内存.
本地编译过程会把应用程序的IL代码以及所有依赖项编译为单一的本地映像.
别指望.
NETCore的所有功能都可用于编译为本地代码,但是随着时间的推移,微软公司的继续发展,越来越多的应用程序可以编译为本地代码.
要运行应用程序,可以使用dotnet命令:>dotnetrun要使用特定版本的框架启动应用程序,可以使用-framework选项.
这个框架必须用project.
json文件配置:>dotnetrun--frameworknet46启动bin/debug目录中的可执行程序,也可以运行应用程序.
1.
6.
3打包和发布应用程序使用dotnet工具还可以创建一个NuGet包,发布应用程序,以进行部署.
命令dotnetpack创建了可以放在NuGet服务器上的NuGet包.
开发人员现在可以使用下面的命令来引用包:>dotnetpack用HelloWorldApp运行这个命令,会创建文件HelloWorldApp.
1.
0.
0.
nupkg,其中包含用于所有支持框架的程序集.
NuGet包是一个ZIP文件.
如果用zip扩展名重命名该文件,就可以轻松地查看它的内容.
对于示例应用程序,创建了两个文件夹dnxcore500和net46,其中包含各自的程序集.
文件HelloWorldApp.
nuspec是一个XML文件,它描述了NuGet包,列出了支持框架的内容,还列出了安装NuGet包之前所需要的程序集依赖项.
要发布应用程序,还需要在目标系统上有运行库.
发布所需要的文件可以用dotnetpublish命令创建:注意:前面是在Windows上构建和运行Hello,World应用程序,而dotnet工具在Linux和OSX上的工作方式是相同的.
可以在这两个平台上使用相同的dotnet命令.
在使用dotnet命令之前,只需要准备基础设施:为UbuntuLinux使用sudo实用工具,在OSX上安装一个PKG包,参见http://dotnet.
github.
安装好.
NETCoreCLI后,就可以通过本小节介绍的方式使用dotnet工具——只是.
NETFramework4.
6是不可用的.
除此之外,可以恢复NuGet包,用dotnetrestore、dotnetbuild和dotnetrun编译和运行应用程序.
本书的重点是Windows,因为VisualStudio2015提供了一个比其他平台更强大的开发平台,但本书的许多代码示例是基于.
NETCore的,所以也能够在其他平台上运行.
还可以使用VisualStudioCode(一个免费的开发环境),直接在Linux和OSX上开发应用程序,参见1.
8节,了解VisualStudio不同版本的更多信息.
第Ⅰ部分C#语言22>dotnetpublish使用可选参数,可以指定用于发布的特定运行库(选项-r)或不同的输出目录(选项-o).
在Windows系统上运行这个命令后,会创建win7-x64文件夹,其中包含目标系统上需要的所有文件.
注意,在.
NETCore中包含运行库,因此不管安装的运行库是什么版本都没有关系.
1.
7应用程序类型和技术可以使用C#创建控制台应用程序,本章的大多数示例都是控制台应用程序.
对于实际的程序,控制台应用程序并不常用.
使用C#创建的应用程序可以使用与.
NET相关的许多技术.
本节概述可以用C#编写的不同类型的应用程序.
1.
7.
1数据访问在介绍应用程序类型之前,先看看所有应用程序类型都使用的技术:数据访问.
文件和目录可以使用简单的API调用来访问,但简单的API调用对于有些场景而言不够灵活.
使用流API有很大的灵活性,流提供了更多的特性,例如加密或压缩.
阅读器和写入器简化了流的使用.
所有可用的不同选项都包含在第23章中.
也可能以XML或JSON格式序列化完整的对象.
第27章讨论了这些选项.
为了读取和写入数据库,可以直接使用ADO.
NET(参见第37章);也可以使用抽象层:ADO.
NETEntityFramework(参见第38章).
EntityFramework提供了从对象层次结构到数据库关系的映射.
ADO.
NETEntityFramework进行了若干次迭代.
EntityFramework的不同版本值得讨论,以很好地理解NuGet包的优点.
还要了解不应继续使用EntityFramework的哪些部分.
表1-4描述了EntityFramework的不同版本和每个版本的新特性.
表1-4EntityFramework说明1.
0.
NET3.
5SP1可用.
这个版本提供了通过XML文件把表映射到对象的映射4.
0在.
NET4中,EntityFramework从第1版跳到第4版4.
1支持代码优先4.
2修复错误4.
3添加了迁移5.
0与.
NET4.
5一起发布,提供性能改进,支持新的SQLServer特性6.
0移动到NuGet包中7.
0完全重写,也支持NoSQL、也运行在Windows应用程序上下面介绍一些细节.
EntityFramework最初发布为.
NETFramework类的一部分,和.
NETFramework一起预装.
EntityFramework1是.
NET3.
5第一个服务包的一部分,它有一个特性更新:.
NET3.
5Update1.
第1章.
NET应用程序体系结构23第2版有许多新特性,因此决定和.
NET4一起跳到第4版.
之后,EntityFramework以比.
NETFramework更快的节奏发布新版本.
要得到EntityFramework的更新版本,必须把一个NuGet包添加到应用程序中(版本4.
1、4.
2、4.
3).
这种方法有一个问题.
已经通过.
NETFramework发布的类必须用以前的方式使用.
只有新添加的功能,如代码优先,用NuGet包添加.
EntityFramework5.
0与.
NET4.
5一起发布.
其中的一些类附带在预装的.
NETFramework中,而附加的特性是NuGet包的一部分.
NuGet包也允许给EntityFramework5.
0和.
NET4.
0应用程序安装NuGet包.
然而在现实中,EntityFramework5.
0添加到.
NET4.
0项目中时,(通过脚本)决定的包就是EntityFramework4.
4,因为一些类型必须属于.
NET4.
5,而不是.
NET4.
下一个版本的EntityFramework解决了这个问题,它把所有EntityFramework类型移动到NuGet包中;忽略框架本身附带的类型.
这允许同时使用Framework6.
0与旧版本,而不会局限于Framework4.
5.
为了不与框架的类冲突,有些类型移到不同的名称空间中.
对此,ASP.
NETWebForms的一些特性有一个问题,因为它们使用了EntityFramework的原始类,而这些类映射到新类没有那么轻松.
在发布不同版本的过程中,EntityFramework提供了不同的选项,把数据库表映射到类.
前两个选项是DatabaseFirst和ModelFirst.
在这两个选项中,映射是通过XML文件完成的.
XML文件通过图形设计器表示,可以把实体从工具箱拖动到设计器中,进行映射.
在4.
1版本中,添加了通过代码来映射的选项:代码优先(CodeFirst).
代码优先并不意味着数据库不能事先存在.
两者都是可能的:数据库可以动态地创建,数据库也可以在编写代码之前存在.
使用代码优先,不通过XML文件进行映射.
相反,属性或流利的API可以以编程方式定义映射.
EntityFrameworkCore1.
0是EntityFramework的完全重新设计,新名称反映了这一点.
代码需要更改,把应用程序从EntityFramework的旧版本迁移到新版本.
旧的映射变体,如DatabaseFirst和ModelFirst已被删除,因为代码优先是更好的选择.
完全重新设计也支持关系数据库和NoSQL.
AzureTableStorage现在是可以使用EntityFramework的一个选项.
1.
7.
2Windows桌面应用程序为了创建Windows桌面应用程序,可以使用两种技术:WindowsForms和WindowsPresentationFoundation.
WindowsForms包含包装本地Windows控件的类;它基于像素图形.
WindowsPresentationFoundation(WPF)是较新的技术,基于矢量图形.
WPF在构建应用程序时利用了XAML.
XAML是指可扩展的应用程序标记语言(ExtensibleApplicationMarkupLanguage).
这种在微软环境中创建应用程序的方式在2006年引入,是.
NETFramework3.
0的一部分.
.
NET4.
5给WPF引入了新特性,如功能区控件和实时塑造.
XAML是用来创建表单的XML声明,表单代表WPF应用程序的所有可视化方面和行为.
虽然可以以编程方式使用WPF应用程序,但WPF是迈向声明性编程方向的一步,软件业正转向这个方向.
声明性编程意味着,不使用C#、VisualBasic或Java等编译语言通过编程方式创建对象,而是通过XML类型的编程方式声明一切对象.
第29章介绍了XAML(使用XMLPaperSpecification、WindowsWorkflowFoundation和WindowsCommunicationFoundation).
第30章涵盖了XAML样式和资源.
第34章提供控件、布局和数据绑定的细节.
打印和创建文档是WPF的另一个重要方面,参见第35章.
WPF的未来是什么UWP是用于未来的新应用程序的UI平台吗UWP的优点是也支持移动设备.
只要一些用户没有升级到Windows10,就需要支持旧的操作系统,如Windows7.
UWP第Ⅰ部分C#语言24应用程序不在Windows7/8上运行.
可以使用WPF.
如果还愿意支持移动设备,最好共享尽可能多的代码.
通过支持MVVM模式,可以使用尽可能多的通用代码,通过WPF和UWP创建应用程序.
这种模式参见第31章.
1.
7.
3UWPUWP(UniversalWindowsPlatform,通用Windows平台)是微软公司的一个战略平台.
使用UWP创建Windows应用程序时,只能使用Windows10和Windows的更新版本,但不限于Windows的桌面版本.
使用Windows10有很多不同的选择,如Phone、Xbox、SurfaceHub、HoloLens和IoT.
还有一个适用于所有这些设备的API!
一个适用于所有这些设备的API是的!
每个设备系列都可以添加自己的软件开发工具包(SoftwareDevelopmentKit,SDK),来添加不是API的一部分、但对所有设备可用的功能.
添加这些SDK不会破坏应用程序,但需要以编程方式检查,这种SDK中的API在运行应用程序的平台上是否可用.
根据需要区分的API调用数,代码可能变得混乱,依赖注入可能是更好的选择.
可以决定什么设备系列支持应用程序.
并不是所有的设备系列都可用于每个应用程序.
在Windows10后,会有新版本的Windows吗Windows11尚未计划.
对于Windows应用程序(也称为Metro应用程序、WindowsStore应用程序、Modern应用程序和UWP),应针对Windows8或Windows8.
1.
Windows8应用程序通常也在Windows8.
1上运行,但Windows8.
1应用程序不在Windows8上运行.
这是非常不同的.
为UWP创建应用程序时,目标版本是10.
0.
10130.
0,定义了可用的最低版本和要测试的最新版本,并假设它在未来版本上运行.
根据可以为应用程序使用的功能,以及希望用户拥有的版本,可以决定要支持的最低版本.
个人用户通常会自动更新版本;企业用户可能会坚持使用旧版本.
运行在UWP上的Windows应用程序利用了Windows运行库和.
NETCore.
讨论这些应用程序类型的最重要部分是第32章和第33章.
1.
7.
4SOAP服务和WCFWindowsCommunicationFoundation(WCF)是一个功能丰富的技术,旨在取代在WCF以前可用的通信技术,它为基于标准的Web服务使用的所有特性提供基于SOAP的通信,如安全性、事务、双向和单向通信、路由、发现等.
WCF允许一次性构建服务,然后在一个配置文件中进行更改,让这个服务用于许多方面(甚至在不同的协议下).
WCF是一种强大而复杂的方式,用来连接完全不同的系统.
第44章将介绍它.
1.
7.
5Web服务和ASP.
NETWebAPIASP.
NETWebAPI是非常容易通信的一个选项,能满足分布式应用程序90%以上的需求.
这项技术基于REST(RepresentationalStateTransfer),它定义了无状态、可伸缩的Web服务的指导方针和最佳实践.
注意:第31章讨论了依赖注入,以及对基于XAML的应用程序有用的其他模式.
第1章.
NET应用程序体系结构25客户端可以接收JSON或XML数据.
JSON和XML也可以格式化来使用OpenData规范(OData).
这个新API的功能是便于通过JavaScript和UWP使用Web客户端.
ASP.
NETWebAPI是创建微服务的一个好方法.
创建微服务的方法定义了更小的服务,可以独立运行和部署,可以自己控制数据存储.
ASP.
NET5是ASP.
NETWebAPI的旧版本,从ASP.
NETMVC分离而来,现在与ASP.
NETMVC6合并,使用相同的类型和特征.
1.
7.
6WebHooks和SignalR对于实时Web功能以及客户端和服务器端之间的双向通信,可以使用的ASP.
NET技术是WebHooks和SignalR.
只要信息可用,SignalR就允许将信息尽快推送给连接的客户.
SignalR使用WebSocket技术,在WebSocket不可用时,它可以回退到基于拉的通信机制.
WebHooks可以集成公共服务,这些服务可以调用公共ASP.
NETWebAPI服务.
WebHooks技术从GitHub或Dropbox和其他服务中接收推送通知.
1.
7.
7Windows服务Web服务无论是通过WCF完成还是通过ASP.
NETWeb服务完成,都需要一个主机才能运行.
IIS(InternetInformationServer,互联网信息服务器)通常是一个很好的选择,因为它提供了所有的服务,但它也可以是自定义程序.
使用自定义选项创建一个后台进程,在运行Windows时启动的是Windows服务.
这个程序设计为在基于WindowsNT内核的操作系统的后台运行.
希望程序持续运行,做好响应事件的准备,而不是让用户显式地启动时,就可以使用服务.
一个很好的例子是Web服务器上的WorldWideWeb服务,它监听来自客户端的Web请求.
很容易用C#编写服务.
.
NETFramework基类在System.
ServiceProcess名称空间中,处理与服务相关的许多样板任务.
此外,VisualStudio.
NET允许创建C#Windows服务(Service)项目,它给基本Windows服务使用C#源代码.
第39章探讨了如何编写C#Windows服务.
1.
7.
8Web应用程序最初引入ASP.
NET1,从根本上改变了Web编程模型.
ASP.
NET5是新的主要版本,允许使用.
NETCore提高性能和可伸缩性.
这个新版本也可以在Linux系统上运行,这个需求很高.
在ASP.
NET5中,不再包含ASP.
NETWebForms(它仍然可以使用,在.
NET4.
6中更新),所以本书关注现代技术ASP.
NETMVC6,它是ASP.
NET5的一部分.
ASP.
NETMVC基于著名的MVC(模型-视图-控制器)模式,更容易进行单元测试.
它还允许把编写用户界面代码与HTML、CSS、JavaScript清晰地分离,它只在后台使用C#.
注意:ASP.
NETWebAPI和微服务的更多信息参见第42章.
第Ⅰ部分C#语言261.
7.
9MicrosoftAzure现在,在考虑开发图片时不能忽视云.
虽然没有专门的章节讨论云技术,但在本书的几章中都引用了MicrosoftAzure.
MicrosoftAzure提供了软件即服务(SoftwareasaService,SaaS)、基础设施即服务(InfrastructureasaService,IaaS)和平台即服务(PlatformasaService,PaaS).
下面介绍这些MicrosoftAzure产品.
1.
SaaSSaaS提供了完整的软件,不需要处理服务器的管理和更新等.
Office365是一个SaaS产品,它通过云产品使用电子邮件和其他服务.
与开发人员相关的SaaS产品是VisualStudioOnline,它不是在浏览器中运行的VisualStudio.
VisualStudioOnline是云中的TeamFoundationServer,可以用作私人代码库,跟踪错误和工作项,以及构建和测试服务.
2.
IaaS另一个服务产品是IaaS.
这个服务产品提供了虚拟机.
用户负责管理操作系统,维护更新.
当创建虚拟机时,可以决定不同的硬件产品,从共享核心开始,到最多32核(这个数据会很快改变).
32核、448GB的RAM和6144GB的本地SSD属于计算机的"G系列",命名为哥斯拉.
对于预装的操作系统,可以在Windows、WindowsServer、Linux和预装了SQLServer、BizTalkServer、SharePoint和Oracle的操作系统之间选择.
作者经常给一周只需要几个小时的环境使用虚拟机,因为虚拟机按小时支付费用.
如果想尝试在Linux上编译和运行.
NETCore程序,但没有Linux计算机,在MicrosoftAzure上安装这样一个环境是很容易的.
3.
PaaS对于开发人员来说,MicrosoftAzure最相关的部分是PaaS.
可以为存储和读取数据而访问服务,使用应用程序服务的计算和联网功能,在应用程序中集成开发者服务.
为了在云中存储数据,可以使用关系数据存储SQLDatabase.
SQLDatabase与SQLServer的本地版本大致相同.
也有一些NoSQL解决方案,例如,DocumentDB存储JSON数据,Storage存储blob(如图像或视频)和表格数据(这是非常快的,提供了大量的数据).
Web应用程序可以用于驻留ASP.
NETMVC解决方案,API应用程序可以用来驻留ASP.
NETWebAPI服务.
VisualStudioOnline是开发者服务(DeveloperService)产品的一部分.
在这里也可以找到VisualStudioApplicationInsights.
它的发布周期更短,对于获得用户如何使用应用程序的信息越来越重要.
Hostinger 商家我们可能一些新用户不是太熟悉,因为我们很多新人用户都可能较多的直接从云服务器、独立服务器起步的。而Hostinger商家已经有将近十年的历史的商家,曾经主做低价虚拟主机,也是比较有知名度的,那时候也有接触过,不过一直没有过多的使用。这不这么多年过去,Hostinger商家一直比较稳妥的在运营,最近看到这个商家在改版UI后且产品上也在活动策划比较多。目前Hostinger在进...
legionbox怎么样?legionbox是一家来自于澳大利亚的主机销售商,成立时间在2014年,属于比较老牌商家。主要提供VPS和独立服务器产品,数据中心包括美国洛杉矶、瑞士、德国和俄罗斯。其中VPS采用KVM和Xen架构虚拟技术,硬盘分机械硬盘和固态硬盘,系统支持Windows。当前商家有几款大硬盘的独立服务器,可选美国、德国和瑞士机房,有兴趣的可以看一下,付款方式有PAYPAL、BTC等。...
官方网站:点击访问青云互联官网优惠码:五折优惠码:5LHbEhaS (一次性五折,可月付、季付、半年付、年付)活动方案:的套餐分为大带宽限流和小带宽不限流两种套餐,全部为KVM虚拟架构,而且配置都可以弹性设置1、洛杉矶cera机房三网回程cn2gia 洛杉矶cera机房  ...