Prism开发框架学习笔录1概述1.1什么是PrismPrism是CompositeApplicationGuidanceforWPF的简称,是用于WPF和Silverlight的企业级框架,由微软P&P(patterns&practices)小组设计。1.1.1Prism的优点把界面(Interface)与逻辑相剥离,从而美工和程序员可以各按其事,互不干扰。这个想法有点乌托邦,因为WPF程序员和超女一样满大街都是,但Blend美工在国内凤毛麟角,不要奢望在你的Team中有这样的一个人。把界面拆分成若干小的模块(Module),从而使模块间的交互实现了最大的松散耦合,降低了“牵一发而动全身”的风险。此外,在部署的时候,也可以实现按需(OnCommand)加载和更新,尤其是对Silverlight而言,用户只有在需要这个模块的时候才会去下载,而不用长时间等待所有的模块加载完毕。模块的拆分,使得开发和测试也可以独立地进行。这是因为Prism使用了TDD的设计理念,当然我们在开发流程中也要follow这样的思想去编程,即“开发未动,测试先行”。最大程度的实现了可复用(re-use)。尤其是日志关联和权限管理,是完全独立于主逻辑的(在数学上,这叫垂直关系,二者的叉积为零,从而各自改变而互不影响)。Prism只是一个框架,所以它与以下技术无关:偶发连接(SmartClient的特性)通信机制(这是WCF的职责)应用程序性能错误处理机制权限验证(可以使用MemberShip)线程同步版本控制Prism的设计理念中充斥着大量的设计模式。然而,真正使用Prism可能会很麻烦,一个简单的逻辑在Prism中需要很复杂,几行代码很可能会变成几百行——对于小型项目而言,是不适合用这套框架的。我们可以从项目一开始就使用Prism进行开发,也可以对原有老的WPF或Silverlight项目进行升级。我的切身感受是,升级并不是很麻烦,只要想清楚这套框架的逻辑,因此,改变设计理念是很重要的。1.1.2Prism相关资源国内对Prism的传经授道很早就开始了,比如说博客园的周银辉和张兴浩,他们分别在自己的项目中使用到这个框架,因此有丰富的心得体会以及大量的介绍性文章,博客地址如下:周银辉:张兴浩:此外,P&P官方论坛也是很不错的地方,上面有来自全世界的反馈和TroubleShooting,地址如下:评估架构师和开发者需要花费些时间以完全理解和评估Prism。虽然并不存在一种简单的方法对一个项目进行评估,但是这份文档还是把评估的过程划分为4个步骤:适合性分析(FitAnalysis)。判断Prism是否适合于你的需要。初始评估(Intialevaluation)。安装、运行并检查Prism。深度评估(In-depthevaluation)。对Prism进行全部的检查。采纳(Adoption)。将Prism集成到一个复杂的应用程序中。1.2.1适合性分析Prism是用来设计复杂的WPF和Silverlight应用程序的。下面的场景是你在使用Prism时应该考虑的:你正在创建一个复合的应用程序,通过一个集成的用户接口来表示来自多个源的信息。你正在开发、测试并部署相互独立的模块。你的应用程序今后将添加更多的View和函数。你必须能够快速安全地改变应用程序,以满足企业级需要。你的应用程序是由多个小组合作开发的。你的应用程序是以WPF和Silverlight为目标,并且你想要在这两个平台间共享尽可能多的代码。如果你的应用程序并不需要这些场景中的一个或多个,那么Prism可能并不适合你。例如,你的应用程序由一些简单的界面组成,或者你正在创建一个原型或演示应用程序,或者你的开发人员并不熟悉这些观念或也没有实践过,并且也没有时间去学习,那么Prism对你而言可能也是不适合的。为了判断Prism是否为一个有潜力的框架,你需要理解这个框架所要解决的问题。下面的部分将帮助你执行这样的适合性分析。什么时候使用Prism目标和优点模块化设计概念UIComposition设计概念适用的人群应该使用1到2个小时来完成这一步骤。1.2.2初始化评估为了近距离接触Prism,你将要学习到更多关于Prism类库的设计,以决定复合的应用程序框架是如何匹配到你的企业级解决方案框架的。你还需要通过开发一个简单的“HelloWorld”应用程序来看一下这些代码。需要阅读如下相关的主题:CompositeApplicationLibrarySeparatedPresentation和DependencyInjection模式容器(Container)设计概念:Container、Services、EventAggregator和UIComposition1.2.3深度评估在决定为你的应用程序使用Prism之前,你可能想要执行一次深度评估。Prism推荐你评估QuickStart和StockTraderRI,并考虑开发一个基于概念的应用程序,以获得对这个类库的深度理解。在这一点上,你还应该考虑到对该类库所需要的扩展和优化,这将帮助你满足你的企业级需求。Prism建议你阅读下面相关的内容:BootstrapperModuleShellandViewCommandsCommunicationMulti-Targeting检查QuickStart熟悉StockTraderRI1.2.4采纳Prism具有一个明确的目标,就是提供一个好的使用体验。为了完成这个目标,Prism提供了下面的建议:你可以使用或不使用Prism类库。例如,你可以只使用你所需要的服务。你可以增长性地添加Prism类库到你已有的WPF或Silverlight应用程序中。你可以创建WPF和Silverlight应用程序以共享尽可能多的代码。为了使用Prism,你将要执行下面的任务:决定你将如何使用类库的:按照原先的样子,或者,自定义适合你需要的类库。对在KeyDecision中描述的关键决定进行决策,并和Team的其它成员进行交流。2Prism的基本概念2.1被引导的Windows窗体Shellwpf程序在启动时,需要一个宿主容器,一般情况下是System.Windows.Window,以下是一个刚创建的窗体.Windowx:Class=HelloWorldSample.Window1xmlns=:x==Window1Height=300Width=300Grid/Grid/Window默认情况下,System.Windows.Application会通过设置StartupUri来运行主窗体.Applicationx:Class=HelloWorldSample.Appxmlns=:x==Window1.xaml/Application接着随着prism框架的加入,运行主窗体的方式改变了.因为prism要在窗体运行之前做一堆事情,来为框架可以做的事情做铺垫.所以我们要去掉StartupUri,手动启动窗体.prism通过一个名为Bootstrapper类作为引导程序,这里我们先不管他做了什么,只知道他起了程序的引导作用.通过Bootstrapper的引导,这个窗体就不再仅仅是一个单纯的窗体了,这个窗体我们也可以称为Shell,也可以理解为一个壳的意思.2.2被附加的内容区域Regionprism框架通过附加属性的方式给Shell定义自定义区域,标题说是附加的内容区域,如下代码,通过附加属性的方式给ItemsControl定义了一个Region,ItemsControl就变成这个Region的容器了.这里的Region与asp.net母版页的ContentPlaceHolder的意义是相同的,只不过实现方式不同罢了.Windowx:Class=HelloWorldSample.Shellxmlns=:x=:cal==CompositeApplicationLibrarySampleWidth=400Height=300ItemsControlcal:RegionManager.RegionName=MainRegion//Window注意:在这里通过RegionManager附加属性RegionName注册的区域的功能,是在该窗体实例化之前,通过Bootstrapper提供的,这就是上面的铺垫作用.2.3被拆分的模块Module定义好Region内容区域以后,可以在Region中加载不同模块的用户控件.每个模块都有着不同功能,一个功能强大的应用程序就是由不同的模块组成的.将应用程序的不同功能,拆分成不同的小模块开发,复杂度明显就会降低.3Region的使用3.1wpf的内容控件继承自ContentControl控件的,我们称之为内容控件.ContentControlContent=/ContentControlContentControl控件定义了一个Content,在没有框架的情况下,也可以将其作为一个内容区域.然而为了满足ui的需求,我们还需要各种不同的控件来当内容区域,如TabControl,DockPanel,Selector等。有些控件则继承自ItemsControl属于集合控件,不属于内容控件.但他们根据不同需求,同时都可以当容器使用,但他们的使用方式却不同.为了统一对内容区域的操作,prism提供了一种适配模式,也可以说提供了控件与Region的映射关系.将不同可以作为容器的控件的操作方式统一为Region的操作方式.prism内置有三种控件可以作为内容区域适配对象ContentControlItemsControlSelector看起来只有三个,但是只要是继承自这三个控件的其他控件也可以.下面介绍使用方法.3.2Region的基本操作,以下以HelloWorld为示例3.2.1在Shell中注册内容区域如下代码,是prism注册的命名空间.用RegionManager的附加属性RegionName注册了一个名叫MainRegion的内容区域Windowx:Class=HelloWorldSample.Shellxmlns=:x=:cal==CompositeApplicationLibrarySampleWidth=400Height=3