Prism 5程序初始化过程

Prism在运行程序前,需要的组件像其他大部分程序架构一样在初始化阶段完成。Prism将这个启动加载器命名为Bootstarpper。在Bootstarpper中,按顺序加载一系列组件,如,moduleCatalog,container,还有UI的 regionAdapter,shell和module等等。

Bootstrapper

在Prism中,自带有基于Unity和MEF两种DI容器的Bootstrapper,分别为UnityBootstrapper和MEFBootstrapper。此文所有介绍都基于UnityBootstrapper,当然我们也可以定义自己的启动器(开闭原则,在后面的文章中还有很多类似的设计原则和设计模式)。Bootstrapper大部分方法是虚拟方法,定义如下:

  1 #region 程序集 Microsoft.Practices.Prism.Composition.dll, v5.0.0.0
  2 // F:\RefrenceProject\compositewpf-ff6316df3dadd0d24083d51aa1dea922d07fb47e\V5\Quickstarts\Hello World\HelloWorld.Desktop\packages\Prism.Composition.5.0.0\lib\NET45\Microsoft.Practices.Prism.Composition.dll
  3 #endregion
  4
  5 using Microsoft.Practices.Prism.Logging;
  6 using Microsoft.Practices.Prism.Modularity;
  7 using Microsoft.Practices.Prism.Regions;
  8 using System;
  9 using System.Windows;
 10
 11 namespace Microsoft.Practices.Prism
 12 {
 13     // 摘要:
 14     //     Base class that provides a basic bootstrapping sequence and hooks that specific
 15     //     implementations can override
 16     //
 17     // 备注:
 18     //     This class must be overridden to provide application specific configuration.
 19     public abstract class Bootstrapper
 20     {
 21         protected Bootstrapper();
 22
 23         // 摘要:
 24         //     Gets the Microsoft.Practices.Prism.Logging.ILoggerFacade for the application.
 25         protected ILoggerFacade Logger { get; set; }
 26         //
 27         // 摘要:
 28         //     Gets the default Microsoft.Practices.Prism.Modularity.IModuleCatalog for
 29         //     the application.
 30         protected IModuleCatalog ModuleCatalog { get; set; }
 31         //
 32         // 摘要:
 33         //     Gets the shell user interface
 34         protected DependencyObject Shell { get; set; }
 35
 36         // 摘要:
 37         //     Configures the Microsoft.Practices.Prism.Regions.IRegionBehaviorFactory.
 38         //     This will be the list of default behaviors that will be added to a region.
 39         protected virtual IRegionBehaviorFactory ConfigureDefaultRegionBehaviors();
 40         //
 41         // 摘要:
 42         //     Configures the Microsoft.Practices.Prism.Modularity.IModuleCatalog used by
 43         //     Prism.
 44         protected virtual void ConfigureModuleCatalog();
 45         //
 46         // 摘要:
 47         //     Configures the default region adapter mappings to use in the application,
 48         //     in order to adapt UI controls defined in XAML to use a region and register
 49         //     it automatically.  May be overwritten in a derived class to add specific
 50         //     mappings required by the application.
 51         //
 52         // 返回结果:
 53         //     The Microsoft.Practices.Prism.Regions.RegionAdapterMappings instance containing
 54         //     all the mappings.
 55         protected virtual RegionAdapterMappings ConfigureRegionAdapterMappings();
 56         //
 57         // 摘要:
 58         //     Configures the LocatorProvider for the Microsoft.Practices.ServiceLocation.ServiceLocator.
 59         protected abstract void ConfigureServiceLocator();
 60         //
 61         // 摘要:
 62         //     Create the Microsoft.Practices.Prism.Logging.ILoggerFacade used by the bootstrapper.
 63         //
 64         // 备注:
 65         //     The base implementation returns a new TextLogger.
 66         protected virtual ILoggerFacade CreateLogger();
 67         //
 68         // 摘要:
 69         //     Creates the Microsoft.Practices.Prism.Modularity.IModuleCatalog used by Prism.
 70         //
 71         // 备注:
 72         //     The base implementation returns a new ModuleCatalog.
 73         protected virtual IModuleCatalog CreateModuleCatalog();
 74         //
 75         // 摘要:
 76         //     Creates the shell or main window of the application.
 77         //
 78         // 返回结果:
 79         //     The shell of the application.
 80         //
 81         // 备注:
 82         //     If the returned instance is a System.Windows.DependencyObject, the Microsoft.Practices.Prism.Bootstrapper
 83         //     will attach the default Microsoft.Practices.Prism.Regions.IRegionManager
 84         //     of the application in its Microsoft.Practices.Prism.Regions.RegionManager.RegionManagerProperty
 85         //     attached property in order to be able to add regions by using the Microsoft.Practices.Prism.Regions.RegionManager.RegionNameProperty
 86         //     attached property from XAML.
 87         protected abstract DependencyObject CreateShell();
 88         //
 89         // 摘要:
 90         //     Initializes the modules. May be overwritten in a derived class to use a custom
 91         //     Modules Catalog
 92         protected virtual void InitializeModules();
 93         //
 94         // 摘要:
 95         //     Initializes the shell.
 96         protected virtual void InitializeShell();
 97         //
 98         // 摘要:
 99         //     Registers the System.Types of the Exceptions that are not considered root
100         //     exceptions by the Microsoft.Practices.Prism.ExceptionExtensions.
101         protected virtual void RegisterFrameworkExceptionTypes();
102         //
103         // 摘要:
104         //     Runs the bootstrapper process.
105         public void Run();
106         //
107         // 摘要:
108         //     Run the bootstrapper process.
109         //
110         // 参数:
111         //   runWithDefaultConfiguration:
112         //     If true, registers default Prism Library services in the container. This
113         //     is the default behavior.
114         public abstract void Run(bool runWithDefaultConfiguration);
115     }
116 }

Bootstrapper初始化的顺序如下:

上图不难理解,软件记录日志,包括Bootstrapper的启动过程,所以Logger启动在第一位,生成和配置DI容器放在第三位,因为下面所有的操作依赖于使用容器解耦,,ModuleCatalog,并不依赖DI容器,可以放在第二位,下面的RegionAdapter和RegionBehavior也差不多意思,至于为什么Module放在最后,其实也无他,也是因为Module(模块)属于Shell(主窗体)。

因此,在使用Prism前,你必须先决定:

  1. 使用Unity或MEF,或其他DI容器。当然,如果使用其他注入容器,也决定了要自定义Bootstrapper。
  2. 你还可能需要把你程序的服务注册到container(DI容器),以方便各个Module(模块)的解释使用。
  3. 决定内置的日志组件是否适合,否则重写CreateLogger。
  4. 决定如何注册你的Module,使用配置文件还是XAML还是目录发现(需要在模块类使用特征标识 )还是直接写死在代码。

选择DI容器,很easy,熟悉哪种选哪种,使用也很简单,只需要继承一下就可以。

using System.Windows;
using Microsoft.Practices.Prism.Modularity;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Prism.UnityExtensions;

namespace HelloWorld
{
    class Bootstrapper : UnityBootstrapper
    {

    }

Bootstrapper是Prism的入口,因此,要指定APP.xaml的Bootstrapper

 1 using System.Windows;
 2
 3 namespace HelloWorld
 4 {
 5     /// <summary>
 6     /// Interaction logic for App.xaml
 7     /// </summary>
 8     public partial class App : Application
 9     {
10         protected override void OnStartup(StartupEventArgs e)
11         {
12             base.OnStartup(e);
13             Bootstrapper bootstrapper = new Bootstrapper();
14             bootstrapper.Run();
15         }
16     }
17 }

CreateShell

createShell是必须要继承的,因为必须指定主窗体。

    class Bootstrapper : UnityBootstrapper
    {
        protected override DependencyObject CreateShell()
        {
            return this.Container.Resolve<Shell>();
        }
    }

这里使用DI容器的Resolve方法,这种方法的好处是把Shell所有需要的引用的DLL都自动引入。当然也可直接new一个主窗体对象出来。

进一步,可以使用ServiceLocator,ServiceLocator也是IOC的一种实现,类似DI也是IOC的一种实现。ServiceLocator最终还是调用DI容器,至于是Unity还是MEF,这是ServiceLocator要关心的事了,我们在这不作更深入的了解。

protected override DependencyObject CreateShell()
{
    return ServiceLocator.Current.GetInstance<Shell>();
}

InitializeShell

Shell初始化所需的工作应该写在这里。

protected override void InitializeShell()
{
    Application.Current.MainWindow = Shell;
    Application.Current.MainWindow.Show();
}

当然也可以把所有初始化工作写到CreateShell()里,IntializeShell不重写,但总感觉有点怪怪的。

CreateModuleCatalog

在调用CreateModuleCatalog之前,Prism会调用CreateModuleCatalog,生成ModuleCatalog。使用模块化开发,需要实现CreateModuleCatalog方法添加Module。

        protected override void ConfigureModuleCatalog()
        {
            base.ConfigureModuleCatalog();

            ModuleCatalog moduleCatalog = (ModuleCatalog)this.ModuleCatalog;
            moduleCatalog.AddModule(typeof(HelloWorldModule.HelloWorldModule));
        }

ConfigureContainer

配置Container(DI容器),Container在Prism中具有非常重要的角色,在使用Prism开发的代码中,常常见到这个家伙。在Container的配置阶段,需要把核心服务注册到Container,当然也要把业务上的关键服务注册到Container。

基类代码实现如下:

 1         protected virtual void ConfigureContainer()
 2         {
 3             this.Logger.Log(Resources.AddingUnityBootstrapperExtensionToContainer, Category.Debug, Priority.Low);
 4             this.Container.AddNewExtension<UnityBootstrapperExtension>();
 5
 6             Container.RegisterInstance<ILoggerFacade>(Logger);
 7
 8             this.Container.RegisterInstance(this.ModuleCatalog);
 9
10             if (useDefaultConfiguration)
11             {
12                 RegisterTypeIfMissing(typeof(IServiceLocator), typeof(UnityServiceLocatorAdapter), true);
13                 RegisterTypeIfMissing(typeof(IModuleInitializer), typeof(ModuleInitializer), true);
14                 RegisterTypeIfMissing(typeof(IModuleManager), typeof(ModuleManager), true);
15                 RegisterTypeIfMissing(typeof(RegionAdapterMappings), typeof(RegionAdapterMappings), true);
16                 RegisterTypeIfMissing(typeof(IRegionManager), typeof(RegionManager), true);
17                 RegisterTypeIfMissing(typeof(IEventAggregator), typeof(EventAggregator), true);
18                 RegisterTypeIfMissing(typeof(IRegionViewRegistry), typeof(RegionViewRegistry), true);
19                 RegisterTypeIfMissing(typeof(IRegionBehaviorFactory), typeof(RegionBehaviorFactory), true);
20                 RegisterTypeIfMissing(typeof(IRegionNavigationJournalEntry), typeof(RegionNavigationJournalEntry), false);
21                 RegisterTypeIfMissing(typeof(IRegionNavigationJournal), typeof(RegionNavigationJournal), false);
22                 RegisterTypeIfMissing(typeof(IRegionNavigationService), typeof(RegionNavigationService), false);
23                 RegisterTypeIfMissing(typeof(IRegionNavigationContentLoader), typeof(UnityRegionNavigationContentLoader), true);
24             }
25         }

如果我们只是实现业务,不需要对Prism二次开发的话,对业务服务的注册,只需要重写ConfigureContainer即可。

    class Bootstrapper : UnityBootstrapper
    {
        protected override void ConfigureContainer()
        {
            base.ConfigureContainer();

            this.RegisterTypeIfMissing(typeof(IModuleTracker), typeof(ModuleTracker), true);
            this.Container.RegisterInstance<CallbackLogger>(this.callbackLogger);
        }
    }

至此,Prism的初始化已介绍完毕。

时间: 2024-10-07 06:28:59

Prism 5程序初始化过程的相关文章

Prism 文档 第二章 初始化Prism应用程序

                                                                       第二章 初始化Prism应用程序 本章将讨论为了使一个Prism应用程序的启动和运行哪些是必须的.Prism的应用程序在启动过程中需要注册和配置,这被称为引导应用程序. 什么是Bootstrapper? bootstrapper是一个类,通过Prism类库负责一个应用程序建立的初始化.通过使用bootstrapper,对于如何将Prism库组件连接到您的应

Prism4 文档翻译系列---第2章:初始化Prism应用程序

这一章节介绍Prism应用程序启动和运行时发生的内容.Prism应用程序在启动时需要有注册和配置的过程,这就是所谓的自自启动程序. 什么是自启动引导程序?     引导程序是一个类,它负责使用Prism库构建的应用程序的初始化.通过使用引导程序,你有更多的控制权使得Prism库组件如何连接到你的应用程序. Prism库包括可被专门用于与任何容器使用一个默认的抽象的引导程序基类.许多在引导程序类的方法都是虚方法.您可以在自己的自定义引导程序中覆盖这些方法. 在自启动过程的基本阶段 Prism库提供

JAVA对象的初始化过程

出处:http://blog.csdn.net/andrew323/article/details/4665379 下面我们通过两个例题来说明对象的实例化过程. 例1:   编译并运行该程序会有以下输出 Static Block Employee Company:china soft Non-Static Block Employee phone:0755-51595599 Employee(String) Empoloyee() 下面我们来对结果做分析: 1 在代码34行实例化对象时, 先对给

Delphi Android程序启动过程

Delphi的Android程序是原生的程序,也就是NativeActivity.那么就需要先看一下NativeActivity的原理, 在AndroidManifest.xml文件里面指定入口activity为nativeactivity,这样应用程序一启动,java虚拟机这边就开一个主线程,主线程创建一个活动,就是nativeactivity,这个nativeactivity在创建的过程中就会去应用程序的.so动态链接库中寻找一个函数: __ANativeActivity_onCreate(

Java对象相关元素的初始化过程

1.类的成员变量.构造函数.成员方法的初始化过程 当一个类使用new关键字来创建新的对象的时候,比如Person per = new Person();JVM根据Person()寻找匹配的类,然后找到这个类相匹配的构造方法,这里是无参构造,如果程序中没有给出任何构造方法,则JVM默认会给出一个无参构造.当创建一个对象的时候一定对调用该类的构造方法,构造方法就是为了对对象的数据进行初始化.JVM会对给这个对象分配内存空间,也就是对类的成员变量进行分配内存空间,如果类中在定义成员变量就赋值的话,就按

Java初始化过程

以下程序执行的结果是: class X{ Y y=new Y(); public X(){ System.out.print("X"); } } class Y{ public Y(){ System.out.print("Y"); } } public class Z extends X{ Y y=new Y(); public Z(){ System.out.print("Z"); } public static void main(Stri

启动期间的内存管理之初始化过程概述----Linux内存管理(九)

日期 内核版本 架构 作者 GitHub CSDN 2016-06-14 Linux-4.7 X86 & arm gatieme LinuxDeviceDrivers Linux内存管理 在内存管理的上下文中, 初始化(initialization)可以有多种含义. 在许多CPU上, 必须显式设置适用于Linux内核的内存模型. 例如在x86_32上需要切换到保护模式, 然后内核才能检测到可用内存和寄存器. 而我们今天要讲的boot阶段就是系统初始化阶段使用的内存分配器. 1 前景回顾 1.1

在程序运行过程中,对象所占的空间是不能随时释放的

使用类名定义的对象(请查看:C++类的声明和对象的定义)都是静态的,在程序运行过程中,对象所占的空间是不能随时释放的.但有时人们希望在需要用到对象时才建立对象,在不需要用该对象时就撤销它,释放它所占的内存空间以供别的数据使用.这样可提高内存空间的利用率. 在C++中,可以使用new运算符动态地分配内存,用delete运算符释放这些内存空间(请查看:C++动态分配内存(new)和撤销内存(delete)).这也适用于对象,可以用new运算符动态建立对象,用delete运算符撤销对象. 如果已经定义

Mybatis深入之初始化过程

Mybatis深入之初始化过程 一:简介 这篇开始是根据Mybatis源码来对Mybatis进行更深入的学习.当然.精力有限.还做不到学习的面面俱到. Mybatis初始化过程可以用一句话概括:就是将Mybatis的配置信息加载到一个类中.供后面Mybatis进行各种操作时使用.这个类叫:Configuration--见名知意.当然这个类的功能并不仅限与存放配置文件信息. 二:整体流程 下面是一段正常情况下从加载配置到执行sql语句的代码: String mybatisConfigPath =