`
king_tt
  • 浏览: 2083314 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

WPF企业内训全程实录

 
阅读更多

一. 摘要

  圣殿骑士由于工作和项目需要,所以对一些技术进行了较为深入的研究,之前在整个公司做过一些技术专场的培训,由于每次时间较短且人员较多的关系,没能讲得很透彻。一直都想以文字的形式把这些培训细节写出来,但是发现进度确实很慢,所以先来几篇宏观的讲解,希望能起到“授人与鱼也授人以渔”的效果。今天我们就来分享一下WPF内训之旅,这篇文章以WPF培训为主线,中间贯穿了一些其他技术和使用心得。其他培训专题诸如“OO到设计模式”、“WCF基础到企业应用“Silverlight基础到企业应用及优化”随后也会奉上,热诚和大家互相学习,如果有讲得不妥之处,也希望大家能够多多指点!

二. 本文提纲

· 1.摘要

· 2.本文提纲

· 3.简要介绍

· 4.WPF介绍

· 5.WPF基础

· 6.WPF工具

· 7.WPF开发模式

· 8.WPF团队协作

· 9.了解并使用MVVM框架

· 10.自己开发MVVM框架

· 11.其他技术引入

· 12.WPF项目及性能优化

· 13.部署与更新

· 14.总结

· 15.详细技术索引

三. 简要介绍

关于如何做好一个专题的培训,圣殿骑士也有一些自己的看法,我觉得如果想要一个培训起到良好的效果,得注意以下几个方面:

1,了解受众:首先要确定培训的受众,他们是直接的受益者,所以你必须得了解他们的知识背景,这样才能合理把要讲的知识插入到他们各自的知识树上去,否则效果就会大打折扣。

2,来龙去脉:不管讲什么技术,首先得介绍这门技术的历史渊源、来龙去脉、市场前景,因为只有介绍了这些,才会使受众仔细聆听且能够跟随你的思路往下走,这也是比较关键的一环。

3,把握联系:我们要讲的这门技术往往不可能单独存在,它或多或少和之前使用的技术有一些联系,所以在讲解过程中适当引入之前的技术会起到很好的效果,并且在项目中,它也不可能单独存在。

4,大道至简:必须从基础讲起,从一个”Hello World“讲起,因为只有用大众化的思维来阐述问题,才会引起大众的共鸣,这同时也体现了一些原则,比如大道至简、深入浅出、先易后难。之后就开始不断深入浅出的讲解各知识点细节,最好以理论+Demo的形式,这样收到的效果才会达到或超过预期。

5,工具使用:对于一门技术,或多或少都有适合它的工具,这些工具不仅能提高开发效率,同时也是更好深入学习该技术的一个前提,所以合理使用工具也是一个比较重要的方面。

6,真实项目:前面讲了来龙去脉,讲了基础知识以及与其他技术的区别和联系,同时也讲了开发工具,那么这个时候就需要引入最重要的关注点——如何把之前讲过的各个方面关联起来,让它们作用在真实项目当中,一般最容易接受的当属简单页面+CRUD操作。

  下面这幅图是我在半年前写的一份PPT,因为公司要求用英文表述,所以写的很简约,这也怪圣殿骑士英文不好:-D,表达不像中文那样灵活自如,不过大家可以将就看一下大纲(PPT和代码在后面的文章中提供下载,暂时还没找到提供下载的地方):

2010-10-21 17-08-32

  因为上面的PPT基本涵盖了WPF的所有重要知识点,所以得为每一个知识点准备相关的Demo,只有这样才能把每个知识点完全讲透,否则只能起到云里雾里、不知所云的效果。如下便是与之配套的Demo截图:

2010-10-21 16-54-49

上面的代码包中主要包括:

WPFBasic:主要讲解WPF的基础概念,涵盖了WPF的方方面面。

WPFPatterns:强调Presentation模式的重要性,主要包括MVC/MVP/MVV以及一些MVVM的框架。

WPFProject:具体项目中如何把握,如何引用之前的技术和经验。

WPFTools:一门技术都有与之相应的开发、管理、协助工具,WPF也不例外。

WPF.PPT:这里是一些简单的介绍,熟悉的可以略过。

  这些Demo主要来源于两个方面,一是自己写了一些;二是改编了网络上的一些素材;如果大家仔细看,可以发现它涵盖了WPF的方方面面,并且对重点和难点也做了区别对待。

四. WPF介绍

1,概念引入

http://images.cnblogs.com/cnblogs_com/zenghongliang/WindowsLiveWriter/3cfdd94adeea_E606/netframwork_2.png

  Windows APIWindows Presentation Foundation (WPF) 是新一代显示系统,用于生成能带给用户震撼视觉体验的 Windows 客户端应用程序。使用 WPF,您可以创建广泛的独立应用程序以及浏览器承载的应用程序。 WPF 的核心是一个与分辨率无关并且基于向量的呈现引擎(这样就可以保证图像和影像具有高清晰度),旨在利用现代图形硬件的优势。WPF 通过一整套应用程序开发功能扩展了这个核心,这些功能包括可扩展应用程序标记语言 (XAML)、控件、数据绑定、布局、二维和三维图形、动画、样式、模板、文档、媒体、文本和版式。WPF 最先包含在如下图的 Microsoft .NET Framework 3.0中,它使您能够生成融入了 .NET Framework 类库的其他元素的应用程序(因为WPF包含在.NET Framework 3.0 里面,所以我们这里不列出3.5和4.0的框架图)。

2,历史渊源

微软在1983年春季就宣布开始研究开发Windows,到现在已经有27年的历史,这27年来,微软官方主力推行的编程语言与API有四个主要阶段:

  • 1983~1991年:C搭配Windows API。当时的程序员是很少的,并且开发一个项目也比较的不容易。

  • 1992~2001年:这段时期C++搭配MFC库。在历史上MFC是最多人用的Windows编程方法。但此后MFC技术也逐渐退出了历史的舞台。

  • 2002~2006年:(C#、VB以及其他语言)+Windows Form框架。这段期间IT技术的焦点是在Web上,所以虽然大家都在用.NET,但真正的主角是ASP.NET,而不是Windows Forms。Windows Forms还没等熬出头,WPF就出现了。Windows Forms注定会是历史中“最少人使用的微软开发技术”。Windows Forms其实是不错的技术,在很多方面都做得挺不错,比如在UI上、图形编程上、开发效率上、稳定性上都做得很让人敬佩,但是我们最后看到的结果却是大家没有引起足够的重视,很多人更偏向于用Delphi和MFC,对Windows Forms却视而不见,所以造成的最后结果就是Windows Forms生不逢时。

  • 2007~现在 :2007年1月30日,Windows Vista正式全球同步发布。它之所以能实现那么绚丽的效果,最关键的一点就是其内在也使用了Windows Presentation Foundation(WPF)类似的技术,所以带来的震撼视觉效果和用户体验使Vista的效果如此绚丽,虽然Vista在后来最终成为了一个败笔,但它为 Windows 7打下了坚实的继承。后台语言(C#、VB以及其他语言)+XAML构成的WPF。你可能觉得很奇怪,微软为何释出两个作用相似,却不同且不相容的.NET API。因为时代的改进,用户对视觉感受需求不断提高。因为WPF支持硬件加速、精确颜色、浮点坐标、动画实现、三维、视频感受等要求提高。而传统的 Winform 是到不到这些效果的。

3,技术更替

http://images.cnblogs.com/cnblogs_com/zenghongliang/WindowsLiveWriter/3cfdd94adeea_E606/image_12.png

  旧的事物迟早会退出历史舞台,新的生命会经过曲折的里程登上王座。从图像界面的出现那一刻起,用户界面(UI)就进入了一个特殊的历史时期。在随后几年里,出现了很多具有历史意义的界面风格。现在,经典的Windows窗口风格已经存在了10多年,即使是深受用户喜爱的Windows XP风格也已出现五年有余。无疑大家与我一样,期待着全新视觉界面的出现。另一方面,当今计算机处理芯片飞速发展,特别是显示芯片,显示卡几乎成为了一台微型的计算机。但是,其强大的处理能力却没有得到充分的应用。目前,显示卡GPU(Graphics Processing Unit)的处理能力大多只应用在游戏和多媒体领域。为了给用户提供最强的体验,满足不断提高的用户视觉需求,Windows Vista引入了全新的图形子系统——WPF。她能充分利用显示卡的处理能力提供给用户最绚的视觉效果。

  在Windows Vista出现之前,Windows平台的图形系统主要有:GDI、GDI+、Direct3D。其中,GDI的应用领域最为广泛。GDI图形系统已经形成了很多年并且已经逐渐形成了自己的一套开发体系。它提供2D图形处理、文本处理,以及有限的图像处理功能。虽然在一些显示卡上支持部分的GDI加速,但是其效果与现在的Direct3D相比还是很弱小。GDI+开始出现是在2001年,它引入了2D图形的反走样、浮点数坐标、渐变以及单个象素的 Alpha支持。它几乎支持所有的常用图像格式。但是,GDI+没有任何加速功能(全部是用软件实现)。

4,核心框架

http://images.cnblogs.com/cnblogs_com/zenghongliang/WindowsLiveWriter/3cfdd94adeea_E606/image_10.png

  如右图,在Windows Vista和Windows 7中,GDI、GDI+和WPF并行存在。但是,WPF所有的操作都不依赖于GDI和GDI+,而是间接依赖于强大的Direct3D。右图中的标示为暗红色的是WPF的三大核心组件,其中milcore组件,它的职责是完成与Direct3D的交互。并且出于效率和安全考虑,milcore由非托管代码实现。WPF 中的所有显示是通过 DirectX 引擎完成的,可实现高效的硬件和软件呈现。WPF 还要求对内存和执行进行精确控制。milcore 中的组合引擎受性能影响关系大,需要放弃 CLR 的许多优点来提高性能。

  WPF的两大核心组件PresentationFramework和PresentationCore都位于通用语言运行库(CLR)之上。那么就可以看出,WPF的大部分代码都是以托管形式存在的。这两大组件提供了WPF项目需要的函数库和功能库,由于是以托管的形式存在,所以也避免了我们直接操作底层和出现诸如内存泄露的可能性。

5,功能介绍

http://images.cnblogs.com/cnblogs_com/zenghongliang/WindowsLiveWriter/3cfdd94adeea_E606/image_2.png

正如上面的这幅图,可以看出一共分成了五大块(Core Presentation、User Interface Services、Base Services、Document Servies和XPS Viewer):

  • Core Presentation:包含了所有的图形效果,如图形、2D图形、3D图形、文本、音频、视频和显示效果。同时还包括强大的动画效果,动画可以应用前面的所有元素。最下面的那个就是视觉基本元素。
  • User Interface Services:包含了Application Services(应用程序服务)、Deployment Services(部署服务)、Controls(控件库)、Layout(布局)和Data Binding(数据绑定).
  • Base Services:提供了XAML支持、Accessibility(提高开发效率)、Input&Events(输入和事件的支持)、Property
    System(属性系统)。
  • Document Servies和XPS Viewer则提供了基本的打印和表报服务,可以通过这些组件实现自定义的打印和显示效果。

基于上面的特性以及我们使用的情况可以总结出:

在输入方面:WPF支持键盘、鼠标、手写笔、触摸屏,蓝牙录入、视频扑捉等,所以基本没有任何限制,在和外部设备的交互上:有驱动、COM、Win32或通信协议支持的任何设备。打印和报表方面:可访问打印对话框、打印队列、打印窗体、控件以及很多可选操作,同时对报表也支持得很好。同时支持流文档和固定文档,对命令的支持以及对文件的无限制访问,最后尤其在动画、图形图像、3D、影像的支持相当好(其他技术是很难做到的),所以WPF除了在性能方面存在着缺陷以外,其他方面可以说是做得非常优秀,同时我们有信心相信微软会在这方面做得更好!

五. WPF基础及核心概念

1,基础概念

从2007年开始接触WPF/Silverlight以来,对学习和使用它们有自己的一些浅薄心得,所以首先让我们来看看WPF的各个基础概念:

  1. Application、Window、Navigation、Dispatcher: 这里强调一个应用程序的基本组成部分,也就是说它是每一个项目都会遇到的概念!
  2. 框架结构及类继承结构: 没有一个宏观的认识作为灯塔,是一件很危险的事情,尤其在做深入研究的时候!
  3. XAML基础:作为WPF的主打概念,它似乎起着不可估量的作用,这也是大家接触WPF的首要概念!
  4. 布局基础: 每一个应用程序,如果没有良好的布局,似乎是一个不可想象的事情,在WPF中提供了很多布局元素,同时也提供了很多扩展点!
  5. WPF的逻辑树和视觉树: 它很有作用,但也很头痛,很多错误不得不归功于它!
  6. 依赖属性、路由事件、Binding、命令: 核心中的核心,所以我们把它列为重点讲解对象,后面分开阐述!
  7. 资源、样式、模板:在很多程度上,它吸取了之前WEB方面的优势,这三个功能在很大程度上提高了复用,同时也规范了项目!
  8. 尺寸缩放、定位与变换元素:由于是矢量元素,所以在做各种图形图像操作的时候就比较如鱼得水!
  9. WPF控件分类介绍与使用技巧:微软的每一种UI相关的技术都会伴随强大的控件库,有了它们可以大大减轻开发的难度!
  10. 用户控件和自定义控件开发: 和WinForm、ASP.NET一样,开发自定义控件也很简单且类似,这里强调控件的多种分类以及区别对待!
  11. 多语言、皮肤和主题:开发一个稍微大型的应用程序都会遇到多语言、皮肤和主题,在WPF中做这些元素也非常简单!
  12. 2D图形:WPF创建和使用2D图形主要集中在3个重要的数据类型之上——Drawing,Visual,Shape,所以需要分别进行研究!
  13. 3D图形:WPF之所以能带来绚丽且强大的3D图形功能,这得归功于DirectX 技术,并且提供的接口也非常简单,这也使大量动画应用成为可能!
  14. 动画(几种动画的应用):动画无疑是WPF中最吸引人的特色之一,因为一想到动画大家可能都会提到Flash,WPF的确也使动画变得非常简单!
  15. 音频、视频、语音:这里强调的影音相关的功能,由于直接使用DirectX,所以较之前的技术,WPF在显示效果和质量上可谓是质的飞跃!
  16. 文档、打印、报表:强调企业使用的一般功能,在WPF中也得到了很好的实现,这也是大量管理应用程序使用WPF的前提!
  17. Win32、Windows Form以及ActiveX之间的互用性:这里强调与其他技术之间互用的兼容性,当然,在WPF中对这些技术提供了很好的支持!
  18. 部署及更新应用程序:和其他客户端技术一样,WPF的部署与自动更新也比较容易,除了传统的三种方法以外,还提供了XBAP的方式,不过已经逐渐被Silverlight所取代。
  19. WPF的开发模式:其他层可以保持不变,针对Presentation提供了MVC 模式、MVP模式 、MVVM 模式。
  20. 项目和性能相关:WPF在诸多方面都做得很好,除了满足其他客户端技术的功能外,也有自己的独特一面。在性能方面,只要多注意一些细节,就可以超过预期的满足企业的需求。

2,核心概念

可以看到上面的基础概念很多,但圣殿骑士认为核心概念主要有以下三点:

A,依赖属性体系

2010-10-21 17-12-08

  首先从依赖属性基本介绍讲起,然后过渡到依赖属性的优先级、附加属性、只读依赖属性、依赖属性元数据、依赖属性回调、验证及强制值、依赖属性监听、代码段 (自动生成) 等相关知识,最后我们会模拟一个WPF依赖属性的实现,来看看它里面的内部究竟是怎样处理的,这样就可以帮助我们更好的认清它的本质,出现问题的时候我们也可以根据原理快速找到原因。

B,事件体系

2010-10-21 17-13-00

  讲到WPF事件体系,我们就不得不来一场短暂旅行,由于圣殿骑士之前是从C和C++过渡到.NET和JAVA,所以对Win32程序有一些粗浅的认识,不管是Win32/C++还是MFC/C++,在窗体和事件处理上本质都是用消息(Message)来进行通信,只不过MFC对这些繁杂和通用的代码进行了一些封装,到WinForm和WPF也不例外,无疑底层还是通过这些消息在传递操作。有了Win32->MFC->WinForm->WPF这种Message的演变之后,我们必须得认识其中的一些核心概念,比如函数指针、委托回调、委托和事件以及现在提的路由事件。由于这些知识太多,所以不进行深究,在这里我们只研究委托和事件的一些知识、委托和事件实现原理、路由事件的原理以及路由事件的使用,通过这么一来回,可能大家会对路由事件有一个比较清晰的认识,最主要的是能在项目中运用自如。

C,Binding

2010-10-21 17-14-01

  前面讲了WPF的依赖属性体系和事件体系,这里再讲第三个核心概念——Binding,WPF 绑定可以在源数据对象和UI 控件间建立联系,实现单向或双向变更通知,以此实现更好的业务逻辑和UI的分离。也正是因为Binding,才使得UI和业务逻辑的耦合隔离变得如此轻松,也正是因为Binding,我们才实现了MVVM模式,所以Binding在这个过程中起到了核心作用。同时我们也要注意到Binding的知识点非常多,所以就分成三大块来讲解。

  大家可能会说为什么三大核心不包含其他概念?如为什么没有Command?为什么没有动画?为什么没有3D?其实这些技术都是比较靠上层的一些技术细节,在最底层还是依赖于上面的三大核心功能,具体本文就不再详细阐述了,后面的文章再续。

六. WPF工具

WPF工具主要分为开发工具和其他帮助工具,当然这里只是列出了使用频率最高且常见的一些工具。

开发工具:

Visual Studio 2005/2008/2010

Expression Design 2/3/4

Expression Blend 2/3/4

Expression Encoder 2/3/4

其他常用工具:

KaXaml

WPF Inspector

Snoop

XAML Power Toys

WPF Performance Suite

基本上就用到了以上的一些开发和帮助工具,具体使用由于受篇幅所限,这里就不做过多介绍,后面会开单独的篇幅来详述。

本篇小结

  由于“WPF企业内训全程实录”这篇文章花了十多个晚上的时间,所以内容涵盖面广且文章较长。为了提高阅读质量,我把它拆分成了三篇,今天先发布内容较少且较简单的上篇,下周一、二会接着发布其余两篇,敬请期待!最后声明一下,由于圣殿骑士才识浅薄,所以以上观点只是个人的看法与心得,遗漏和错误之处也敬请海涵。怀着技术分享与交流的态度分享出来,希望各位多多指教!

摘要

  WPF企业内训全程实录由于文章比较长,所以一共拆分成了三篇,上篇WPF企业内训全程实录(上)主要讲了基础,这篇作为该实录的中篇,起着承上启下的作用,主要讲解开发模式、团队协作及应用框架。其实如果大家仔细看目录,可以发现我安排的顺序是首先讲解最基本的概念和基础内容、然后过渡到开发模式及框架、最后结合其他技术和项目实际运用,这也是学习并应用一门技术最好的流程。上篇实际上主要有两个侧重点:一则就是理清脉络——历史渊源、概念引入及基本阐述;二则是讲解WPFBasic——主要讲解WPF的每个知识点,涵盖了WPF的方方面面;如果大家感兴趣,可以下载代码进行仔细研究,如果有不懂的地方也可以参考我写的WPF 基础到企业应用系列,这里受篇幅限制,就不详细论述。今天的中篇主要围绕WPF开发模式、WPF团队协作和MVVM框架三个议题进行阐述,希望能给大家带来一些参考和帮助。

章节纲要

· 1.摘要

· 2.本文提纲

· 3.简要介绍

· 4.WPF介绍

· 5.WPF基础

· 6.WPF工具

· 7.WPF开发模式

· 8.WPF团队协作

· 9.了解并使用MVVM框架

· 10.自己开发MVVM框架

· 11.其他技术引入

· 12.WPF项目及性能优化

· 13.部署与更新

· 14.总结

· 15.详细技术索引

七. WPF开发模式

提到WPF开发模式(这里通常所说的是Presentation模式,其他层的模式不在此列),大家可能会立马想到MVC/MVP/MVVM模式:

1,MVC:模型-视图-控制器(Model View Controller)

2,MVP:模型-视图-表现类(Model-View-Presenter)

3,MVVM:模型-视图-视图模型(Model-View-ViewModel)

的确,时下流行的就这三种常见的Presentation模式(这三种模式又衍生了很多变种),从根本上说这些模式是为了解决如下的几个问题:

1,逻辑与UI紧密耦合,更换UI上的显示往往需要更改很多逻辑代码,正所谓“牵一发而动全身”。

2,应用程序状态的维护,主要包括状态 (State) , 逻辑 (Logic) ,同步 (Synchronization)耦合太紧。

3,不能使不同的UI共享相同的逻辑(复用问题)。

4,要测试用户界面效果,你需要做复杂的UI测试。

5,团队协作不能充分发挥,因为耦合太紧的关系。

6,维护比较困难,这也是由于耦合紧密且没有完整的单元测试。

  之前的C/S(WinForm)和B/S(ASP.NET/ASP.NET MVC)我们已经习惯了MVC和MVP模式,现在针对WPF和Silverlight的具体特征——它带来了3D、动画、音频、视频……这导致了UI的变化将更加细节化和可定制化。同时,在技术层面上,WPF和 Silverlight也带来了诸如Binding、 Dependency Property、Routed Events、Command、Attached Behavior(依赖属性体系间接实现)、DataTemplate、ControlTemplate等新特性。我们怎样才能立足于原有的技术框架并把WPF/Silverlight的新特性揉合进去,以应对客户日益复杂且多变的需求呢?那么MVVM模式就是一个不错的选择,详见如下框架图:

mvvmModel_2

图1

  在MVVM模式中,你需要一个为View量身定制的model,那么这个model实际上就是上图ViewModel。ViewModel包含所有UI所需要的接口、属性和命令,这样只需要通过Binding使他们进行关联,就可以使二者之间达到松散耦合,所以这样一来,UI就可以由UI专业人员用Design和Blend来实现(当然很多效果还是需要用传统的制图软件,所以我们都称这种想法叫理想状态),代码人员也可以专心写他的逻辑和业务代码,所以这样分工和协作变得更轻松、更愉快了。更漂亮的是View完全可以由(Unit/Automatic Test)所取代,所以单元测试也变得相对简单。这对于我们的开发人员和测试人员无疑是一个很好的解脱,同时也提高了系统的可测性、稳定性和维护性。数据绑定系统同时也提供了标准化的方式传输到视图的错误验证和输入验证(但是个人觉得不是很好用,所以我们在实际的项目当中会写一套自己的验证框架)。

讲到这里,我们这里不得不引入下面这幅图,我觉得它能阐述一些比较重要问题:

Figure 1 The Components of an MVVM Application

图2(注:此图引用自Robert McCarter的MVVM一文)

上面的这幅图表达了几个概念:

1,Domain Model 始终是应用程序的核心,必须投入大量精力,按照面向对象的分析和设计 (OOAD) 最佳做法进行设计同时按照OOP进行开发。

2,Model、View 和 ViewModel 层之间实施严格的分离,也强调了它们之间是一种松散耦合的关系。

3,每一层或者每一个模块都有自己完整的单元测试,这样即提高了代码质量,同时也增强了稳定性和可维护性。

4,不要为了MVVM而MVVM,不要强调UI端不产生一句后台代码而把所有代码都扔进ViewModel,因为有的操作如果不参与逻辑流程,放在UI端处理会更好,这也符合UI和逻辑隔离的最终原则。

  当然使用这个模式的时候,我们还要注意很多细节,这个是我们必须面对的,比如我们怎么实现View和ViewModel关联、View和ViewModel如何通信、ViewModel与ViewModel如何交互、ViewModel和Model之间的弱关联、怎样用 Attached Behavior实现特定命令操作、怎样弹出UI、怎样实现导航、Validation的自定义设置、异步调用、延迟加载、性能优化、与传统技术的交互等等问题。

八. WPF团队协作

  前面我们讲了WPF的开发模式,针对不同的开发模式,团队协作也会有一些具体的改变,不管是MVC、MVP还是MVVM,无疑都强调的是Presentation,所以我们的域模型和底层操作都不会有所变化,或者严格一点的说是只能影响到服务层/域模型之上的操作!如果不考虑多系统分布式、ESB及SOA体系,就可以分成以下六种角色:

  1. 专业美工人员:整个系统的基调与样式、页面布局图、页面效果图、页面的样式与颜色、常用按钮图标、常用图标图片等等。

  2. XAML人员:Style,Template,Trigger,Resource用XAML代码书写,另外强调和美工及ViewModel人员的交互与合作。

  3. ViewModel :主要封装领域模型暴露的接口,然后提供给View,所以这里强调UI和领域模型的一个适配作用。

  4. 领域模型(核心):应用程序的核心,必须投入大量精力,按照面向对象的分析和设计 (OOAD) 最佳做法进行设计同时按照OOP进行开发。

  5. 框架+常用功能开发人员:这里就包括MVVM框架的开发、维护以及扩展,同时还包括数据底层访问、日志、异常、常用功能等。

  6. 数据库开发和管理人员:数据库库表的建立及维护、数据库脚本的创建及维护、数据库优化以及日常的数据操作问题。

当然在开发中,这六种角色也并不是完全分离的,可以根据具体需求进行调整,同时也可以根据项目的功能划分模块,总之选择项目最合适的协作方式就行。

九. 了解并使用MVVM框架

1,到底有哪些开源MVVM框架?

  前面介绍了WPF的基本概念和一些相关知识,我们了解到开发WPF应用程序可以使用现成的框架和模式,最为合适的莫过于时下正热的MVVM模式,所以这里我们也列出针对MVVM模式的已有开源框架:

2010-10-31 22-51-52

图3

  上面除了WPFToolKit和MEF之外都是一些常用的MVVM框架,连带自己开发的一共是八个,所以自己也取了一个响亮的名字——MVVM八大框架!圣殿骑士本人实际项目中只用到了三个框架,之前WPF使用过MVVM Helpers,在Silverlight项目当中用过MVVMLight+MEF,后来就一直使用自己开发的框架,其他框架也研究了很长时间,但都是为了开发MVVM框架借鉴之用。框架虽然众多,但万变不离其宗,通用功能如下:

1,Model、View 和 ViewModel之间的关系:View和ViewModel如何关联起来(IOC)以及如何通信(通常采用Message),ViewModel和Model之间的弱关联(通常采用接口或者简单注入)。

2,事件驱动模式在MVVM模式采用Command和Attached Behaviors的形式。

3,属性及ViewModel的NotifyPropertyChanged处理。

4,提供完整的单元测试,这也是保证框架的稳定性和维护性的保证。

  也许有一些朋友会问我为什么要研究这么多框架,其实做项目只需要认真研究并实践其中一个就行,研究它们的原因则主要归功于自己开发MVVM框架的需要。下面就让我们来看一下具体有哪些MVVM的开源框架(具体到每一个框架后面有时间再阐述,一篇文章写得确实很累):

2,最强大且功能最多的组合框架——Prism

下载地址:http://compositewpf.codeplex.com/

开发者:微软patterns & practices团队

是否支持Silverlight:是

学习资料:Composite Application Guidance for WPF and Silverlight - May 2010.chm以及Quickstarts和StockTraderRI等。

源码截图如下:

2010-10-6 23-54-02

图4

  Prism——之前又叫Composite Application Guidance for WPF and Silverlight,它是构建复杂的基于WPF/Silverlight企业级应用的主流框架。Prism中有几个比较重要的概念:

1,BootStrapper:应用程序切入点,继承Prism的UnityContainer或MEF提供的MefUnityContainer,为系统提供一个容器。

2,Shell:它是一个外壳,通过UI元素和Region布局页面。 它是应用程序的顶级窗口,显示的内容一般就由View来填充,Shell本身并不知道它包含了哪些内容,所以功能则是由各个Module来具体提供。

3,View:它等同于MVP模式、MVVM模式中的View。可以通过IRegionManager注入到Region中。

4,Module:可以把一个大项目拆分开来,每一个Module都包含View、数据、模型,主要用于实现复杂业务操作。

5,IModuleManager:主要用于管理模块加载,可以实现动态加载。

6,IEventAggregator:事件处理接口,实现订阅和发布模式,这也是MVVM框架的一般做法。

  Prism是一个比较庞大的组合框架,4.0引入MEF及功能调整以后变得更加强大了,现在可以说是组合框架和应用框架的统一体,而且是微软团队的力量,所以选它是值得保证的。

3,最强大且功能最多的应用框架——Caliburn

下载地址:http://caliburn.codeplex.com/

开发者:Rob Eisenberg

是否支持Silverlight:是

学习资料:我主要参考项目实例、源码、单元测试用例、国外一些博客和社区。

源码截图如下:

2010-10-31 22-50-51

图5

Caliburn中有几个比较重要的概念:

1,在Actions基础上的Commands带有很多功能,其中包括多参数、过滤操作以及异步调用。

2,窗体和控件的生命周期事件也处理得比较好(包括activation、deactivation、shutdown等)。

3,不管是整个框架还是基于这个框架的应用程序的可测性都比较好。

4,提供了很多常用功能,这些在项目当中都比较有用。

5,除了支持MVVM模式之外,还很好的支持MVP模式以及其他的一些变种模式。

6,强大的依赖注入框架以及AOP框架,这里可以灵活选用其中一种。

Caliburn是一个非常强大的MVVM应用框架,对很多功能都提供了灵活且多种实现,不论是项目使用还是研究代码,感觉都受益颇多。

4,轻量级且适用的MVVMLight

下载地址:http://mvvmlight.codeplex.com/

开发者:Laurent Bugnion

是否支持Silverlight:是

学习资料:除了online documentation,我主要参考项目实例、源码、单元测试用例、国外一些博客和社区。另外这三篇文章非常不错,用MVVMLight开发了一个比较完整的Silverlight企业项目

源码截图如下:

2010-10-21 16-22-04

图6

MVVMLight中有几个比较重要的概念:

1,RelayCommand:通过对Command进行封装,使得MVVM模式在WPF和Silverlight上更加容易。你只需要在ViewModel中定义好各个RelayCommand,然后在View中通过Command来绑定ViewModel中定义好的RelayCommand,就可以实现像WinForm、ASP.NET事件一样的效果,只不过这里是解除了UI和逻辑的强耦合。

2,Messager:MVVMLight中的Messager作用比较大,前面讲了MVVM模式解除了ViewModel和View的强引用,那么它们如何来进行交互呢?就是靠它来让ViewModel和View来进行通信的。一般我们会定义一个静态AppMessages类来作为通用的一个通信类,原理就是发布订阅模式。

3,EventToCommand:这里就比较类似于附加行为的概念,是在MVVM Light Toolkit V3中开始引入的概念。

4,ICleanup接口:当显示某个View时,需要先调用Cleanup方法清除数据,这也是由于ViewModel和View的耦合隔离产生的一些必要操作。

  MVVMLight是一个非常好用的MVVM框架,提供了VS和Blend的模板及智能感知。它结合MEF使用真的感觉很轻量级且高效,而且提供了WPF和Silverlight的支持,尤其在Silverlight的支持上比较好,所以一般选择轻量级的Silverlight MVVM模式,它比较被看好。

5,功能齐备且易用的MVVM Helpers

下载地址:http://mvvmhelpers.codeplex.com/

开发者:Mark Smith

是否支持Silverlight:否

学习资料:http://www.julmar.com/blog/mark/以及提供的实例、源码及测试用例。

源码截图如下:

2010-10-21 16-25-14

图7

MVVM Helpers又叫JulMar MVVM Helpers + Behaviors,其中有几个比较重要的概念:

1,提供了MVVM模式的基本功能,包括ViewModel、View及Model之间的隔离,另外还提供了一些常用功能。

2,ViewModel的创建使用标签的形式注入,现在也可以引入MEF。

3,IOC/DI的支持,属性都有验证机制,Wait Cursor的支持,当使用完viewmodel之后能及时释放,这样避免内存泄露。

4,提供了常用的Attached Behaviors支持。

5,消息机制的引入,避免强引用产生的耦合。

MVVM Helpers是一个非常适用的MVVM框架,尤其是提供了MVVM常用功能+MEF+Attached Behaviors,所以项目中的问题基本都能解决。

6,功能强大且轻巧的Cinch

下载地址:http://cinch.codeplex.com/

开发者:Sacha Barber

是否支持Silverlight:否

学习资料:http://sachabarber.net/以及提供的实例、源码及测试用例。

  1. A walkthrough ofCinch, and its internals - Part I
  2. A walkthrough ofCinch, and its internals - Part II
  3. How to develop ViewModels usingCinch
  4. How to Unit test ViewModels usingCinchapp, including how to test Background work threads which may run withinCinchViewModels
  5. A Demo app usingCinch

源码截图如下:

2010-10-21 16-34-31

图8

如果仔细研究其代码,你会发现它和上面讲的MVVM Helpers有很多相似的代码,估计是相互参考了一番:-D。Cinch 中有几个比较重要的概念:

1,这个框架在没有MEF出现之前就已经实现了ViewModel和View之间的强引用隔离,它既没有一般IOC的配置,也没有IView来做中转,并且窗体和控件的生命周期事件也处理得比较好,所以在这方面来说是非常不错的。

2,提供了常用的Attached Behaviors支持,另外也提供了一些MVVM常用功能。

3,DI/IOC使用Unity实现,多线程的实现,避免系统出现不可预料的错误。

4,当使用完viewmodel之后能及时释放,这样避免内存泄露,验证机制的加入,常用导航实现。

5,消息机制的引入,避免强引用产生的耦合。

Cinch 是一个非常强大的框架,尤其是它比较着眼整个应用程序的搭建,所以也比较受到青睐。

7,功能简单且易扩展的MVVMFoundation

下载地址:http://mvvmfoundation.codeplex.com/

开发者:Josh Smith

是否支持Silverlight:否

学习资料:http://joshsmithonwpf.wordpress.com/以及提供的实例、源码及测试用例。

源码截图如下:

2010-10-21 16-22-57

图9

MVVMFoundation中有几个比较重要的概念:

1,Messenger:这里主要用在各种不同的ViewModel之间通信(比如相互关联的ViewModel、主从ViewModel等),当然也可以扩展成ViewModel与View之间进行通信。

2,ObservableObject:这里相当于ViewModelBase的概念,每一个ViewModel继承自该类,调用完成之后立即释放,防止内存泄露。

3,PropertyObserver:主要是对INotifyPropertyChanged.PropertyChanged进行封装,这样封装可以精简代码,同时可以防止不当操作引起的内存泄露。

4,RelayCommand接口:封装command的声明,包括execution执行逻辑,可选的can-execute逻辑等。外部只需要实例化并Binding就可以简单使用。

MVVMFoundation是一个非常简单的MVVM框架,如果你觉得研究源码比较困难,就可以先从这个框架入手,代码简单而且精炼。

8,附加:支持插件式的依赖注入MEF

下载地址:http://mef.codeplex.com/

源码截图如下:

2010-10-21 16-20-52

图10

9,如何充分利用这些框架

  上面我们已经介绍了七大MVVM框架+支持插件式的依赖注入MEF,其实另外这三个框架WPF Application Framework (WAF)CalciumCoreMVVM(Basic MVVM framework)也很值得研究,由于时间和精力的关系,针对这三个框架圣殿骑士也没有进行仔细的剖析,只是粗略看了一下基本功能。

其他一些框架诸如OnyxnRouteNito MVVMOceanGoodLight就没有太多关注,有兴趣的朋友也可以选择其中某一个或多个框架作为研究和学习,不过还是推荐研究主流的框架,毕竟这些主流框架的开发团队和成熟度都比较强。

上面看到了这么多MVVM框架,那么我们应该怎么去学习和使用呢?简单来说可以归纳为以下几句话:

1,根据具体的项目选择适合的框架,团队和项目有大有小,所以得根据这些来选择具体的框架,其实终归来说,几个框架功能都比较类似。

2,框架不用研究太多,只要适用于项目就行,尤其是熟练使用并根据其提供的TDD测试代码追溯其原理。

3,框架不是万能的,对于某些应用和功能可以对框架扩展,这也开源最大的好处之一。

针对框架的研究,自己也总结了几点:

1,首先看框架的相关介绍,了解相关的背景、功能、架构图以及其他一些相关信息——认识了解。

2,根据介绍查看并调试框架所提供的实例——熟悉功能。

3,自己写一些相关的项目,主要是熟悉该框架,如果说要急于做项目,后面就可以把框架引入到项目当中——具体使用。

4,根据该框架提供的详细单元测试研究其源码,这也是我最喜欢研究这些开源框架的原因——原理剖析。

5,通过上面的步骤认真分析其原理及细节——准备重现。

6,自己也根据之前的思路重复开发这个框架,最好能用TDD——框架复原捷径。

  上面我们谈了一些开源框架相关知识,下一步我们得自己开发一个MVVM框架,一方面是对知识的总结,另一方面也是对知识的再提炼,同时也能使自己的认识提升到另一个高度,紧接下文。

十. 自己开发MVVM框架

  由于之前自己做了一套框架,但是还没有趋于完善,所以暂时不准备共享出来(主要是WPF和Silverlight版本更替比较频繁且没有加入模板及智能感知)。对于开发一套MVVM框架,具体需要做一下几个操作:

1,要能解决Model、View和ViewModel之间的强关联,这也是核心功能,尤其是View和ViewModel,不管是使用IOC Container还是MEF都行。

2,命令和附加事件的处理,对Command进行封装,满足多参数、方法过滤、泛型、异步回调等,对附加事件进行封装,使它像使用命令一样简便。

3,由于View和ViewModel是弱关联或者是无关联,如何让它们进行通信?这就需要加入Messenger机制。

4,前面引入了消息机制(一般是静态化处理),如何来管理、实例化、清除消息呢?这里得建立一套消息机制。

5,由于前面采用了弱关联或者无关联,并且引入了消息机制,所以需要对操作有日志记录,否则出了问题无法快速定位及追查原因。

6,如何统一管理ObservableObject、PropertyObserver等这些对象呢?所以得自己建立一套变更体系。

7,对常用功能及操作进行封装,提供一些常用类库以及UI Helper等。

  总之,开发MVVM框架不能求全,只要适合项目就行,也不要想一次就能完善整个框架,在使用时不断根据需求扩展才是明智之举。另外附加三点开发MVVM框架心得:

1,充分借鉴其他开源框架,研究各个框架的不足和优势,然后把思想贯穿于自己的框架中,当然有些常用功能代码也可以直接借鉴过来。

2,对于这样一个比较庞大的框架,使用TDD+反复重构无疑会提高开发效率,同时也能提高框架的可维护性和稳定性,这也是团队使用的一个前提。

3,框架会使用一些常用设计模式,有了它们可以让框架更具有扩展性,同时也减少了开发成本、增加了可维护性。比如观察者模式(消息的发布、订阅、触发)、中介者模式(直接通信的类转化为中间类来处理,隔离耦合)、外观模式(提供一个简单的接口出来,在内部进行大量的封装,这样就可以起到易用且功能强大的目的)、装饰模式(原来已经稳定的功能模块,如果在不改变原有结构的基础上进行扩展,无疑这是一个很好的实践)等。

总结

  上篇WPF企业内训全程实录(上)主要讲解历史渊源、概念引入、基本阐述以及WPF的每个知识点。这篇主要主要围绕WPF开发模式、WPF团队协作和MVVM框架三个议题进行阐述。下篇将着重强调结合其他技术共同打造WPF项目、相关性能优化、以及部署与更新问题,所以敬请期待!另外如果有不懂的地方也可以参考之前写的WPF 基础到企业应用系列,最后声明一下,由于圣殿骑士才识浅薄,所以以上观点只是个人的看法与心得,遗漏和错误之处也敬请海涵。怀着技术分享与交流的态度分享出来,希望各位多多指教!

摘要

  WPF企业内训全程实录由于文章比较长,所以一共拆分成了三篇,上篇WPF企业内训全程实录(上)主要讲了基础,中篇WPF企业内训全程实录(中)主要讲解开发模式、团队协作及应用框架,起着承上启下的作用,主要讲解开发模式、团队协作及应用框架。这篇作为该实录的下篇——终结篇,起着总结的作用,主要讲解其他技术的引用、WPF项目及性能优化、部署与更新等议题。

  其实如果大家仔细看目录,可以发现我安排的顺序是首先讲解最基本的概念和基础内容、然后过渡到开发模式及框架、最后结合其他技术和项目实际运用,这也是学习并应用一门技术最好的流程。上篇实际上主要有两个侧重点:一则就是理清脉络——历史渊源、概念引入及基本阐述;二则是讲解WPFBasic——主要细究WPF的每个知识点,基本涵盖了WPF的方方面面;如果大家感兴趣,可以下载代码并进行仔细研究,如果有不懂的地方也可以参考我写的WPF 基础到企业应用系列,这里受篇幅限制,就不详细重复论述。中篇主要围绕WPF开发模式、WPF团队协作和MVVM框架三个议题进行阐述,侧重于为什么要引入MVC/MVP/MVVM模式、从根本上说这些模式是为了解决什么问题、针对不同的开发模式,团队协作会有哪些具体的改变、了解并使用常用的开发框架以及追根索源探究并实现自己的开发框架。下篇则主要总结前面所讲的内容,同时介绍其他技术引入、WPF项目及性能优化与部署与自动更新等概念,其目的在于项目具体应用层次的归纳和总结。

章节纲要

· 1.摘要

· 2.本文提纲

· 3.简要介绍

· 4.WPF介绍

· 5.WPF基础

· 6.WPF工具

· 7.WPF开发模式

· 8.WPF团队协作

· 9.了解并使用MVVM框架

· 10.自己开发MVVM框架

· 11.其他技术引入

· 12.WPF项目及性能优化

· 13.部署与自动更新

· 14.总结

· 15.详细技术索引

十一. 其他技术引入

通过WPF 基础到企业应用和前面两篇文章,我们基本讲解了WPF的基础知识和框架相关细节,可以用以下这幅图进行简要概括:

圣殿骑士

图1

那么下面我们就来探讨一下WPF和其他技术之间的衔接问题。我们之前做项目都有一个基本流程,大致包括以下几个方面:

1.基础开发平台与工具:在开发一个中、大型项目之前,我们一般都会有技术选型的过程,比如选择Linux + Apache + PHP + MySQL或者Linux + Apache + Java (WebSphere) + Oracle再或者我们最熟悉的Windows Server 2003/2008 + IIS + C#/ASP.NET + SQL Server,当然这些操作系统、WEB服务器、开发语言和数据库在一定条件下可以任意搭配,比如你想用FreeBSD操作系统,你想用Ruby或者Python语言,你想用DB2或者其他数据库等。决定了开发平台和语言之后,就需要有定制的开发工具,比如Java你可能需要Eclipse或者MyEclipse插件,Net你需要强大的Visual Studio或者MONO环境下使用SharpDevelop,PHP你可能需要强大的Zend。简而言之,不管使用什么开发平台,都需要对应的开发套件与开发工具作为辅助。当然我们今天谈的是WPF项目的开发,所以必然我们会首先选择Windows Server 2003/2008 + IIS + C#/ASP.NET + SQL Server这种搭配,也有人会说可以考虑MONO下的WPF开发和部署,不过很遗憾,MONO下针对WPF并没有完全进行实现。

2.基础框架及资源:这里的基础框架是指有没有现成的数据访问框架、通用权限框架、异常和日志处理框架、IOC框架、AOP框架、简单的CMS管理框架、Office文档及PDF交互、报表及打印功能等,因为有了这些以后,开发项目就简单了许多,我们只需要关注具体的业务处理就行,这样可以使项目更加高效且稳定的完成。

3.逻辑架构:逻辑架构往往决定了你如何划分模块以及如何来分层,这个要根据项目的具体情况而定,比如项目的大小、项目模块的多少以及开发方式、开发团队等。往往在这一阶段决定项目的整体架构(三层及多层架构、是否有必要搭建ESB与SOA等)。

4.物理搭建:之前在做WEB应用的时候,会非常重视物理结构及环境的搭建,因为往往它在项目伸缩性、灵活性以及负载方面起着至关重要的作用,其实在决定逻辑架构的时候也必须要考虑到物理架构,我们这里所说的物理架构就是指整个系统或者多个系统在物理环境上的一个部署情况,比如Web Server集群、App Server集群、文件服务器集群、图片服务器集群、流媒体服务器集群、全文检索服务器集群、缓存服务器集群、负载均衡服务器、数据库主从、读写服务器集群等的部署情况。做简单的WPF管理系统也许并不用考虑这么多,如果要做大型的WPF播放器以及大型的WPF应用,这些都得经过仔细的斟酌才行。

5. 框架的选择:这个地方是选择整个应用程序的框架,当然选择的前提还必须参考前面的逻辑与物理结构。具体框架包括数据底层处理框架、公共基础框架以及我们前面所提及的诸如MVC/MVP/MVVM模式等。

6. 其他处理:面向对象设计与实现、面向方面思想、权限系统设计、缓存体系设计、异常及日志框架设计、分布式及负载均衡等都是我们需要考虑的重点和要点。最后要特别注意团队及项目规范、项目整体开发流程、版本与配置管理、项目开发注意细节等问题。

十二. WPF项目及性能优化

一,WPF项目

1)之前的项目架构

在讲WPF项目架构与基础结构之前,我们先来看一下之前搭建的WEB应用程序:

clip_image002

clip_image004

图2及图3

上面的两幅图具体概念如下:

01,User Interface即UI层:该层作为数据输入和展示的界面,是与用户交互的有效途径,所以它起着至关重要的作用。往往给人第一印象的就是UI层,在设计的时候也要根据不同的技术或者不同的要求进行斟酌。通常可以把UI分为B/S UI、C/S UI以及WEB服务。在这里就是我们的ASP.NET项目。

02,WebModelCommon:这层作为UI与领域逻辑的中间层,它的充当了桥梁、筛选、过滤和验证的作用。它主要包括两个工程,WebHelper主要提供给UI一些常用操作。WebLogic主要对UI与领域逻辑的数据进行转换、筛选、验证及过滤操作。

03,Business Logic:Domain Model (Data Model Layer)始终是应用程序的核心,必须投入大量精力,按照面向对象的分析和设计 (OOAD) 最佳做法进行设计同时按照OOP进行开发。业务逻辑层根据业务进行文件夹区分,每个文件夹主要包括业务实体、业务接口、业务具体逻辑、业务适配器以及业务自动单元测试。

04,FrameWork:主要包括数据访问框架、通用权限框架、异常和日志处理框架、IOC框架、AOP框架等基础或常用功能。

05,SOA:这一层不是必须的,根据项目的具体情况进行取舍,如果业务比较复杂且交互项目繁多,那么SOA可以减轻我们的负担;如果业务比较单一且相对简单,就可以直接调用或者使用Web Service/Remoting/WCF作为通信框架即可。在实施SOA的过程中,可以自己使用WCF+WF搭建一个小型轻量级的SOA框架,也可以使用诸如Biztalk等软件。

06,Reference:这里主要包括第三方的框架和组件项目,把这些文件分门别类地集中放在此目录下。

07,Solution Items:项目的规范、流程、重要文件等。

08,Test:这里主要放置测试需要的一些信息,如测试版本、测试文档等。

09,Publish:这个文件夹主要放置发布的版本。

这个框架能解决大多数问题,但仍有不完善之处。

1)WPF或Silverlight架构

  在MVVM模式中,你需要一个为View量身定制的model,那么这个model实际上就是上图ViewModel。ViewModel包含所有UI所需要的接口、属性和命令,这样只需要通过Binding使他们进行关联,就可以使二者之间达到松散耦合,所以这样一来,UI就可以由UI专业人员用 Design和Blend来实现(当然很多效果还是需要用传统的制图软件,所以我们都称这种想法叫理想状态),代码人员也可以专心写他的逻辑和业务代码,所以这样分工和协作变得更轻松、更愉快了。更漂亮的是View完全可以由(Unit/Automatic Test)所取代,所以单元测试也变得相对简单。这对于我们的开发人员和测试人员无疑是一个很好的解脱,同时也提高了系统的可测性、稳定性和维护性。数据绑定系统同时也提供了标准化的方式传输到视图的错误验证和输入验证(但是个人觉得不是很好用,所以我们在实际的项目当中会写一套自己的验证框架)。

2010-12-8 22-07-25

图4

那么根据上面这幅图,我们具体可以得出如下结论:

1,首先介绍的是UI层,该层作为数据输入和展示的界面,是与用户交互的有效途径,所以它起着至关重要的作用。往往给人第一印象的就是UI层,在设计的时候也要根据不同的技术或者不同的要求进行斟酌。通常可以把UI分为B/S UI、C/S UI以及WEB服务。

2,ViewModel作为用户界面和业务领域模型的中间层,它往往起着类似于桥梁的作用(UI和领域业务逻辑层之间的桥梁以及耦合的隔离者)。

3,Domain Model (Data Model Layer)始终是应用程序的核心,必须投入大量精力,按照面向对象的分析和设计 (OOAD) 最佳做法进行设计同时按照OOP进行开发。业务逻辑层根据业务进行文件夹区分,每个文件夹主要包括业务实体、业务接口、业务具体逻辑、业务适配器以及业务自动单元测试。

4,Model、View 和 ViewModel 层之间实施严格的分离,也强调了它们之间是一种松散耦合的关系。

5,每一层或者每一个模块都有自己完整的单元测试,这样即提高了代码质量,同时也增强了稳定性和可维护性。

6,不要为了MVVM而MVVM,不要强调UI端不产生一句后台代码而把所有代码都扔进ViewModel,因为有的操作如果不参与逻辑流程,放在UI端处理会更好,这也符合UI和逻辑隔离的最终原则。

7,数据底层操作层可以随意的搭配,既可以使用传统的方式也可以用ORM的方式,这个根据团队或项目的具体情况作抉择。如传统的存储过程或者脚本、借助于企业库、IBATIS.NET、Nhibernate,Active Record,Entity framework,Linq To Sql,entity framework或者Custom ORM等。

8,Database做为最底层,它对应用程序起着最为关键的作用,项目没有数据就等于失去了最本质的东西,除非这个项目和数据没有太多关联,所以必须投入大量的时间和精力在这一层,这也是数据库库团队存在的必要。最典型的问题包括数据库优化、数据库拆分、分离、同步、数据挖掘以及数据库的备份与复原等。

前段时间本来要重构一个项目,但由于诸多原因,这个项目没有能够在整体架构上进行调整,这里也把项目整体结构图贴出来,供大家参考

Arc1
  • Arc2

图5及图6

上面的两幅图具体概念如下:

01,UI:该层作为数据输入和展示的界面,是与用户交互的有效途径,所以它起着至关重要的作用。往往给人第一印象的就是UI层,在设计的时候也要根据不同的技术或者不同的要求进行斟酌。通常可以把UI分为B/S UI、C/S UI以及WEB服务。在这里就是我们的WPF项目。

02,ViewModel作为用户界面和业务领域模型的中间层,它往往起着类似于桥梁的作用(UI和领域业务逻辑层之间的桥梁以及耦合的隔离者),这里没有把它从UI里面独立出来,所以它放在UI或者独立出来均可。

03,LogicBusiness:Domain Model (Data Model Layer)始终是应用程序的核心,必须投入大量精力,按照面向对象的分析和设计 (OOAD) 最佳做法进行设计同时按照OOP进行开发。

04,Common:主要包括数据访问框架、通用权限框架、异常和日志处理框架、IOC框架、AOP框架等基础或常用功能。

05,SOA Service:这一层不是必须的,根据项目的具体情况进行取舍,如果业务比较复杂且繁多,那么SOA可以减轻我们的负担;如果业务比较单一且相对简单,就可以直接调用或者使用Web Service/Remoting/WCF作为通信框架即可。在实施SOA的过程中,可以自己使用WCF+WF搭建一个小型轻量级的SOA框架,也可以使用诸如Biztalk等软件。

06,DataAccess:数据库访问组件。

07,AddedDll:这里主要包括第三方的框架和组件项目,把这些文件分门别类地集中放在此目录下。

08,UnitTest:对每层及每个模块进行单元测试。

  从上面WEB与WPF两个项目中可以看到具体的差别与联系:联系在于公共的东西都是不会变的;差别在于WEB与WPF都有各自的特点,所以在处理上也有一些细微的区别!

二,性能优化

  关于性能优化,在任何项目都会有所涉及,使用WPF的项目也不例外(或者更甚)。那么针对WPF项目,我们如何来做好性能优化呢?其实这个问题比较大,因为往往某个细节的操作会影响到整个WPF应用程序的性能,所以在做项目的时候一般都会针对这些性能优化操作列一个表(详细说明性能优化点及注意事项)。WPF性能优化就像之前做WEB优化一样,都有一些“银弹”可供参考,WEB项目有Yahoo团队实践分享——网站性能优化的条黄金守则和业界的一些经验;WPF作为出道不久的技术,主要参考微软提供的性能优化注意事项以及自己的实践经验。本来是想罗列一些性能优化点,无奈由于时间仓促且怕罗列不全面或不正确,所以把它留在以后心情好的时候再续,不然就会起到不能帮助读者反而误导读者的效果。

十三. 部署与自动更新

  一个优良的软件都会有自己完整的部署与自动更新流程,C/S应用程序尤其如此,所以如何解决客户端的部署与自动升级问题便是一个非常重要的问题。大家都知道ClickOnce 无疑是微软对Client/Server模式部署的最佳解决方案,但正是因为它的功能特别强大而且又要使用相当简单,所以在产品的封装上就特别严实,基本上就暴露了一些简单的操作接口,这样用户就无法做定制化的操作,所以我们下面主要探讨不使用ClickOnce的操作流程。

一,打包操作

  关于打包操作,现在市面上有很多的打包工具与代码,但最为常用的要数Installshield和微软自带的打包工具软件,两者在这方面都有不俗的表现,前者强调打包的定制化以及多样性,后者强调易操作及快速性。如果你想要更多漂亮及定制化的操作,可以选择Installshield+脚本的方式;如果你想做一般的效果,那么微软自带的打包工具软件就特别适合;当然这也不是绝对的定律,只是一般情况下的选择,下面我们就主要来讲解微软自带的打包工具软件。

1) 创建安装和部署项目:

1,右键点击当前解决方案—>Add—>New Project,在弹出的窗口中选择Other Project Types—>Setup and Deployment—>Setup Project;然后输入项目的名字,点击“OK”按钮。新添加的安装和部署项目就会出现在解决方案列表中。

2) 添加项目输出及制作安装界面:

1,首先把你要安装的项目加进来,也就是加入到应用程序文件夹,由于VS SetUp设置比较简单,你只需要按照操作步骤一步一步设置即可。在完成应用程序文件夹之后设置开始菜单和用户桌面的快捷方式。

2,右键点击安装项目,选择View—>User Interface可以看到VS SetUp为我们提供的一些默认安装界面,当然你也可以创建、修改或者移除这些窗口,总之你可以定制化你的安装步骤和页面。

3) 注册表问题:

和前面的操作类似,对于注册表的设置也比较简单,右键点击安装项目,选择View->Registry即可创建、修改及移除注册表键值。

4) 创建组件注册项目:

1,右击当前解决方案—>Add—>New Project,在弹出的窗口中选择 Visual C#—>Class Library;然后在下方文本框中输入Name,点击“OK”按钮。新添加的项目会出现在解决方案列表中。

2,右键点击该项目—>Add—>New Item,在弹出的窗口中选择Installer Class;在下方文本框中输入名字,点击“Add”按钮添加文件并关闭窗口。

3,选中刚添加的文件,按F7或者View Code转到代码页,在代码页面添加以下方法:

namespace RegsvrDll
{
    [RunInstaller(true)]
    public partial class InstallerReg : Installer
    {
        public InstallerReg()
        {
            InitializeComponent();
        }

        public override void Install(System.Collections.IDictionary stateSaver)
        {
            base.Install(stateSaver);
        }

        protected override void OnAfterInstall(IDictionary savedState)
        {
            base.OnAfterInstall(savedState);

            string LogicDir = Context.Parameters["LogicDir"];

            // Close the writer and underlying file.
            // 注册CDO组件
            // /s 关闭注册成功的提示窗口显示,/c退出cmd窗口
            System.Diagnostics.Process.Start("cmd", @"/c regsvr32 " + @LogicDir + @"ComUtilities.dll /s");

            string path = @LogicDir + @"App.exe";
            using (RegistryKey regWrite = Registry.LocalMachine.CreateSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths"))
            {
                regWrite.SetValue("App.exe", path);
                regWrite.Close();
            }
        }

        protected override void OnBeforeInstall(IDictionary savedState)
        {
            base.OnBeforeInstall(savedState);
        }
    }
}

注意:需要加入using System.Configuration.Install;

5) 在安装和部署项目中添加要安装的项目和文件:

1, 添加项目:右击项目—>View—>File System,在出现的界面中,右击左列的Application Folder—>Add—>Project Output,在弹出的窗口中选择相应的Project,然后点击“OK”按钮。多个项目重复多次。在这里我们假设我们开发的项目为 MainProject,注册组件的项目名称为RegDll,那么我在弹出的窗口中先选择项目MainProject,点击“OK”后,我在重复添加项目 RegDll。

2,添加文件:右击项目—>View—>File System,在出现的界面中,右击左列的Application Folder—>Add—>File,在弹出的窗口中选择C:\WINDOWS\system32 \misexec.exe;

3,创 建快捷方式:在右列中选择Primary output from MainProject(Active),右击 选择Create Shortcut to Primary output from MainProject(Active),你可以按F2给新添加的快捷方式更名。右击msiexec.exe 选择 Create Shortcut to misexec.exe,你可以按F2将刚生成的快捷方式更名为“卸载”;

4,创建程序组:右击左列的User’s Programs Menu选择 Add—>Fold,你可以将新创建的文件夹更名,当软件安装完毕后它将出现在程序组中,然后将上一步创建的两个快捷方式拖到新创建的文件夹中。

5,实现“卸载”的功能:选中安装和部署项目,按F4,复制ProductCode的内容,然后选中“卸载”快捷方式,按F4,将Arguments 的内容更改为:/x 刚复制的ProductCode的内容。

6) 安装时注册组件问题:

  右击安装和部署项目—>View—>Custom Actions,在出现的界面中右击左列的Install—>Add Custom Action,选择Application Folder中的Primary output from RegDll(Active)。

clip_image002

图7

修改“主输出来自RegDll (活动)”的CustomActionData属性为 /LogicDir="[TARGETDIR]\"

clip_image004

图8

7)自动检测当前系统中MDAC、.Net Framework版本、Windows Installer3.1是否满足版本要求,如果不满足则安装:

  右击安装和部署项目选择属性,在弹出的窗口中点击按钮 “Prerequisites”。选中MDAC2.8、.Net Framework2.0、Windows Installer3.1;然后选中Download prerequisites from the same location as my application 单选按钮,点击“OK”,再点击“OK”。

8)重新编译项目生成项目安装包,这个时候就可以把安装包Host在网上供用户下载。

二,自动更新

1),简要介绍

  众所周知,对于一般的软件开发,在开始的时候都会有一个技术选型的阶段,最大的选型就是首先要确定是选择Client/Server模式还是 Browser/Server模式。综合而论:两者各有优劣,在很多方面都不能被对方互相取代,如在适用Internet、维护工作量等方面,B/S比C /S要强很多;但在运行速度、数据安全、人机交互等方面,B/S就远不如C/S那么强大。所以综上所述,凡是C/S的强项,便是B/S的弱项,反之亦然。由于今天讨论的是自动更新组件,所以接下来我们就往这方面细讲,既然C/S模式在运行速度、数据安全、人机交互有这么多的优点,尤其是客户端技术日益发展的今天,如何解决客户端的部署与自动升级问题便是一个非常重要的问题。

2),ClickOnce与自定义之间的权衡

  在前面的摘要中我们简单介绍了自动更新功能的重要性,在这一小节里我们来谈一下为什么不使用微软给我们提供的自动更新组件ClickOnce,大家都知道ClickOnce给我们提供了很多功能:简单说来,ClickOnce 应用程序就是任何使用 ClickOnce 技术发布的 Windows 窗体或控制台应用程序。可以采用三种不同的方法发布 ClickOnce 应用程序:从网页发布、从网络文件共享发布或是从媒体(如 CD-ROM)发布。ClickOnce 应用程序既可以安装在最终用户的计算机上并在本地运行(即使当计算机脱机时也可以运行),也可以仅以联机模式运行,而不在最终用户的计算机上永久安装任何内容。ClickOnce 应用程序可以自行更新;这些应用程序可以在较新版本变为可用时检查较新版本,并自动替换所有更新的文件。开发人员可以指定更新行为;网络管理员也可以控制更新策略,如将更新标记为强制性的。最终用户或管理员还可以对更新进行回滚,使应用程序恢复到早期的版本。

从上面大家可以看出ClickOnce 无疑是微软对Client/Server模式部署的最佳解决方案,但正是因为它的功能特别强大而且又要使用相当简单,所以在产品的封装上就特别严实,基本上就暴露了一些简单的操作接口,这样就无形把一些定制化的操作拒之于门外,比如:

  • 用户不能自己指定安装路径。
  • 对自动更新流程不能做定制化的操作。
  • 对自动更新的UI不能定制化的设计。

正因为这几个原因,所以很多企业都会做一些定制化的组件来实现自动更新的功能,基于此,我们这里也实现了一个非常简单的自动更新组件.

3),自定义更新操作流程

其实自动更新的原理很简单,分析起来无非就是简单的几步操作,当然实现方式也是大同小异,这里我们就选一种较简单的方式:

1.启动主程序,主程序里面调用升级程序,升级程序连接到IIS或者FTP。

2.升级程序获取服务器端XML配置文件中新版本程序的更新日期或版本号或文件大小。

3.升级程序获取原有客户端应用程序的最近一次更新日期或版本号或文件大小,然后两者进行比较;如果新版本日期>原有程序的最新日期,则提示用户是否升级;或如果新版本版本号>原有程序的版本号,则提示用户是否升级;再或如果新版本文件大小>原有程序的文件大小,则提示用户是否升级。本文主要采用一般的做法,就是通过版本号来进行对比。

4.如果用户选择升级,则获取下载文件列表;

5.在本地建立与远程IIS或者FTP相应的临时目录,然后下载到这个临时目录文件下;

6.删除旧的主程序,拷贝临时文件夹中的文件到相应的位置;

8.结束升级流程并重新启动主程序。

4),自动更新效果图

当我们运行主程序(WinForm或者WPF),如果服务器上有最新的版本,就会弹出如下页面进行提示并让用户选择是否更新。

2010-10-13

图9

当用户不需要更新时,可以选择Skip按钮跳过并继续主程序流程,反之则进入如下页面。

2010-10-13

图10

在下载的过程中,用户可以选择Cancel停止下载并重新回到主流程。

十四,总结

  上篇WPF企业内训全程实录(上)主要讲解历史渊源、概念引入、基本阐述以及WPF的每个知识点。中篇WPF企业内训全程实录(中)主要主要围绕WPF开发模式、WPF团队协作和MVVM框架三个议题进行阐述。下篇WPF企业内训全程实录(下)将着重强调结合其他技术共同打造WPF项目、相关性能优化、以及部署与更新问题。另外如果有不懂的地方也可以参考之前写的WPF 基础到企业应用系列,最后声明一下,由于圣殿骑士才识浅薄,所以以上观点只是个人的看法与心得,遗漏和错误之处也敬请海涵。怀着技术分享与交流的态度分享出来,希望各位多多指教!

十五,详细技术索引

· 1. WPF 基础到企业应用系列1——开篇有益

· 2. WPF 基础到企业应用系列2——WPF前世今生

· 3. WPF 基础到企业应用系列3——WPF开发漫谈

· 4. WPF 基础到企业应用系列4——WPF千年轮回

· 5. WPF 基础到企业应用系列5——WPF千年轮回 续前缘

· 6. WPF 基础到企业应用系列6——WPF布局全接触

· 7. WPF 基础到企业应用系列7——深入剖析依赖属性(核心篇)

· 8. WPF 基础到企业应用系列8——依赖属性之“风云再起”

WPF企业内训全程实录(上)

WPF企业内训全程实录(中)

WPF企业内训全程实录(下)


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics