• 2: 使用Prism初始化程序(纯汉语版)


    本篇内容讲解了Prism应用程序启动和运行都发生了什么。一个Pris应用程序在程序启动期间需要注册和配置——这被叫做引导应用程序。Prism引导过程包括创建和配置一个模块目录,创建一个例如Unity的依赖注入容器,为组合式UI配置默认区域适配器,创建和初始化壳视图,还有初始化模块们。

    什么是引导器?

        引导器是一个负责初始化Prism应用程序的类。通过使用引导器,你可以更多的控制Prism组件连接到你的应用程序。

        Prism包括一个默认抽象Bootstrapper 基类,可以使用任何容器。多数在引导器类中的方法都是虚方法。你可以在你自定义的引导器类中重写它们。

    引导器执行过程的基本步骤

      Prism还提供了一些继承自Bootstrapper的类,拥有一些大多数应用都需要的默认实现。仅留给你实现的步骤是创建和初始化壳。

    依赖注入

       Prism构建的程序由一个容器提供依赖注入。类库提供和Untiy或是MEF一同工作的程序集,当然 也允许使用其他依赖注入容器,引导器步骤中就有配置容器和主持类型到容器。

       Prism包括UnityBootstrapper 和MefBootstrapper 类,都实现了大多数必要的功能。初上上图的步骤,这俩引导器还添加了跟自己容器相关的一些步骤。

    创建壳

       在传统的WPF程序里,启动URI是在App。xaml文件里,指向主窗口。

       Prism程序,其引导器的职责是创建壳或主窗口。壳依靠的服务,如区域管理器,要在壳展示之前注册。

    关键决定

    在你决定使用Prism之后,有一些决定需要你来考虑:

    • 考虑用MEF,Unity还是其他容器作为你的依赖注入容器。这将决定你要用何种bootstraper。
    • 你该考虑你想要的应用程序的服务。这些需要注册到容器里。
    • 决定是否使用内置日志服务,如果不用,你需要创建其他日志服务。
    • 决定怎样去发现模块,使用直接代码引用,在模块上标注代码特性,配置或使用XAML。

    余下的文章会提供更多详细信息。

    核心方案

        创建启动方案是构建Prism应用程序非常重要的一部分。此章节描述怎样创建一个引导器并定义它创建壳,配置依赖注入容器,注册程序级别服务,还有怎样加载和初始化模块。

    为你的应用程序创建一个引导器

      如果你选择Unity或MEF其中一个作为你的依赖注入容器,创建一个引导器非常easy。创建一个新类继承自 MefBootstrapper 或UnityBootstrapper。然后,实现CreateShell 方法,你还可以重写InitializeShell 方法用于对壳有啥特别操作。

    Implementing the CreateShell Method 实现CreateShell方法

       CreateShell 方法允许开发者指定一个顶级窗口。壳一般就是 MainWindow 或 MainPage. 实现此方法,返回一个壳实例。在Prism应用程序中,你可以创建壳项目,或者从容器中解析它,这根据你程序的需求。

      一个使用ServiceLocator 解析壳对象的示例,代码如下所示。

    protected override DependencyObject CreateShell()
    {
        return ServiceLocator.Current.GetInstance<Shell>();
    }
    注意
    你将经常看到使用ServiceLocator解析类型的示例而不是用依赖注入容器。ServiceLocator 是通过调用容器实现的,所有这样可以写出容器无关的代码。你也可以直接引用容器替换掉ServiceLocator

     实现初始化壳方法

        创建壳之后,你可能需要允许一些初始化步骤,确保壳可以展示。对于WPF应用程序,你可以将创建的壳对象赋给程序主窗口,如下所示(来自WPf版模块化开始入门)

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

        基类的InitializeShell 什么也没做,所有不调用基类实现也没关系。

    创建和配置模块目录

       如果你正创建一个模块应用程序,你需要创建并配置一个模块目录。Prism使用一个具体的IModuleCatalog 实例追踪程序启用的模块。这些模块需要被下载和驻留。

       引导器提供一个可保护的ModuleCatalog 属性指向一个目录,也提供了一个virtualCreateModuleCatalog 虚方法。基类实现是返回一个新的ModuleCatalog ;然而,此方法可以重写成返回一个不同的IModuleCatalog 的方法。如下所示:(来自MEF版模块化快速入门示例)

    protected override IModuleCatalog CreateModuleCatalog()
    {
        // When using MEF, the existing Prism ModuleCatalog is still
        // the place to configure modules via configuration files.
        return new ConfigurationModuleCatalog()
    }

       无论在UnityBootstrapper 还是 MefBootstrapper 中,Run方法调用CreateModuleCatalog 方法并利用返回值设置类中的ModuleCatalog 属性。如果你重写此方法,不需要调用基类实现,因为你是要替换容器提供的功能。更多信息,请看"模块化应用程序开发."

    创建和配置容器

       容器扮演了一个Prism程序中关键的角色。程序需要容器来加载需求的依赖项和服务。在容器配置期间,一些核心的服务项被注册。除了核心服务,你还需要一些程序相关的服务应该被添加。

    核心服务

    下表列出了程序无关的核心服务

    服务接口

    描述

    IModuleManager

    检索并初始化程序模块。

    IModuleCatalog

    包含程序中模块的元数据,Prism提供了一些不同的目录。

    IModuleInitializer

    初始化模块。

    IRegionManager

    注册和检索区域,区域是指一种可视化的布局容器。

    IEventAggregator

    事件集合,以松耦合方式连接发布者和订阅者。

    ILoggerFacade

    一个包装日志的机制,你也可以选择使用自己的日志机制。股票操盘参考实现(Stock Trader RI)使用的是微软企业库日志模块,使用EnterpriseLibraryLoggerAdapter类,作为一个实现自定义日志的示例。通过引导器的run方法,将日志服务注册到容器里。使用CreateLogger 的返回值。支持的其他日志器将不会工作;需要重写CreateLogger 方法才行。

    IServiceLocator

    允许Prism库访问容器。如果你想定做或扩展类库,此接口或许有用。

    应用程序特定服务

       下表列出的是股票操盘程序的应用程序特定服务,这可以作为一个理解你应用程序提供的服务类型的一个示例。

    股票操盘程序示例

    描述

    IMarketFeedService

    提供实时(模拟的) 的市场信息。PositionSummaryViewModel 更新它屏幕位置上的信息就是根据此服务。

    IMarketHistoryService

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

    IAccountPositionService

    提供了在组合投资的一组基金。

    IOrdersService

    显示提交的买卖订单

    INewsFeedService

    提供一个选择基金的新项。

    IWatchListService

    当新的观察项被添加时的处理服务

       Bootstrapper 继承的两个类,UnityBootstrapper 和 MefBootstrapper. 创建和配置不同的容器涉及不同的实现方式但却相似的概念。

    在UnityBootstrapper创建和配置容器

       UnityBootstrapper 类的CreateContainer 方法创建和返回一个UnityContainer实例。大多数情况下,你不需要改变此功能;然而,此方法是虚的,因此你可以改。

       容器创建之后,需要配置它,ConfigureContainer 默认实现注册了一些Prism核心服务,如下。

    注意
    模块基本的服务在它自己的Initialize 方法中。
    // 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(typeof(IRegionNavigationJournalEntry), typeof(RegionNavigationJournalEntry), false);
        RegisterTypeIfMissing(typeof(IRegionNavigationJournal), typeof(RegionNavigationJournal), false);
        RegisterTypeIfMissing(typeof(IRegionNavigationService), typeof(RegionNavigationService), false);
        RegisterTypeIfMissing(typeof(IRegionNavigationContentLoader), typeof(UnityRegionNavigationContentLoader), true);
    
      }
    }

      引导器的RegisterTypeIfMissing 方法很检查一个服务是否被注册了——服务不会被注册两次。这允许你重写默认注册项。你可以关闭任何默认服务;为做到这一点,重写Bootstrapper.Run 方法并传递个false. 你也可以重写ConfigureContainer 方法并关闭你不需要的服务,例如事件聚合。

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

        为了扩展ConfigureContainer默认行为。只需重写它。如下所示(来自使用Unity模块化快速入门),注册ModuleTracker 类型作为IModuleTracker的实现。注册callbackLogger 作为回调日志器的一个单例。

    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 创建并返回一个使用CatalogExportProviderCompositionContainer 实例。更多情况下,你将不需要改变此功能;然而,方法时虚的,因此你也可以改。

       容器创建之后,它需要在你的程序中配置。ConfigureContainer实现一系列核心Prism服务的注册。如下代码所示。如果你重写此方法,仔细考虑你是否应该调用基类默认注册的核心Prism服务,或者在你自己的实现中提供这些服务。

    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中,核心服务作为单例添加到容器中。

        除了提供CreateContainer 和ConfigureContainer 方法,MefBootstrapper 也提供两个方法来创建和配置AggregateCatalog 。CreateAggregateCatalog 方法创建并返回一个AggregateCatalog 对象。和MefBootstrapper中其他方法一样,此方法也是虚的,你可以重写它。

       ConfigureAggregateCatalog 方法允许你添加类型注册到 AggregateCatalog 。如下所示(来自MEF模块化快速入门中加载模块A和模块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));
        this.AggregateCatalog.Catalogs.Add(
                     new AssemblyCatalog(typeof(ModuleC.ModuleC).Assembly));
    
        // Module B and Module D are copied to a directory as part of a post-build step.
        // These modules are not referenced in the project and are discovered by inspecting a directory.
        // Both projects have a post-build step to copy themselves into that directory.
        DirectoryCatalog catalog = new DirectoryCatalog("DirectoryModules");
        this.AggregateCatalog.Catalogs.Add(catalog);
    }

    更多信息

      有关MEFAggregateCatalog, 和AssemblyCatalog,的更多信息,请看在MSDN上的 Managed Extensibility Framework Overview 。

  • 相关阅读:
    hdu 1272 小希的迷宫
    hdu 1318 Palindromes
    ANR traces中内存占用情况解读
    请教会linux shell脚本的=~是什么意思?
    kernel struct definition location
    SecureCRT sysrq键设置
    sysrq
    Linux中断管理 (1)Linux中断管理机制【转】
    Linux suspend 流程介绍(2)之 freeze task
    Linux进程状态解析 之 R、S、D、T、Z、X (主要有三个状态)
  • 原文地址:https://www.cnblogs.com/DoubleChen/p/3688305.html
Copyright © 2020-2023  润新知