prism4.0——chapter 2:初始化Prism应用

  Prism 4 Documentation:http://compositewpf.codeplex.com/releases/view/55580

  这一章解决了建立和运行一个Prism应用需要做的事情。一个Prism程序需要在应用快速启动的过程中进行注册和配置,这就是众所周知的bootstrapping 应用。

  什么是一个Bootstrapper?

  一个bootstrapper是一个类,它会用Prism类库来承担已建立的应用程序的初始化。通过运用bootstrapper,你将更好的控制怎样将Prism类库的组件连接到你的应用中。

   Prism类库包含了一个默认的抽象的Bootstrapper基类,这些基类可以通过任一容器对其具体化的方式来使用。在bootstrapper类上的需多方法是虚拟方法。你可以重写这些方法,让这些方法成为适合你自己习惯的bootstrapper安装启用。

  bootstrapper过程的基础近阶

  Prism类库提供了一些附加的基类,这些基类从Bootstrapper中得到,有适合于大部分应用的默认安装。唯一剩余的需要你的应用bootstrapper来实现的阶段是创建和初始化shell。

  Dependency Injection

  通过Prism类库建立起来的应用依赖于由容器提供的dependency injection。类库提供的程序集于Unity或是MEF一起工作,它也允许你使用其他的dependency injection 容器。部分bootstrapper过程需要配置容器和为容器注册类型。

 

  Prism库包含了UnityBootstrapper和MefBootstrapper类,这就能够实现使用Unity或是MEF作为应用中dependency injection容器大部分需要的功能。除了前面例子中所展示的领域外,每一个bootstrapper在它们的容器中添加了一些具体的步骤。

  创建shell

  在传统的WPF应用中,App.xaml文件中一个URI启动是指定的,用来登陆主窗口。在Silverlight应用中,应用中的RootVisual属性是在App.xaml文件后面的代码中设定的。

  在一个用Prism库创建的应用中,创建shell或是主窗口是由bootstrapper来完成的。这是应为shell依赖于服务,像Region Manager,只有当它注册以后shell才能显示。

  关键的决定

  你决定了在你的应用中使用Prism库之后,还需要做很多其他的决定:

  • 你将需要决定你是否使用MEF,Unity或是为dependency injection 容器使用其他的容器。这将决定你使用哪个类来提供bootstrapper,你是否需要为其他的容器创建一个bootstrapper。
  • 你需要思考在你的应用中要什么特定的应用服务。这些需要在容器中进行注册。
  • 决定固有的登陆服务是否适合你的需要或者你需要创建另一个登陆服务。
  • 决定你的应用怎样发掘模块:是通过明确的代码声明,通过目录浏览发现在模块中的代码属性,部署或是XAML.

剩下的章节提供更多的细节。

核心脚本

  创建一个快速启动序列式你建立你的Prism应用重要的一部分。这一节叙述如何创建一个bootstrapper并定制它来创建一个shell,配置dependency injection 容器,注册应用的水平服务和如何加载并初始化模块。

为你的应用创建一个bootstrapper

  如果你选择使用Unity或是MEF作为你的dependency injection 容器,为你的应用创建一个简单的bootstrapper是很容易的。你需要从MefBootstrapper或是UnityBootstrapper中创建一个新的类。然后,实施CreatShell这个方法。你也可以选择为特定初始化shell重写InitializeShell方法。

实施CreateShell方法

  CreateShell方法允许开发人员为Prism应用指定最高层次的窗口。shell通常是主窗口或是主页。通过返回你应用的shell类中的一个例子来实现这种方法。在一个Prism应用中,你可以创建一个shell对象或是将它从容器中解析出来,这取决于你应用的需要。

  下面的代码示例是使用ServiceLocator来决定shell对象的:

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

Note:

  你总会看到ServiceLocator被用来解析类型的实例,以此取代了特定的依赖注入容器。ServiceLocator通过呼叫容器来实现,因此它为容器的未知代码提供了一个好的选择。你也可以直接应用和使用容器来取代ServiceLocator。

  实现InitializeShell的方法

  在你创建了一个shell以后,你可能需要运行初始化的步骤来确保shell在待显示状态。实现InitializeShell的方法取决于你是用WPF还是Silverlight写的应用,这两者是不同的。对于Silverlight应用来说,你需要设置shell作为应用的可视化根基,像如下所示:

 

c#
protected override void InitializeShell()
{
    Application.Current.RootVisual = Shell;
}

 

   对于WPF应用,你将创建shell应用对象并将它设置为应用的主窗口,像如下所示(来自WPF模块的快速入门)

 

1 c#
2 protected override void InitializeShell()
3 {
4     Application.Current.MainWindow = Shell;
5     Application.Current.MainWindow.Show();
6 }

 

  InitializeShell方法的基础实现不需要做什么。不调用基类实现是安全的。

创建和配置组件目录

  如果你建立一个组件应用,你将需要创建和配置一个组件目录。Prism用一个具体的IModuleCatalog实例来阐释了对于应用来说什么样的组件式有效的,哪种组件可能需要下载下来试用,以及组件存放在哪里。

  引导程序提供了一个受保护的ModuleCatalog属性来引用目录和一个可视化CreateModuleCatalog方法的基本实现。这个基本实现返回一个新的ModuleCatalog;然而,可以重写这种方法以用来提供一个不同的IModuleCatalog实例取代它自身,就像下面的代码显示的那样,这些代码来自Silverlight快速入门中MEF模块QuickStartBootstrapper。

1 c#
2 protected override IModuleCatalog CreatModuleCatalog()
3 {
4     //当使用MEF时,已存在的Prism模块目录是静态的
5    //通过配置文件来配置模块
6     return ModuleCatalog.CreatFormXaml(new Uri("/ModelarityWithMef.Silverlight;component/ModulesCatalog.xaml",UriKind.Relative));
7 }

 

在UnityBootstrapper和MefBootstrapper类中,Run方法调用CreateModuleCatalog方法然后用返回值的方式设这类的ModuleCatalog属性。如果你要重写这个方法,不需要调用基础类的安装启动,因为你将会代替已经提供了的功能。更多关于模块化的信息参照第四章,“模块应用开发。”

创建和配置容器

  在用Prism库创建的应用中,容器起了一个关键的作用。Prism库和创建在它顶部的应用都依赖于一个注入了需要的依赖和服务的容器。在容器配置阶段,需要注册几个核心的服务。除了这些核心服务外,你可能需要具体应用服务,这些服务由于跟组成相关提供了附加的功能。

核心服务

下面的表格列出了在Prism库中具体不适用的核心服务。

服务接口

描述

IModuleManager为将要检索的服务定义了接口并初始化了应用的模块。
IModuleCatalog包含了在应用中关于模块的元数据。Prism库提供了几个不同的目录。
IModuleInitialize初始化模块。
IRegionManager为在布局中的可视化容器注册和检索区域。
IEventAggregator在出版者和捐赠者之间的低耦合事件的收集。
ILoggerFacade

一个登陆机制的封装,你可以选择你自己的登陆机制。Stock  Trader RI通过EnterpriseLibraryLoggerAdapter类使用企业类库登陆应用区域,这个可以作为一个例子来说明你怎样使用你自己的记录器。记录服务已经用容器进行了注册,它是通过bootstrapper的Run方法,使用CreateLogger方法的有效返回值来实现的。用这个容器来注册其他的记录器将不再生效;反而在bootstrapper上重写了CreateLogger方法。

IServiceLocator允许Prism库使用容器。这可能对定制或是扩展类库起作用。

具体应用服务

下面的表格列出了使用在Stock Trader RI中的具体应用服务。这个可以当做一个了解你的应用中可能提供的服务的类型的例子来使用。

Stock Trader RI中的服务

描述

IMarketFeedService提供模拟的实时交易数据。PositionSummaryPresentationModel根据它从这个服务接收到的通告来跟心屏幕位置。
IMarketHistoryService提供历史交易数据用来展示所选基金的趋势走向。
IAccountPositionService技工文件夹中的基金列表
IOrderService持续提交买/卖命令
INewsFeedService为所选的基金提供一个新闻列表。
IWatchListService当新的密切关注的项目被添加到观看列表时进行操作。

 在Prism中有两个衍生Bootstrapper类可用,UnityBootstrapper和MefBootstrapper。创建和配置不同的容器涉及到实施起来不同但却相同的概念。

在UnityBootstrapper中创建和配置容器

   UnityBootstrapper类的CreateContainer方法很容易的可以创建和返回一个新的UnityContainer实例。在大部分情况中,你不需要改变这个功能;然而,方法是有效的,从而具有灵活性。

  在创建了容器之后,它可能需要为你的应用进行配置。ConfigureContainer在UnityBootstrapper中的安装被默认的注册了许多核心Prism服务,如下所示。

Note:

这是一个当一个模块在它的Initialize方法中注册模块级服务时的例子。

 

c# UnityBootstrapper.cs
protected virtual void ConfigureContainer()

{
    ...
    if ( useDefaultConfiguration)
 {
     RegisterTypeIfMissing( typeof( IServiceLocator),typeof ( UnityServiceLocatorAdapter), ture);
     RegisterTypeIfMissing( typeof( IModuleInitializer), typeof(ModuleInitializer), ture);
     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方法决定了一个服务是否被注册,它将不会被二次注册。你就可以通过配置来重写默认的注册。你也可以关闭默认注册服务;如果你这样做,用传入false参数加载Bootstrapper.Run 方法。你也可以重写ConfigureContainer方法禁用你不想使用的服务,像事件聚合器。

Note:

    如果你关闭了默认注册,你需要手动注册需要的服务。

 

  要扩展默认的ConfigureContainer方法,只需要简单的添加一个方法重写到你应用的引导程序中,随意调用基本的安装启用,如下面的代码所示,这些代码是Modularity for WPF(with Unity)QuickStart中的QuickStartBootstrapper。这个实现调用了基类的安装启用,注册了ModuleTracker类型作为IModuleTracker的具体实施,并且注册了callbackLogger作为一个Unity的CallbackLogger的单例模式。

 

1 C#
2 protected override void ConfigureContainer()
3 {
4     base.ConfigureContainer();
5     this.RegisterTypeIfMissing(typeof(IModuleTracker),typeof(ModuleTracker),ture);
6     this.Container.RegisterInstance<CallbackLogger>(this.callbackLogger);
7 }

 

 

 

在MefBootstrapper中创建和配置容器

MefBootstrapper类的CreateContainer方法做了如下几件事情。第一,它创建了一个AssemblyCatalog和一个CatalogExportProvider。CatalogExportProvider允许MefExtensions程序集为许多Prism类型提供默认的主配置文件,也允许你重写默认类型的注册。其次,CreateContainer使用CatalogExportProvider创建并返回了一个新的CompositionContainer实例。在大部分情况中,你不需要改变这个功能;然而,这个方法是虚拟的,因此允许灵活使用。

Note:

   在Silverlight中,由于受安全性限制,不能用一个类型来取回一个集合。Prism使用了Assembly.GetCallingAssembly方法来取代。

  容器创建了之后,需要对你的应用进行配置。MefBootstrapper中的ConfigureContainer的实现默认的注册了许多核心Prism服务,像如下的代码所示。如果你重写这个方法,要考虑清楚你是否应该调用基类的实现来注册核心的Prism服务,你是否需要在你的应用实现中提供这些服务。

 

C#
protected virtual void ConfigureContainer()
{
    this.RegisterBootstrapperProvidedTypes();
}
protected virtual void RegisterBootstrapperProviderTypes()
{
    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);
}

 

Note:

在MefBootstrapper中,Prism的核心服务作为单例添加到了容器中,因此它们可以在整个应用的过程中通过容器进行定位。

  MefBootstrapper除了提供CreateContainer和ConfigureContainer方法外,通过使用MEF也提供两个方法来创建和配置AggregateCatalog。CreateAggregateCatalog方法很容易的创建和返回一个AggregateCatalog对象。像MefBootstrapper中的其他方法一样,CreateAggregateCatalog是虚拟的,如果需要的话可以重写它。

  ConfigureAggregateCatalog方法允许命令式的将类型注册添加到AggregateCatalog中。例如,Modularity with MEF for Silverlight QuickStart中的QuickStartBootstrapper明确将ModuleA和ModuleC添加到了AggregateCatalog中,如下所示:

 

C#
protected override void ConfigureAggregateCatalog()
{
    base.ConfigureAggregateCatalog();
    //将这个集合添加到ModuleTracker出口中
   this.AggregateCatalog.Catalogs.Add( new AssemblyCatalog(typeof(QuickStartBootstrapper).Assembly));
     //...
    this.AggregateCatalog.Catalogs.Add(new.AssemblyCatalog(typeof(ModuleA.ModuleA).Assembly));
    //...
    this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(ModuleA.ModuleC).Assembly));
}

 

 

 

 

更多信息

  关于MEF的更多信息,AggregateCatalog和AssemblyCatalog,参见MSDN上的“Managed Extensibility Framework Overview”http://msdn.microsoft.com/en-us/library/dd460648.aspx .

 

 

 

 

 

转载于:https://www.cnblogs.com/blancpure/archive/2012/07/03/2574378.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值