silverlight   发布时间:2022-05-03  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了Prism研究(for WPF & Silverlight)5.Module研究大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

概述

终于要坐下来说一说Module的相关技术了。       本来不想讨论Module,因为一旦写好这些框框,以后就再也不会改变了。要知道,我们在Prism中更关心的是MVP模式的拆分。       Module相关技术包括两部分,一是如何加载Module,也就是在SHell的Bootstarpper中重写它的InitializeModules方法,从而把所有需要的Module加载到主程序中。二是如何
终于要坐下来说一说Module的相关技术了。

      本来不想讨论Module,因为一旦写好这些框框,以后就再也不会改变了。要知道,我们在Prism中更关心的是MVP模式的拆分。

      Module相关技术包括两部分,一是如何加载Module,也就是在SHell的Bootstarpper中重写它的InitializeModules方法,从而把所有需要的Module加载到主程序中。二是如何创建映射,即在每个Module内,实现IModule接口的Initialize方法,从而建立Region和View之@L_757_3@mapping关系。

      (一)在Bootstarpper中加载模块:对抽象类UnityBootstrapper的实现

      UnityBootstrapper这个类可称得上是Prism框架的中枢神经。

      我们知道,在App.xaml.cs中,执行的是Bootstarpper类的Run方法,就在这方法中,都包括了哪些关键步骤呢?

            1.调用ConfigureContainer()方法,配置容器。包括3小步:

                  1)注入ILoggerFacade,于是我们可以定义自己的Log系统,这个技术我会在以后章节单独介绍。

                  2)调用GetModuleCatalog方法,从而获取注册全部Module。我们通常会重写这个方法

                  3)根据Run方法中的布尔值(认为true),决定是否要注册8对接口和相应的类:

            我们经常会重写这个方法,从而加上自己的逻辑,存在两种场景:

                  1) 基类方法注册的Mapping不满意,注销其中的一个或全部。代码如下:

                  2) 当我们想要连SHell都进行MVP模式重构时,以下是strokeTrader RI中的示例代码

            2.调用ConfigureRegionAdapterMappings方法注册基础控件和相应适配器之@L_757_3@mapping关系。WPF下有3个基础控件(SELEctor、ItemsControl、ContentControl,我们经常使用的是ContentControl),在Silverlight下还要额外注册TabControl。

            我们可以定义自己的适配器,这将在以后章节中看到。

            这三个基础控件的使用场合是什么呢?我一开始是很明白的,后来完全被Prism自带的Sample搞糊涂了。我会在RI项目分析时,讨论这个问题。

            3.调用ConfigureDefaultRegionBehaviors方法,配置Behavior。

            这块涉及到另一门新的技术了,我准备另开章节,这里不宜展开。

            4.调用RegisterFrameworkExceptionTypes方法,这涉及到Prism内部的异常处理机制,再议再议。

            5.调用CreateSHell方法,注意到,UnityBootstrapper类之所以是抽象的,就是因为这个方法是虚的,所以我们要重写它,创建并返回SHell窗体对象,并依赖注入IRegionManager对象。

            6.调用InitializeModules方法,决定了哪些Module要被加载。终于说到这里了,累死我了。这个方法是要仔细分析的。

            如何把Module加载到SHell中呢?一种方式就是重写前面的GetModuleCatalog方法,如下所示:

            另一种方式就是重写InitializeModules方法了,也能达到同样的效果

            只是这次,我们要手动@L_286_8@module的Initialize方法了。

            而在GetModuleCatalog方法中是自动加载Module的:实例化ModuleManager,依次调用该实例的Run方法——LoadModulesWhenAvailable方法——LoadModuleTypes方法——LoadModulesThatAreReadyForLoad方法——InitializeModule方法——@L_286_8@moduleInitializer实例的Initialize方法——调用IModule的Initialize方法

            终于绕出来了,算是殊途同归了吧。

            那么,为什么要有两种调用方法呢?我曾经困惑过一段时间,莫衷一是。不过在研究了Prism框架的源码时候我明白了,这两个方法都是可以重写的,只是调用GetModuleCatalog方法的位置位于InitializeModules的前面,我们可以任选一个而忽略另一个。什么?你要在GetModuleCatalog方法中加载ModuleA,而在InitializeModules方法中加载ModuleB——等着被同事Complaint吧。

            现在我们着重分析GetModuleCatalog方法

            通常有两种加载模块的方式:一,手动编码加载;二,在配置文件中设置。

            此外,在WPF中,还可以遍历目录进行加载;而在Silverlight中,又有一种RemoTing加载的技术。

            Prism文档为这4种技术分别提供了一个Demo。依次讨论如下:

            @H_683_301@1.手动加载Module

            参加目录\Quickstarts\Modularity\DefiningModulesInCodeQuickstart

            这种方式是很直接的。就像我们刚才写的代码那样:

            不要小看这几行代码,麻雀小五脏俱全,涵盖了手动加载的所有技巧。

            效果图如下:

Prism研究(for WPF & Silverlight)5.Module研究

            最好是F5一步步调试,就可以看到,先加载模块B,然后是D,最后是A。而模块C开始时并不显示,只有当点击模块B中的按钮时,才会显示

Prism研究(for WPF & Silverlight)5.Module研究

            这是因为,AddModule方法有5种重载:

            在前两个重载方法中,我们指定了第1个参数moduleType为模块的类型,而dependsOn参数指定了前面的模块依赖于后面这个模块,initializationMode参数是一个枚举。

            WhenAvailable是认选项,就是说一开始就加载;而ondemand则表示按需加载,一开始并不会进行加载。因为我们在代码中指定了

            所以,一开始并不会显示模块C。在点击模块B中按钮的时候,@L_286_8@moduleManager实例的LoadModule方法

            顺藤摸瓜,沿着LoadModule方法一级级找下去——调用LoadModuleTypes方法——LoadModulesThatAreReadyForLoad方法——InitializeModule方法——@L_286_8@moduleInitializer实例的Initialize方法——调用IModule的Initialize方法。于是,模块C被加载了。

            第3个和第4个重载方法不常用,因为modulename实际上就是moduleType.Name。第5个重载方法是给Silverlight用的,它有一个refValue参数,用来指定远程XAP的地址。

@H_683_301@2.根据配置文件动态加载Module

            还是刚才那个效果,我们把模块的前后顺序和依赖关系写在App.config的配置节点modules中:

            这样的话,我只需在GetModuleCatalog方法中直接返回ConfigurationModuleCatalog对象就可以了:

            罗嗦几句,根据配置文件加载Module的方式远远优于手动编程的方式,然配置起来很麻烦,但是在大型项目中是首选。

 

      (二)具体Module内的编程:IModule接口

      Module介于SHell和View之间,我们可以认为它是View的载体。因此,在把一个复杂的xaml拆分成若干零散的View的时候,我们会手动创建若干以Module名称命名的项目,并把这些View按照类别放到不同的Module项目中。比如说Prism自带的StrockTraderRI(简称RI),参下面的截图:

Prism研究(for WPF & Silverlight)5.Module研究

      看到没有,RI有4个Module,它们都作为项目而存在,并且每个项目都带有一个类似于MarketModule这样的类,它派生自接口IModule:

      于是,实现了IModule接口的类,都具有这样的格式:

      我们看到:

            1.要在构造函数中实现依赖注入,需要什么就注入什么。

            2.实现Initialize方法包括

                  1)在容器中注册接口和实现了该接口的类的mapping关系,比如说service、View、Model、Presenter,我们一般都会同时添加相应的接口。我们将这些注册封装在一个名为RegisterViewsAndservices的方法中。

                  2)还要在Initialize方法中,注册Register和View之间的关系,也就是RegisterViewWithRegion方法

            所有的Module类都是按照这样的格式来实现。而关于注册View的技术,还有一些小变体。

            比如说,我们可以把

      替换为:

      这里,regionViewRegistry的声明和注入是这样的

      这就引入了一个新的问题,IRegionViewRegistry和IRegionManager都具有RegisterViewWithRegion方法,二者有区别么?

      答案是——没有。我们已经分析过,在UnityBootstrapper的中,已经认建立了IRegionManager和RegionManager的映射关系。所以,只要查看Prism框架中的RegionManager就可以了。

      以下则是RegionManager的RegisterViewWithRegion方法,这是一个扩展方法

      哦,原来还是要间接地调用RegionViewRegistry的RegisterViewWithRegion方法

      还是那句老话,殊途同归。

 

 

@H_683_301@下回内容提示

      我们还可以把

      替换为:

      ——这就涉及到了View的两种模式:View Injection和View Discovery。

 

      我们还可以将其替换为:

      ——这就涉及到了MVP的两种变体:View -first和Presenter-first。

 

      欲知详情,请看下回《Prism研究——MVP模式之七十二变》。

大佬总结

以上是大佬教程为你收集整理的Prism研究(for WPF & Silverlight)5.Module研究全部内容,希望文章能够帮你解决Prism研究(for WPF & Silverlight)5.Module研究所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。