65.9K
CodeProject 正在变化。 阅读更多。
Home

从 Prism 开始 - 第一部分

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.94/5 (19投票s)

2012年8月9日

CPOL

7分钟阅读

viewsIcon

51659

downloadIcon

1087

Prism 简介。

介绍 

Prism 提供创建组合式应用程序的指导,并帮助我们设计松散耦合的组件,这些组件可以无缝集成和开发。与任何其他应用程序一样,Prism 应用程序也需要从某个地方开始。而对于 Prism 来说,它就是 Bootstrapper 和 Shell。这两个东西可以帮助任何 Prism 应用程序启动和运行。在本文中,我们将更深入地研究 Bootstrapper 及其过程。所以,准备好,让我们开始吧……

Bootstrapper

那么,什么是 Bootstrapper?Bootstrapper 是负责初始化我们应用程序的类。现在问题是初始化什么?所以,首先要初始化的是核心服务,然后是应用程序特定服务。

核心服务:这些是 Prism 库提供给我们的非应用程序特定服务。这些服务包括:

  • IModuleManager - 负责检索应用程序的模块
  • IModuleCatalog - 用于注册模块
  • IModuleInitializer - 负责初始化模块
  • IRegionManager - 这些是 UI 的可视化容器
  • IEventAggregator - 它允许我们创建事件
  • ILoggerFacade - 这是日志记录机制的包装器
  • IServiceLocator - 这用于让应用程序访问您的容器

应用程序特定服务:除了核心服务,Prism 还初始化一些应用程序特定服务。这些服务是特定于我们应用程序的,并且在所有应用程序模块中都是通用的。例如,如果您正在开发 RSS 类型应用程序,在这种情况下,RSS Feed 服务将是应用程序特定服务,几乎所有模块都将使用它来读取 feed。

引导程序流程

Bootstrapper 是一个非常重要的类,它使我们能够控制应用程序连接起来的每个组件。Prism 库提供了一个默认的抽象 Bootstrapper 基类,它有许多虚拟方法。让我们继续看看 Bootstrapper 过程。请记住,此过程的大部分阶段将在后续文章中更详细地介绍。

  • 第一件事是创建 LoggerFacade,它主要处理日志记录
  • 接下来需要配置模块目录
  • 然后需要创建一个容器,可以选择任何喜欢的容器,例如 Ninject、Unity、MEF 等。Prism 库实际上包含两个 Bootstrapper 类。一个叫做 UnityBootstrapper,另一个是 MEF,它包含了将 Unity 或 MEF 用作依赖注入容器所需的大部分功能。
  • 接下来需要配置默认的区域适配器映射。所以,我们必须创建一个自定义区域适配器,我们将在那里注册它
  • 接下来我们将配置默认的区域行为
  • 然后我们将注册我们的框架异常类型
  • 接下来我们将创建 Shell
  • 然后 Shell 将被初始化
  • 最后模块将被初始化

请记住,我们不需要实现每个阶段。

UnityBootStrapper 示例代码

为了使用 Unity,需要在项目中添加以下引用

  • Microsoft.Practices.Prism.dll
  • Microsoft.Practices.Prism.UnityExtensions.dll
  • Microsoft.Practices.Prism.Unity.dll

接下来我们需要添加一个名为 Bootstrapper 的类,如下:

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

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

        App.Current.MainWindow = (Window)Shell;
        App.Current.MainWindow.Show();
    }
}
public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);
        Bootstrapper bootstrapper = new Bootstrapper();
        bootstrapper.Run();
    }
}

区域

在这里我将讨论区域在任何 Prism 应用程序中的作用。在这里我们将讨论区域是什么以及它们在我们的应用程序中扮演什么角色。我们还将研究 RegionManager 以及它如何管理我们的 Prism 应用程序。我们还将涉及 RegionAdapter 以及区域与 RegionManager 之间的关系。然后我们将看到如何创建自定义区域,因为 Prism 不支持的控件需要它。

什么是区域?

区域只是任何将在我们的 UI 中呈现的动态内容的占位符。区域类似于 ASP.NET 的内容占位符。它只是一个命名位置,您可以使用它来定义您的视图将出现在哪里。我希望您还记得,我们之前谈到了 Shell 的概念以及 Shell 如何包含区域,我们将视图注入其中。

现在让我们快速举个例子。在这个例子中,我们将有一个 MenuBar 区域和一个 Content 区域。

这些区域定义了 UI 中将注入我们视图的区域。每个区域都应该明确命名并描述我们将注入区域的内容类型。因此,给定一个带有两个视图(MenuBar 视图和 Content 视图)的模块。这些视图将被注入到各自的区域中。这意味着,每个区域都将有其对应的视图。在这里,MenuBar 视图将被注入到 MenuBar 区域,Content 视图将被注入到 Content 区域。

现在,请记住,我们不一定非要在 Shell 中,因为区域也可以在另一个视图中定义。

区域对视图一无所知。我们可以将内容定位到区域,而无需确切了解区域是如何以及在哪里定义的。这允许更改布局而不会影响模块中的视图。例如:在上面的图中,我们可以将“MenuBar 区域”移动到“Content 区域”的左侧,但我们的“MenuBar 视图”仍将注入到“MenuBar 区域”,“Content 视图”仍将放置在“Content 区域”中。因此,通过这种方式,我们可以在不重新编写任何类型的基础设施代码的情况下重新设计我们的 Shell。

区域可以在代码中或 XAML 中创建。我们需要记住的一点是,区域不是控件,而是一个宿主控件,并且它总是实现 IRegion 接口。这很重要,因为当您以编程方式访问区域时会使用它。

区域管理器

我希望,正如你们中的许多人可能已经猜到的那样,区域管理器负责管理应用程序中的区域。它通过维护区域集合来做到这一点。它还提供了一个 RegionName 属性。这实际上是一个附加属性,用于通过将其应用于宿主控件来创建区域,这可以通过 XAML 或代码再次完成。

Region Manager 还会将 RegionAdapter 映射到控件。现在,RegionAdapter 负责将 Region 与宿主控件关联起来。为了将 UI 控件公开为 Region,它必须具有 RegionAdapter,并且每个 RegionAdapter 都适应特定类型的 UI 控件。

Prism 为我们提供了四个 RegionAdapter

  • ContentControlRegionAdapter - 适应内容控件类型的控件
  • ItemsControlRegionAdapter - 适应内容控件类型的控件
  • SelectorRegionAdapter - 适应 Selector 类提供的控件,例如 Tab 控件
  • TabContorlRegionAdapter - 这仅包含在 SL 版本中,因为在 SL 中,它不属于 Selector 类,并且与 WPF 控件的行为略有不同

现在,如果 Prism 提供的 RegionAdapter 不满足我们的需求,我们当然可以创建自己的。

Region Manager 还提供了一个 RegionContext 附加属性。此属性类似于 DataContext 的概念。它是一种在父视图和子视图之间共享数据的技术。RegionContext 也可以从代码或 XAML 设置。

创建区域的示例代码片段

为了创建一个区域,需要在 XAML (Shell) 中添加以下引用

xmlns:local="http"//www.codeplex.com/prism"

接下来我们需要创建区域,如下:

<DockPanel>
  <ContentControl DockPanel.Dock="Top" local:RegionManager.RegionName="MenuBarRegion"/>
  <ContentControl local:RegionManager.RegionName="ContentRegion"/>
</DockPanel>

现在,转到 Module 类并添加以下内容

public class MyModule : IModule
{ 
   IUnityContainer _container;
   IRegionManager _regionManager;
   public MyModule(IUnityContainer container, IRegionManager regionManager)
   {
      _container = container; 
      _regionManager = _regionManager
   } 

   public void Initialize()
   {
      regionManager.RegisterViewWithRegion("MenuBarRegion", typeof(MenuBarView));
      regionManager.RegisterViewWithRegion("ContentRegion", typeof(ContentView));
   }
}

自定义区域

有时,我们需要使用第三方控件或自定义控件作为区域宿主。只要我们的自定义控件可以使用 Prism 提供的 RegionAdapter,就没有问题。但情况并非总是如此。因此,我们需要创建自己的 RegionAdapter 来将自定义控件作为区域宿主。我们只需遵循几个步骤

  • RegionAdapterBase<T> 派生您的类
  • 实现 CreateRegion 方法 - 此方法返回以下对象之一
    1. SingleActiveRegion(主要用于内容控件)
    2. AllActiveRegion(主要用于项控件)
    3. Region(主要用于从 Selector 类派生的控件)
  • 实现 Adapt 方法 - 这实际上是适应您的控件
  • 注册您的适配器

请观看本系列的下一篇文章,此处

© . All rights reserved.