Prism框架深入解析:Bootstrapper与区域管理

在现代软件开发中,模块化和解耦是提高软件可维护性和可扩展性的关键。Prism框架正是为了帮助开发者设计出松耦合的组件,这些组件可以无缝集成和开发。每个应用程序都需要从某个地方开始,对于Prism应用程序来说,Bootstrapper和Shell是启动的关键。本文将深入探讨Bootstrapper及其初始化过程。

Bootstrapper

Bootstrapper是负责初始化应用程序的类。那么,它需要初始化什么呢?首先,需要初始化的是核心服务,然后是应用程序特定的服务。

核心服务是Prism库提供给非应用程序特定的服务,包括:

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

除了核心服务,Prism还初始化一些应用程序特定的服务。这些服务是特定于应用程序的,并且在所有应用程序模块中都是通用的。例如,如果正在开发一个RSS类型的应用程序,那么RSS Feed服务就是一个应用程序特定的服务,几乎所有的模块都会使用它来读取Feed。

Bootstrapper过程

Bootstrapper是一个非常重要的类,它控制着每个组件的装配过程。Prism库提供了一个默认的抽象Bootstrapper基类,其中包含许多虚拟方法。让来看一下Bootstrapper的过程。请记住,这个过程的大多数阶段将在后续文章中更详细地介绍。

首先,需要创建一个LoggerFacade,它主要负责日志记录。接下来,需要配置模块目录。然后,需要创建一个容器,可以选择任何容器,如Ninject、Unity、MEF等。Prism库实际上包括两个Bootstrapper类。一个叫做UnityBootstrapper,另一个是MEF,它包含了使用Unity或MEF作为依赖注入容器所需的大部分功能。

接下来,需要配置默认的区域适配器映射。因此,需要创建一个自定义的区域适配器,并在那里注册。然后,需要配置默认的区域行为。接着,将注册框架异常类型。然后,将创建Shell。接着,Shell将被初始化。最后,模块将被初始化。

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

为了使用Unity,需要向项目添加以下引用:

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

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

C# public class Bootstrapper : UnityBootstrapper { protected override System.Windows.DependencyObject CreateShell() { return Container.Resolve(); } 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应用程序。还将探讨区域适配器以及区域和RegionManager之间的关系。然后,将看到如何创建自定义区域,这对于Prism不支持的控件是必要的。

区域简单地说就是UI中将要呈现的任何动态内容的占位符。区域类似于ASP.NET的内容占位符。它只是一个命名位置,可以用来定义视图将出现的地方。希望记得之前讨论过Shell的概念以及如何包含区域,将视图注入到这些区域。

现在让快速举一个例子。在这个例子中,将有一个MenuBar区域和一个Content区域。这些区域定义了UI的区域,视图将被注入。每个区域应该明确命名,并描述将注入区域的内容类型。假设有一个模块,包含两个视图,分别命名为MenuBar视图和ContentView。这些视图将被注入到它们各自的区域。这意味着每个区域将有其对应的视图。这里MenuBar视图将被注入到MenuBar区域,ContentView将被注入到Content区域。

现在,请记住,不仅仅在Shell中定义区域,区域也可以在另一个视图中定义。区域对视图一无所知。可以将内容定位到区域,而不需要确切地知道区域是如何定义的。这允许在不影响模块中的视图的情况下更改布局。例如,在上图中,可以将'MenuBar区域'移动到'Content区域'的左侧,但'MenuBar视图'将被注入到'MenuBar区域','ContentView'仍然会被放置到'Content区域'。因此,可以重新设计Shell,而不需要重新编写任何类型的基础设施代码。

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

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

区域管理器还将区域适配器映射到控件。现在,区域适配器负责将区域与宿主控件关联起来。为了将UI控件暴露为区域,它必须有一个区域适配器,每个区域适配器适应特定类型的UI控件。

Prism为提供了四种区域适配器:

  • ContentControlRegionAdapter - 适应内容控制类型的控件
  • ItemsControlRegionAdapter - 适应内容控制类型的控件
  • SelectorRegionAdapter - 适应由Selector类提供的控件,如标签控件
  • TabContorlRegionAdapter - 这只包含在SL版本中,因为在SL中,它不是Selector类的一部分,并且与WPF控件的行为略有不同

现在,如果Prism提供的区域适配器不满足需求,完全可以创建自己的。

区域管理器还提供了一个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类并添加以下内容:

C# 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)); } }
  • 从RegionAdapterBase派生类
  • 实现CreateRegion方法 - 这个方法返回以下对象之一
  • 实现Adapt方法 - 这是实际适应控件的方法
  • 注册适配器
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485