2: 使用Prism初始化程序 Initializing Applications Using the Prism Library 5.0 for WPF(英汉对照版)

    This topic addresses what needs to happen to get a Prism for WPF application up and running. A Prism application requires registration and configuration during the application startup process—this is known as bootstrapping the application. The Prism bootstrapping process includes creating and configuring a module catalog, creating a dependency injection container such as Unity, configuring default region adapter for UI composition, creating and initializing the shell view, and initializing modules.

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

What Is a Bootstrapper?什么是引导器?

    A bootstrapper is a class that is responsible for the initialization of an application built using the Prism Library. By using a bootstrapper, you have more control of how the Prism Library components are wired up to your application.

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

    The Prism Library includes a default abstract Bootstrapper base class that can be specialized for use with any container. Many of the methods on the bootstrapper classes are virtual methods. You can override these methods as appropriate in your own custom bootstrapper implementation.

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

Basic stages of the bootstrapping process 引导器执行过程的基本步骤

    The Prism Library provides some additional base classes, derived from Bootstrapper, that have default implementations that are appropriate for most applications. The only stages left for your application bootstrapper to implement are creating and initializing the shell.

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

Dependency Injection 依赖注入

    Applications built with the Prism Library rely on dependency injection provided by a container. The library provides assemblies that work with the Unity Application Block (Unity) or Managed Extensibility Framework (MEF), and it allows you to use other dependency injection containers. Part of the bootstrapping process is to configure this container and register types with the container.

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

    The Prism Library includes the UnityBootstrapper and MefBootstrapper classes, which implement most of the functionality necessary to use either Unity or MEF as the dependency injection container in your application. In addition to the stages shown in the previous illustration, each bootstrapper adds some steps specific to its container.

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

Creating the Shell 创建壳

    In a traditional Windows Presentation Foundation (WPF) application, a startup Uniform Resource Identifier (URI) is specified in the App.xaml file that launches the main window.

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

    In an application created with the Prism Library, it is the bootstrapper's responsibility to create the shell or the main window. This is because the shell relies on services, such as the Region Manager, that need to be registered before the shell can be displayed.

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

Key Decisions 关键决定

  After you decide to use the Prism Library in your application, there are a number of additional decisions that need to be made:

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

  • You will need to decide whether you are using MEF, Unity, or another container for your dependency injection container. This will determine which provided bootstrapper class you should use and whether you need to create a bootstrapper for another container.
        考虑用MEF,Unity还是其他容器作为你的依赖注入容器。这将决定你要用何种bootstraper。
  • You should think about the application-specific services you want in your application. These will need to be registered with the container.
        你该考虑你想要的应用程序的服务。这些需要注册到容器里。
  • Determine whether the built-in logging service is adequate for your needs or if you need to create another logging service.
        决定是否使用内置日志服务,如果不用,你需要创建其他日志服务。
  • Determine how modules will be discovered by the application: via explicit code declarations, code attributes on the modules discovered via directory scanning, configuration, or XAML.
        决定怎样去发现模块,使用直接代码引用,在模块上标注代码特性,配置或使用XAML。

  The rest of this topic provides more details.

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

Core Scenarios 核心方案

    Creating a startup sequence is an important part of building your Prism application. This section describes how to create a bootstrapper and customize it to create the shell, configure the dependency injection container, register application level services, and how to load and initialize the modules.

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

Creating a Bootstrapper for Your Application 为你的应用程序创建一个引导器

    If you choose to use either Unity or MEF as your dependency injection container, creating a simple bootstrapper for your application is easy. You will need to create a new class that derives from either MefBootstrapper or UnityBootstrapper. Then, implement the CreateShell method. Optionally, you may override the InitializeShell method for shell specific initialization.

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

Implementing the CreateShell Method 实现CreateShell方法

    The CreateShell method allows a developer to specify the top-level window for a Prism application. The shell is usually the MainWindow or MainPage. Implement this method by returning an instance of your application's shell class. In a Prism application, you can create the shell object, or resolve it from the container, depending on your application's requirements.

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

    An example of using the ServiceLocator to resolve the shell object is shown in the following code example.

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

protected override DependencyObject CreateShell()
{
    return ServiceLocator.Current.GetInstance<Shell>();
}
Note:注意
You will often see the ServiceLocator being used to resolve instances of types instead of the specific dependency injection container. The ServiceLocatoris implemented by calling the container, so it makes a good choice for container agnostic code. You can also directly reference and use the container instead of the ServiceLocator.
你将经常看到使用ServiceLocator解析类型的示例而不是用依赖注入容器。ServiceLocator 是通过调用容器实现的,所有这样可以写出容器无关的代码。你也可以直接引用容器替换掉ServiceLocator

Implementing the InitializeShell Method 实现初始化壳方法

 After you create a shell, you may need to run initialization steps to ensure that the shell is ready to be displayed.For WPF applications, you will create the shell application object and set it as the application's main window, as shown here (from the Modularity QuickStarts for WPF).

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

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

  The base implementation of InitializeShell does nothing. It is safe to not call the base class implementation.

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

Creating and Configuring the Module Catalog 创建和配置模块目录

    If you are building a module application, you will need to create and configure a module catalog. Prism uses a concrete IModuleCatalog instance to keep track of what modules are available to the application, which modules may need to be downloaded, and where the modules reside.

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

    The Bootstrapper provides a protected ModuleCatalog property to reference the catalog as well as a base implementation of the virtualCreateModuleCatalog method. The base implementation returns a new ModuleCatalog; however, this method can be overridden to provide a differentIModuleCatalog instance instead, as shown in the following code from the QuickStartBootstrapper in the Modularity with MEF for WPF QuickStart.

    引导器提供一个可保护的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()
}

   In both the UnityBootstrapper and MefBootstrapper classes, the Run method calls the CreateModuleCatalog method and then sets the class'sModuleCatalog property using the returned value. If you override this method, it is not necessary to call the base class's implementation because you will replace the provided functionality. For more information about modularity, see "Modular Application Development."

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

Creating and Configuring the Container 创建和配置容器

    Containers play a key role in an application created with the Prism Library. Both the Prism Library and the applications built on top of it depend on a container for injecting required dependencies and services. During the container configuration phase, several core services are registered. In addition to these core services, you may have application-specific services that provide additional functionality as it relates to composition.

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

Core Services 核心服务

The following table lists the core non-application specific services in the Prism Library.

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

Service interface

服务接口

Description

描述

IModuleManager

Defines the interface for the service that will retrieve and initialize the application's modules.

检索并初始化程序模块。

IModuleCatalog

Contains the metadata about the modules in the application. The Prism Library provides several different catalogs.

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

IModuleInitializer

Initializes the modules.

初始化模块。

IRegionManager

Registers and retrieves regions, which are visual containers for layout.

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

IEventAggregator

A collection of events that is loosely coupled between the publisher and the subscriber.

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

ILoggerFacade

A wrapper for a logging mechanism, so you can choose your own logging mechanism. The Stock Trader Reference Implementation (Stock Trader RI) uses the Enterprise Library Logging Application Block, via the EnterpriseLibraryLoggerAdapter class, as an example of how you can use your own logger. The logging service is registered with the container by the bootstrapper's Runmethod, using the value returned by the CreateLogger method. Registering another logger with the container will not work; instead override the CreateLogger method on the bootstrapper.

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

IServiceLocator

Allows the Prism Library to access the container. If you want to customize or extend the library, this may be useful.

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

Application-Specific Services 应用程序特定服务

    The following table lists the application-specific services used in the Stock Trader RI. This can be used as an example to understand the types of services your application may provide.

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

Services in the Stock Trader RI

股票操盘程序示例

Description

描述

IMarketFeedService

Provides real-time (mocked) market data. The PositionSummaryViewModel updates the position screen based on notifications it receives from this service.

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

IMarketHistoryService

Provides historical market data used for displaying the trend line for the selected fund.

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

IAccountPositionService

Provides the list of funds in the portfolio.

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

IOrdersService

Persists submitted buy/sell orders.

显示提交的买卖订单

INewsFeedService

Provides a list of news items for the selected fund.

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

IWatchListService

Handles when new watch items are added to the watch list.

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

    There are two Bootstrapper-derived classes available in Prism, the UnityBootstrapper and the MefBootstrapper. Creating and configuring the different containers involve similar concepts that are implemented differently.

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

Creating and Configuring the Container in the UnityBootstrapper 在UnityBootstrapper创建和配置容器

    The UnityBootstrapper class's CreateContainer method simply creates and returns a new instance of a UnityContainer. In most cases, you will not need to change this functionality; however, the method is virtual, thereby allowing that flexibility.

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

    After the container is created, it probably needs to be configured for your application. The ConfigureContainer implementation in the UnityBootstrapperregisters a number of core Prism services by default, as shown here.

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

Note:注意
An example of this is when a module registers module-level services in its Initialize method.
模块基本的服务在它自己的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);

  }
}

    The bootstrapper's RegisterTypeIfMissing method determines whether a service has already been registered—it will not register it twice. This allows you to override the default registration through configuration. You can also turn off registering any services by default; to do this, use the overloadedBootstrapper.Run method passing in false. You can also override the ConfigureContainer method and disable services that you do not want to use, such as the event aggregator.

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

Note:注意
If you turn off the default registration, you will need to manually register required services.
如果你关闭默认注册,则你需要手动注册需要的服务。

    To extend the default behavior of ConfigureContainer, simply add an override to your application's bootstrapper and optionally call the base implementation, as shown in the following code from the QuickStartBootstrapper from the Modularity for WPF (with Unity) QuickStart. This implementation calls the base class's implementation, registers the ModuleTracker type as the concrete implementation of IModuleTracker, and registers the callbackLogger as a singleton instance of CallbackLogger with Unity.

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

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

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

Creating and Configuring the Container in the MefBootstrapper 创建和配置MefBootstrapper容器

    The MefBootstrapper class's CreateContainer method does several things. First, it creates an AssemblyCatalog and a CatalogExportProvider. TheCatalogExportProvider allows the MefExtensions assembly to provide default exports for a number of Prism types and still allows you to override the default type registration. Then CreateContainer creates and returns a new instance of a CompositionContainer using the CatalogExportProvider. In most cases, you will not need to change this functionality; however, the method is virtual, thereby allowing that flexibility.

    MefBootstrapper 类的CreateContainer 方法做了一些事情,第一件,它创建一个AssemblyCatalog 和一个CatalogExportProvider。CatalogExportProvider 允许MefExtensions 程序集去加载默认Prism类型注册,并允许你重写默认类型注册。CreateContainer 创建并返回一个使用CatalogExportProviderCompositionContainer 实例。更多情况下,你将不需要改变此功能;然而,方法时虚的,因此你也可以改。

    After the container is created, it needs to be configured for your application. The ConfigureContainer implementation in the MefBootstrapper registers a number of core Prism services by default, as shown in the following code example. If you override this method, consider carefully whether you should invoke the base class's implementation to register the core Prism services, or if you will provide these services in your implementation.

    容器创建之后,它需要在你的程序中配置。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);
}
Note:注意
In the MefBootstrapper, the core services of Prism are added to the container as singletons so they can be located through the container throughout the application.
MefBootstrapper中,核心服务作为单例添加到容器中。

    In addition to providing the CreateContainer and ConfigureContainer methods, the MefBootstrapper also provides two methods to create and configure the AggregateCatalog used by MEF. The CreateAggregateCatalog method simply creates and returns an AggregateCatalog object. Like the other methods in the MefBootstrapperCreateAggregateCatalog is virtual and can be overridden if necessary.

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

    The ConfigureAggregateCatalog method allows you to add type registrations to the AggregateCatalog imperatively. For example, theQuickStartBootstrapper from the Modularity with MEF QuickStart explicitly adds ModuleA and ModuleC to the AggregateCatalog, as shown here.

    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);
}

More Information 更多信息

    For more information about MEF, AggregateCatalog, and AssemblyCatalog, see Managed Extensibility Framework Overview on MSDN.

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

原文地址:https://www.cnblogs.com/DoubleChen/p/3688191.html