这一章节介绍Prism应用程序启动和运行时发生的内容。Prism应用程序在启动时需要有注册和配置的过程,这就是所谓的自自启动程序。
什么是自启动引导程序?
    引导程序是一个类,它负责使用Prism库构建的应用程序的初始化。通过使用引导程序,你有更多的控制权使得Prism库组件如何连接到你的应用程序。
    Prism库包括可被专门用于与任何容器使用一个默认的抽象的引导程序基类。许多在引导程序类的方法都是虚方法。您可以在自己的自定义引导程序中覆盖这些方法。
在自启动过程的基本阶段
    Prism库提供了一些额外的基类,从引导程序而得,具有默认实现,适用于大多数应用。留下您的应用程序的引导程序来实现创建和初始化Shell的唯一阶段。
依赖注入
    内置的Prism库的应用程序依赖于一个容器提供的依赖注入。该库提供了与Unity应用程序块(单位)或托管扩展性框架(MEF)的工作组件,它允许你使用其他的依赖注入容器。在引导过程的一部分是配置这个容器并注册类型的容器。
    Prism库包括UnityBootstrapper和MefBootstrapper类,实现最必要的功能,无论是使用Unity或MEF在你的应用程序的依赖注入容器。除了在前面的图中所示的阶段中,每个引导程序添加特定于它的容器的一些步骤。
创建Shell
    在传统的WPF应用程序中,App.xaml文件中使用启动统一资源标识符(URI)指定启动主窗口。在Silverlight应用程序,App.xaml文件后台代码中使用RootVisual属性来设置启动界面窗口。
    在使用Prism类库创建的应用程序中,引导程序负责创建Shell或主窗口。这是因为Shell依赖于服务,例如该区域管理器,在Shell中显示之前需要注册。
关键决定
    在你决定在你的应用程序中使用Prism后,这里还有一系列额外的决定需要你去做:
  • 你需要去决定是否使用MEF,Unity或者其他的依赖注入容器,这将决定你将使用哪个引导程序类或者你需要自己为其他的依赖注入容器创建一个引导程序类
  • 你需要考虑清楚应用程序的单独的服务,这需要在容器中被注册
  • 决定是否使用内置的日志服务或者你需要自己创建另外的日志服务
  • 决定模块是如何被应用程序查找并加载:代码方式明确声明,代码方式标记模块的属性,扫描路径,配置或者在XAML中

剩下的章节将会提供更多的细节

 
核心方案
    搭建你的Prims应用程序用一个重要的部分就是创建一个启动队列,本节将讲述如何创建一个引导程序并自定义它去创建Shell,配置依赖注入容器,注册应用程序级服务,以及如何加载和初始化模块。
为你的应用程序创建引导程序
    如何你选择了Unity或者MEF作为你的依赖注入容器,创建一个简单的引导程序将会非常简单,你需要创建一个继承于MefBootstrapper 或者UnityBootstrapper的类,然后,实现CreateShell方法,作为可选的,你可能会为了一个特殊初始化Shell重写InitializeShell方法。
 
实现CreateShell方法
    CreateShell方法允许一个开发人员指定Prism应用程序的顶层窗口,这个Shell就是通常讲的 MainWindow 或 MainPage.通过返回应用程序的Shell类的实例来实现这个方法,在Prism应用程序中国,你可以创建Shell对象,或者从容器中解析,这依赖于你的应用程序的需求。
下面的代码实例中展示了使用ServieLocator来解析Shell对象
protected override DependencyObject CreateShell()
{
return ServiceLocator.Current.GetInstance<Shell>();
}
    注意:你将会经常看到ServiceLocator被用作解析类型的实例而不是作为特殊的依赖注入容器,SericeLocator被调用者实现,所以它是一个很不错的选择使得容器与具体代码无关,当然,你也可以直接引用并使用容器来替代SericeLocator。
 

实现InitializeShell 方法

    当你创建了一个Shell之后,你将会运行初始化步骤来确保这个Shell已经可以被显示,根据你创建的是一个WPF或者Silverlight应用程序,这个InitalShell方法将会不同。

在Sliverlight应用程序中,你将会看到Shell作为应用程序的visual root,如下所示:

protected override void InitializeShell()
{
Application.Current.RootVisual = Shell;
}
    在WPF应用程序中,你将创建应用程序的Shell对象,并将它设置为应用程序的主窗口,如下所示(来自Modularity QuickStarts for WPF工程)
protected override void InitializeShell()
{
Application.Current.MainWindow = Shell;
Application.Current.MainWindow.Show();
}
在InitialzeShell方法的基类实现中不做任何事情,不去调用基类的实现将是安全的。
 
创建并配置模块目录
    如果你实在搭建一个模块化的应用程序,你需要创建并配置一个模块目录,Prism使用了一个IModuleCatalog的具体实例来保存系统中可用的模块,哪些模块需要被下载,模块的位置的跟踪。
    Bootstrapper提供了一个受保护的ModuleCatalog属性作为目录的引用同时也是虚方法CrateModuleCatalog的实现,在基类的实现中返回了一个新的ModuleCatalog;然而,这个方法可以被重写去提供一个不同的IModuleCatalog对象,例如下面来自Modularity with MEF for Silverlight QuickStart中的QuickStartBootstrapper工程中的代码
protected override IModuleCatalog CreateModuleCatalog()
{
// When using MEF, the existing Prism ModuleCatalog is still
// the place to configure modules via configuration files.
return ModuleCatalog.CreateFromXaml(new Uri(
"/ModularityWithMef.Silverlight;component/ModulesCatalog.xaml",
UriKind.Relative));
}
    在UnityBootstrapper 和 MefBootstrapper类中,Run方法调用CreateModuleCatalog方法并且用方法返回值来设置类的ModuleCatalog属性,如果你重写了这个方法,调用基类的实现并不是必须的,因为你将会替换掉方法的功能,关于模块的更多的信息,请查看第四章的"Modular Application Development."
创建并配置容器
    在使用Prism创建的应用程序中,容器扮演着一个关键的角色,无论是Prism类库和建立在它之上的应用程序依赖于容器中注入需要的依赖和服务。在容器配置的阶段,一些核心的服务被注册,除了这些核心服务,您可能必须提供额外的功能,因为它涉及到组成应用程序特定的服务。
核心服务
下面的表列出了Prism库中的核心的非特定应用的服务。

服务接口

描述

IModuleManager

定义检索并初始化应用程序模块的服务的接口。

IModuleCatalog

包含应用程序的模块中的元数据。Prism库提供了几个不同的目录。

IModuleInitializer

初始化模块

IRegionManager

注册和检索的区域,这是可视化的容器进行布局。

IEventAggregator

发布者和订阅者之间的松耦合事件的集合。

ILoggerFacade

一个日志机制的封装,所以你可以选择你自己的日志记录机制, 例如,你可以 通过EnterpriseLibraryLoggerAdapter类使用企业级类库Stock Trader Reference Implementation (Stock Trader RI)记录应用程序块。通过在引导程序中Run方法使用的CreateLogger 方法的返回值,日志服务被注册在容器内。 在引导程序中不去重写CreateLogger 方法而在在容器中注册另一个记录器将不起作用。

IServiceLocator

允许Prism类库访问容器,如果你想自定义或者扩展类库,它或许将很有用。

应用程序特定服务
下表列出了在 Stock Trader RI中使用的应用程序特定的服务。这可以被用来作为一个例子来理解服务应用程序可能会提供的类型。
 

Stock Trader RI中的服务

描述

IMarketFeedService

提供了实时的 (模拟) 市场数据. 当从服务中收到数据时PositionSummaryPresentationModel 将会更新屏幕上的点的位置

IMarketHistoryService

提供用于显示的趋势线所选基金历史市场数据。

IAccountPositionService

提供资金的投资组合名单。

IOrdersService

持续提交的买/卖订单。

INewsFeedService

提供选定基金的新闻条目。

IWatchListService

处理被添加到观察名单中的新条目

Prism提供了两种引导程序的派生类:UnityBootstrapper 和 MefBootstrapper,通过不同的实现方式创建和配置容器包含的那些类似的概念。
在UnityBootstrapper 中创建并配置容器
    UnityBootstrapper 类中的CreateContainer方法只是简单的创建并返回了一个UnityContainer的实例,,在大多数情况下,您不需要更改此功能;然而,该方法是虚方法,从而具有灵活性。
    在容器被创建之后,肯呢个需要为你的应用程序做些配置,在UnityBootstrapperConfigureContainer的实现中默认注册了一系列Prism核心的服务,如下所示:
    注意:这是一个当某个模块在Initialze方法中注册模块级服务的例子。
C# UnityBootstrapper.cs
protected virtual void ConfigureContainer()
{
...
if (useDefaultConfiguration)
{
RegisterTypeIfMissing(typeof(IServiceLocator), typeof(UnityServiceLocatorAdapter), true);
RegisterTypeIfMissing(typeof(IModuleInitializer), typeof(ModuleInitializer), true);
RegisterTypeIfMissing(typeof(IModuleManager), typeof(ModuleManager), true);
RegisterTypeIfMissing(typeof(RegionAdapterMappings), typeof(RegionAdapterMappings), true);
RegisterTypeIfMissing(typeof(IRegionManager), typeof(RegionManager), true);
RegisterTypeIfMissing(typeof(IEventAggregator), typeof(EventAggregator), true);
RegisterTypeIfMissing(typeof(IRegionViewRegistry), typeof(RegionViewRegistry), true);
RegisterTypeIfMissing(typeof(IRegionBehaviorFactory), typeof(RegionBehaviorFactory), true);
}
}

引导程序的RegisterTypeIfMissing 方法 决定了一个服务是否已经被注册,它不会被重复注册,这允许你可以通过配置来重写默认的注册信息,你也可以关闭默认注册任何服务;要做到这一点,使用重载Bootstrapper.Run方法并传入false。你也可以重写方法并且禁用你不想使用的服务,例如事件聚合器。

注意:如果你关闭的morning注册的服务,你需要手动的注册一些必须的服务。

为了扩展ConfigureContainer的默认行为,只需添加一个覆盖你的应用程序的引导程序的实现并且可选调用基类的实现,就像下面来自Modularity for WPF (with Unity) QuickStart中QuickStartBootstrapper工程中的代码一样,在它的实现中调用了基类的实现,注册了IModuleTracker的实现ModuleTracker类型,并且使用Unity注册了CallbackLogger的单例callbackLogger。

C#
protected override void ConfigureContainer()
{
base.ConfigureContainer(); this.RegisterTypeIfMissing(typeof(IModuleTracker), typeof(ModuleTracker), true);
this.Container.RegisterInstance<CallbackLogger>(this.callbackLogger);
}
在MefBootstrapper中创建并配置容器

    MefBootstrapper 类的CreateContainer 方法做了几件事情。首先,他创建了AssemblyCatalog 和CatalogExportProvider。CatalogExportProvider允许MefExtensions程序集提供一系列Prism类型的导出,而且允许你重写默认的注册。CreateContainer使用CatalogExportProvider创建并返回了CompositionContainer的实例,在大多数情况下,您不需要更改此功能;然而,该方法是虚方法,从而具有灵活性。

注意:在Silverlight中,由于安全限制,不能使用类型信息来检索程序集,作为替代,Prism使用另外的方法,就是使用Assembly.GetCalllingAssembly方法来实现。

在容器被创建之后,肯呢个需要为你的应用程序做些配置,在MefBootstrapperConfigureContainer的实现中默认注册了一系列Prism核心的服务,如下所示:如果重写此方法,慎重考虑是否应该调用基类的实现注册Prism核心服务,或者您会在您的实现提供这些服务。

C#
protected virtual void ConfigureContainer()
{
this.RegisterBootstrapperProvidedTypes();
} protected virtual void RegisterBootstrapperProvidedTypes()
{
this.Container.ComposeExportedValue<ILoggerFacade>(this.Logger);
this.Container.ComposeExportedValue<IModuleCatalog>(this.ModuleCatalog);
this.Container.ComposeExportedValue<IServiceLocator>(new MefServiceLocatorAdapter(this.Container));
this.Container.ComposeExportedValue<AggregateCatalog>(this.AggregateCatalog);
}

注意:在MefBootstrapper中,Prism的核心服务是以单例的形式添加到容器中的,所以他们可以在整个应用程序中通过容器来定位。

    此外,CreateContainer 和 ConfigureContainer 方法中,MefBootstrapper也提供了两个方法来创建并且配置MEF使用的AggregateCatalog,CreateAggregateCatalog方法仅仅创建并返回了AggregateCatalog对象,就像MefBootstrapper中的其他方法一样,CreateAggregateCatalog是个虚方法,必要时可以重写。
ConfigureAggregateCatalog方法允许你向AggregateCatalog命令式的添加类型注册。例如,来自 the Modularity with MEF for Silverlight QuickStart的QuickStartBootstrapper明确地向AggregateCatalog添加了ModuleA和ModuleC,如下所示。
C#
protected override void ConfigureAggregateCatalog()
{
base.ConfigureAggregateCatalog();
// Add this assembly to export ModuleTracker
this.AggregateCatalog.Catalogs.Add(
new AssemblyCatalog(typeof(QuickStartBootstrapper).Assembly));
// Module A is referenced in in the project and directly in code.
this.AggregateCatalog.Catalogs.Add(
new AssemblyCatalog(typeof(ModuleA.ModuleA).Assembly)); // Module C is referenced in in the project and directly in code.
this.AggregateCatalog.Catalogs.Add(
new AssemblyCatalog(typeof(ModuleC.ModuleC).Assembly));
}
更多信息
如果想要了解关于MEF, AggregateCatalog, 以及 AssemblyCatalog,的更多信息,请查阅MSDN上的"Managed Extensibility Framework Overview" :http://msdn.microsoft.com/en-us/library/dd460648.aspx.  
 

Prism 4 文档 ---第2章:初始化Prism应用程序的更多相关文章

  1. Prism 4 文档 ---第11章 部署Prism应用程序

        要成功移动Prism应用到生产中,需要对部署计划为应用程序的设计过程的一部分.本章介绍了注意事项和你需要采取的准备以部署应用程序,以及你要在用户手中获得部署程序所需要采取的行动.     Si ...

  2. Prism 4 文档 ---第7章 组成用户界面

    一个应用程序的用户界面(UI)可以通用以下几种模式之一来构建: 窗体所需要所有的控件都包含在一个单独的XAML文件中,在设计时组合这个窗体. 窗体的逻辑区域被分割到单独的部分中,通常指哟过户控件.这些 ...

  3. Prism 4 文档 ---第3章 管理组件间的依赖关系

     基于Prism类库的应用程序可能是由多个松耦合的类型和服务组成的复杂应用程序,他们需要根据用户的动作发出内容和接收通知进行互动,由于他们是松耦合的,他们需要一种方式来互动和交流来传递业务功能的需求. ...

  4. Prism 4 文档 ---第10章 Silverlight和WPF之间共享代码

        本主题帮助你理解来自Prism的多目标和它的优缺点.多目标的代码针对两个不同的平台有大致相同的代码库.这允许同时保持代码尽可能多一样能够产生针对两种不同技术的二进制文件.在这种情况下,本节介绍 ...

  5. Prism 4 文档 ---第8章 导航

        作为同用户具有丰富的交互的客户端应用程序,它的用户界面(UI)将会持续不断的更新来反映用户工作的当前的任务和数据.用户界面可以进行一段时间相当大的变化作为用户交互的应用程序中完成各种任务.通过 ...

  6. Prism 4 文档 ---第6章 高级MVVM场景

        在上一章中描述了如何通过将UI,表现逻辑,业务逻辑分别放到三个单独的类中(View,View Model,Model),实现这些类之间的交互(通过数据绑定,命令以及数据验证接口)以及实现一个策 ...

  7. Prism 4 文档 ---第9章 松耦合组件之间通信

    当构建一个大而负责的应用程序时,通用的做法时将功能拆分到离散的模块程序集中.将模块之间的静态引用最小化.这使得模块可以被独立的开发,测试,部署和升级,以及它迫使松散耦合的沟通. 当在模块之间通信时,你 ...

  8. Prism 4 文档 ---第5章 实现MVVM模式

        MVVM模式有助于清楚的区分应用程序界面的业务层和展现层.保持一个清晰的应用程序逻辑和UI分离有助于处理开发和设计过程中大量的问题,同时,使得应用程序的测试,维护,和扩展更加容易.MVVM也可 ...

  9. Prism 4 文档 ---第4章 模块化应用程序开发

    模块化应用程序是指将一个应用程序拆分成一系列的可以组合的功能单元.一个客户端模块封装了应用程序的一部分,并且通常是一系列相关的关注点.它可以包含一个相关的组件的集合,就像用户界面,应用程序功能,和一些 ...

随机推荐

  1. NC审批流开发流程

            1.新建的是数据库表结构中一定要有                          [审批人.                            制单人.             ...

  2. windows下mysql安装失败的一个解决案例

    操作系统:windows8.1,之前安装过mysql,这次安装在配置的最后一部执行“Apply security settings”的过程中弹出经典错误: Access denied for user ...

  3. Eclipse+Spark搭建源码分析环境问题分析

    欢迎和大家交流技术相关问题: 邮箱: jiangxinnju@163.com 博客园地址: http://www.cnblogs.com/jiangxinnju GitHub地址: https://g ...

  4. 使用selenium前学习HTML介绍

    <!-- HTML 是用来描述网页的一种语言. HTML 指的是超文本标记语言 (Hyper Text Markup Language) HTML 不是一种编程语言,而是一种标记语言 (mark ...

  5. c++第三十二天

    p164~p170: 大致内容 迭代语句 1.while语句. 2.传统for. 3.范围for.两个注意点是:1- 通常使用auto来确保类型相容,2- 如果需要修改元素则需要使用&符(还可 ...

  6. php 安装Memcache扩展

    转载地址:http://www.tuicool.com/articles/EB3imm 文章概述:由于当前机器安装的php,是用yum安装,现在需要使用到memadmin做一些监控, memadmin ...

  7. 如何在Kubernetes集群动态使用 NAS 持久卷

    1. 介绍: 本文介绍的动态生成NAS存储卷的方案:在一个已有文件系统上,自动生成一个目录,这个目录定义为目标存储卷: 镜像地址:registry.cn-hangzhou.aliyuncs.com/a ...

  8. 20145302张薇《Java程序设计》第五周学习总结

    20145302 <Java程序设计>第五周学习总结 教材学习内容总结 第八章 try catch JVM会先尝试执行try区块中的内容,若发生错误且与catch后面的类型相符,则执行ca ...

  9. 20145321 《Java程序设计》第3周学习总结

    20145321 <Java程序设计>第3周学习总结 教材学习内容总结 第四章 4.1 类与对象 1.定义类:类定义时用关键词 class. 一个原始码中可以有多个类定义,但只能有一个公开 ...

  10. Jquery8 基础事件

    学习要点: 1.绑定事件 2.简写事件 3.复合事件 JavaScript 有一个非常重要的功能,就是事件驱动.当页面完全加载后,用户通过鼠标或键盘触发页面中绑定事件的元素即可触发.jQuery 为开 ...