Microsoft patterns & practices Composite UI Application Block (CAB) based Module Composite Mapper Service:一个用于工作空间、UI元素、命令和事件发布/订阅的XML可配置生成器






4.51/5 (16投票s)
本文提供了一个基于 Microsoft patterns & practices Composite UI Application Block (CAB) 的模块复合映射器服务,包含 C# 源代码,该服务使用模块指定的 XML 配置文件来构建工作空间、UI 元素、命令以及事件的发布/订阅。
引言
本文提供了一个基于 Microsoft patterns & practices Composite UI Application Block (CAB) 的模块复合映射器服务,包含 C# 源代码,该服务使用模块指定的 XML 配置文件来构建工作空间、UI 元素、命令以及事件的发布/订阅。模块复合映射器服务基于 CAB,并在一个概念验证 (POC) 框架内使用模型-视图-表示器 (MVP) 模式执行。本文及其包含的源代码提供了 POC 框架类、模块复合映射器服务类、模块复合映射器 XML 配置文件语法及示例、模块复合映射器主题格式指南以及示例/模板模块。
除了下文将进一步详细描述的 POC 框架和模块复合映射器服务项目外,本文上下文中还引用了以下 CAB 项目,其定义与 CAB 文档中的类似,如下所示:
- 模块 (Module):CAB 应用程序的独立部署单元;模块提供了关注点分离,例如,一个模块可以包含特定应用程序类型的所有(或逻辑分组的)基础结构服务,或者一个模块可以包含实现特定(或逻辑分组的)用例的组件,包括工作项、命令、事件、智能部件 (SmartParts)、服务和其他组件。
- 外壳 (Shell):代表应用程序的主窗口,并提供核心 UI 项,如菜单、工具栏、状态栏和工作空间;托管在外壳中的控件(即由模块复合映射器构建的模块指定的 UI 元素)在整个应用程序中共享,例如菜单项、工具栏按钮或状态面板(核心菜单项如“文件-退出”和“帮助-关于”由外壳本身处理);模块使用工作空间来显示其特定角色的用户界面。
- 服务 (Service):为应用程序提供基础结构功能(例如,CAB 特定的模块加载器服务和 POC 框架的模块复合映射器服务)。
概念验证框架
模块复合映射器服务基于 CAB,并在一个概念验证 (POC) 框架内使用模型-视图-表示器 (MVP) 模式执行。虽然 POC 框架可以根据您的需求进行修改(或完全移除),但以下内容将更详细地描述 POC 框架的基类。请注意,POC 框架外壳对本地启动目录使用原生的基于 CAB 反射的模块加载器服务。
- 模块初始化类 (例如MyModuleInit):在 POC 框架中,实际上只是模块工作项的引导机制) (包含在任何模块的根命名空间中)
- 工作项接口和类(IXSWorkItem和XSWorkItem): MVP 模式中的模型桥梁(即,与底层业务对象通信状态)和/或模型实现(即,与持久层通信状态),它包含了视图(即智能部件)、表示器和其他组件(即 UI 元素、命令、事件、服务等),这些组件在运行时协作以实现特定的用例(包含在任何模块的根命名空间中);在 POC 框架中,基于工作项的复合映射在工作项构建时(即 OnBuiltUp)应用,确保事件的发布/订阅与原生的 CAB 应用程序初始化序列一致(以及在外壳工作空间、UI 元素和命令初始化之后,在可能依赖于外壳托管项的模块目录枚举之前)。
this.RootWorkItem.Services.Get<IXSModuleCompMpprService>().ApplyModuleMappings(this);
在 POC 框架中,请注意,基础工作项和表示器类提供了通用事件,以提高编程效率和优化基础结构性能,避免了需要使用模块复合映射器服务重复指定此类应用程序范围的事件(即,使用原生的 CAB 事件发布声明模型)。
- 表示器接口和类(IXSPresenter和XSPresenter): MVP 模式中的表示器,它根据广播/接收到的事件或来自/发往参与的工作项(即模型)的方法调用来管理最终用户显示的视图(包含在任何模块的 SmartParts 命名空间中);在 POC 框架中,基于表示器的复合映射在表示器构造时应用(这发生在所属的 XSWorkItem.Run 上),确保视图在实际显示之前不会被复合映射器类(例如 XSWorkspaceCompMppr)访问。
this.workItem.RootWorkItem.Services.Get<IXSModuleCompMpprService>().ApplyModuleMappings(this);
如前所述,POC 框架的基础工作项和表示器类提供了通用事件,以提高编程效率和优化基础结构性能,避免了需要使用模块复合映射器服务重复指定此类应用程序范围的事件(即,使用原生的 CAB 事件发布声明模型)。
- 视图接口和类(IXSView 和 XSView): MVP 模式中的视图,它仅根据来自/发往参与的表示器的方法调用来提供最终用户显示(包含在任何模块的 SmartParts 命名空间中)。
模块复合映射器服务
模块复合映射器服务允许模块开发人员使用模块复合映射器 XML 配置文件(语法将进一步详细描述)指定以下复合类型。请注意,复合是一个通用术语,用于描述以下任何一项:
- 工作区: 封装了控件和智能部件的特定布局,例如在选项卡页面内;在 POC 框架中,主要适用于外壳表示器,它提供了接口以便轻松地在所需的工作空间中显示模块视图。
- UI 扩展站点 (UI Extension Site): 由扩展站点主题标识,提供一个 UI 元素适配器,作为任何已注册 UI 元素(即用于添加和删除子 UI 元素)的扩展点;在 POC 框架中,允许模块在外壳内指定用户界面元素扩展(例如,菜单、工具栏和状态栏项),包括最终用户通过插入优先级控制添加的 UI 元素的顺序。
- 命令 (Command):将模块表示器上定义的命令处理程序方法与任何命令主题关联起来。
- 事件发布 (Event Publication):将在模块工作项或表示器上定义的方法指定为事件广播的发布处理程序。
- 事件订阅 (Event Subscription):将在模块工作项或表示器上定义的方法指定为事件接收的订阅方法。
模块开发人员与模块复合映射器服务的交互最少,仅通过以下项目进行(包含在任何模块的 Services.XSModuleCompMppr 命名空间中):
- 模块复合映射器 XML 配置文件规范
- 用于视图显示的工作空间主题访问(来自外壳的工作空间复合映射器……一个XSWorkspaceCompMppr类的静态属性)
- 用于视图管理的用户界面元素访问(来自特定于表示器的 UI 扩展站点复合映射器……一个XSPresenter基类属性)
模块复合映射器服务类
- 模块复合映射器服务接口和类(IXSModuleCompMpprService和XSModuleCompMpprService): 一个单例服务类,管理模块复合映射器的创建,并将模块复合映射的应用(在工作项或表示器级别)委托给其包含的模块复合映射器。
模块复合映射器服务在 shell 应用程序的 AddServices 方法中实例化和注册,如下所示:
XSModuleCompMpprServiceservice =XSModuleCompMpprService.CreateInstance();
this.RootWorkItem.Services.Add<IXSModuleCompMpprService>(service); - 模块复合映射器类(XSModuleCompMppr): 使用模块指定的 XML 配置文件(以及一个私有的基于 XMLReader 的加载器类,XSModuleCompMpprLoader) 构建模块复合映射器对象层次结构,并将复合映射的应用(在工作项或表示器级别)委托给其包含的复合映射器;请注意,模块复合映射器类将事件发布和事件订阅复合映射应用于工作项和表示器(如配置文件中所指定),而工作空间、UI 扩展站点和命令复合映射仅应用于表示器,这是基于 POC 框架实现中对 MVP 模式的解释。
- 复合映射器类:作为服务的“主力”,复合映射器类根据从模块复合映射器 XML 配置文件构建的所包含的复合体(如果有的话),应用复合映射(在工作项或表示器级别,使用重载的 ApplyCompositeMappings 方法)。
复合映射器类上提供了几个独特的接口,包括:
XSWorkspaceCompMppr.ShellWorkspaceCompMppr:外壳的工作空间复合映射器,允许...
XSWorkspaceCompMppr.GetWorkspaceTopic:通过预定义的工作空间类型访问工作空间主题以显示视图。
基础的XSPresenter.ShowView 方法在请求的工作空间中显示其当前视图,如下所示:
受保护的 voidShowView(XSWorkspaceTypethisWorkspaceType)
{
this.workItem.RootWorkItem.Workspaces[
XSWorkspaceCompMppr.ShellWorkspaceCompMppr.GetWorkspaceTopic(
thisWorkspaceType)].Show(this.View);
}
XSUIExtSiteCompMppr.GetUIElements:表示器通过用户界面元素访问来进行视图管理(例如,在命令调用时设置菜单项和工具栏项的 Checked 属性);目前,所有与主题参数匹配的 UI 元素都会被返回,包括 UI 元素的命令、注册或父主题属性(显然,这可以根据您的需求进行修改或扩展)。
- 复合类:复合体本质上是由模块复合映射器 XML 配置文件(只读)持久化并直接构建的;每个复合类都提供了静态对象创建方法(即 CreateInstance),包括对从XSModuleCompMpprLoader加载器类传递的 XML 配置文件输入参数的一些验证。
模块复合映射器 XML 配置文件语法及示例 (XSModuleCompMppr.xml)
下面详细提供了模块复合映射器 XML 配置文件的语法,包括复合规范示例。模块复合映射器服务目前要求配置文件满足以下条件才能正常工作:
- 配置文件及任何关联的图像文件必须设置为在容器模块项目中作为嵌入式资源进行编译。
- 配置文件的位置和名称必须遵循以下命名空间层次结构,即文件夹和文件名(假设项目名称为 MyComponentModule):
MyComponentModule.Services.XSModuleCompMppr.XSModuleCompMppr.xml
该XSModuleCompMppr.CreateInstance 方法使用以下代码,以便使用IXSWorkItem参数类型(因为它预计位于程序集的默认命名空间中)、标准的模块复合映射器服务程序集扩展命名空间和文件名来获取清单资源流(参考XSModuleCompMppr.AssyXSModuleCompMpprNS)
mpprStream = thisWorkItem.GetType().Assembly.GetManifestResourceStream(
thisWorkItem.GetType(),
XSModuleCompMppr.AssyXSModuleCompMpprNS);
XSModuleCompMppr.xml 语法
<XtensibleSolutions version="2.0" language="XSModuleCompMppr">
<!--模块复合映射器包含复合映射器:
* 工作空间 (Workspace)(可选;仅适用于外壳表示器)
* UI 扩展站点 (UI extension site)(可选)
* 命令 (Command)(可选)
* 事件 (Event)(可选)
注意:所有 WorkItems/Presenters 都会发布通用事件。-->
<Module_Composite_Mapper>
<!--工作空间复合映射器包含工作空间复合体
* 工作空间类型描述符(可选;仅为可读性)以及...
* 工作空间类型枚举值(必需)
* 工作空间主题(必需)-->
<Workspace_Composite_Mapper>
<Workspace_Composite
XSWorkspaceType_Descriptor="Foo"
XSWorkspaceType_Enum="0"
Workspace_Topic="wks://XS/Shell/Foo"/>
<!--UI 扩展站点复合映射器包含 UI 扩展站点复合体:
* 父主题 (Parent topic)(必需)
* 插入优先级 (Insert priority)(可选 - 默认为 0.0;用于指示
UI 元素相对于其同级
项的定位插入优先级);如果未填充,则分配空优先级 (0.0) 并使用默认
CAB 行为进行请求的插入(作为最后一项追加);
如果已填充(使用浮点数值),则分配指定的优先级并
用于定位请求的插入,其中:
- 指定的数值越小,其优先级越高,该项
将越靠近列表顶部,如果不是第一项的话(即 1.0 被
认为是“第一优先级”,尽管实际算法在下限上没有实际限制,
同时也考虑了 0.0 的特殊值)
- 指定的数值越大,其优先级越低,该项
将越靠近列表底部,如果不是最后一项的话(例如 99.0 的
优先级低于 1.0)
- 优先级相等时,现有项优先(即,
新项插入到与其优先级相等的项之后)
- 已分配的优先级总是优先于那些未分配的
(未分配的会作为最后一项追加)(例如,99.0 的优先级高于
0.0)
* UI 元素类型 (UI element Type)(可选 - 默认为 "ToolStripMenuItem")
* UI 元素属性 (UI element properties)(可选;一个通用属性,使用
属性|值|属性|值|... 对来配置
创建的 UI 元素上的几乎任何属性);当前
支持的属性类型包括字符串、布尔值和图像...
示例:
"Text|&File":将 UI 元素的 Text 属性设置为 "File",
并将 "F" 指定为 UI 元素的助记符
"Checked|true":将 UI 元素的 Checked 属性设置为 True
"Image|MyImageFile.ico":从指定的图像文件设置 UI 元素的 Image 属性
(例如,工具栏图标);图像必须
根据属性规范命名(例如,MyImageFile.ico),
与复合映射器文件一起位于 XSModuleCompMppr
文件夹中,并编译为嵌入式资源
* 注册主题 (Register topic)(可选)以及...
* 注册属性 (Register property)(可选 - 默认为 "DropDownItems";用于
指示创建的 UI 元素上的哪个属性被注册为
扩展点)
* 命令主题 (Command topic)(可选)以及...
* 命令事件名称 (Command event name)(可选 - 默认为 "Click")-->
<UIExtensionSite_Composite_Mapper>
<UIExtensionSite_Composite
Parent_Topic="ste://XS/Shell/Menu"
Insert_Priority="1.0"
UIElement_Type="ToolStripMenuItem"
UIElement_Properties="Text|&文件"
Register_Topic="ste://XS/Shell/Menu/File"
Register_Property="DropDownItems"
Command_Topic="cmd://XS/Shell/File_Click"
Command_EventName="单击"/>
</UIExtensionSite_Composite_Mapper>
<!--命令复合映射器包含命令复合体:
* 命令主题(必需)
* 命令处理程序方法名(必需)-->
<Command_Composite_Mapper>
<Command_Composite
Command_Topic="cmd://XS/Shell/FileExit_Click"
Command_HandlerName="OnFileExit_Click"/>
</Command_Composite_Mapper>
<!--注意:所有 WorkItems/Presenters 都会发布通用事件。-->
<!--事件发布复合映射器包含事件发布复合体:
* 事件主题(必需)
* 发布范围描述符(可选;仅为可读性)以及...
* 发布范围枚举值(可选 - 默认为
全局 {0});值包括(更多信息请参阅 CAB 帮助):
- 全局 {0} (Global)
- 工作项 {1} (WorkItem)
- 后代 {2} (Descendants)
* 发布者类型描述符(可选;仅为可读性)以及...
* 发布者类型枚举值(可选 - 默认为 WorkItem {0});
值包括:
- 工作项 {0} (WorkItem)
- 表示器 {1} (Presenter)
* 发布处理程序方法名(必需)-->
<EventPublication_Composite_Mapper>
<EventPublication_Composite
Event_Topic="evt://XS/MyModule/MyEvent"
PublicationScope_Descriptor="全局"
PublicationScope_Enum="0"
XSEventPubSubType_Descriptor="WorkItem"
XSEventPubSubType_Enum="0"
Publication_HandlerName="BroadcastMyEvent"/>
</EventPublication_Composite_Mapper>
<!--事件订阅复合映射器包含事件订阅复合体:
* 事件主题(必需)
* 订阅者类型描述符(可选;仅为可读性)以及...
* 订阅者类型枚举值(可选 - 默认为 WorkItem {0});
值包括:
- 工作项 {0} (WorkItem)
- 表示器 {1} (Presenter)
* 订阅方法名(必需)-->
<EventSubscription_Composite_Mapper>
<EventSubscription_Composite
Event_Topic="evt://XS/MyModule/MyEvent"
XSEventPubSubType_Descriptor="WorkItem"
XSEventPubSubType_Enum="0"
Subscription_MethodName="OnReceiveMyEvent"/>
</EventSubscription_Composite_Mapper>
</Module_Composite_Mapper>
</XtensibleSolutions>
模块复合映射器主题格式
以下小节提供了关于标准模块复合主题格式的指南,包括示例。这些示例使用参数字符串和方法特性来提供上下文和清晰度,而模块复合映射器服务实际上通过使用单点配置的模块复合映射器文件,避免了对这些修饰的需求。
工作空间主题格式
wks(工作空间)
XS (Xtensible Solutions, Inc. 或最终用户公司)
ModuleName(或 Generic,如果应用于整个应用程序)
Descriptor00/Descriptor01/...
(客户端定义;工作空间主题描述符应使用相关XSWorkspaceType名称后跟具体实例的简要说明,例如 WorkspaceTypeFooMain)
示例
this.RootWorkItem.Workspaces.Add(
this.Shell.GetWorkspace(XSWorkspaceType.WorkspaceTypeFoo),
"wks://XS/Shell/WorkspaceTypeFooMain");
this.RootWorkItem.Workspaces["wks://XS/Shell/WorkspaceTypeFooMain"].Show(this.view);
UI扩展站点主题格式
ste (UIExtensionSite)
XS (Xtensible Solutions, Inc. 或最终用户公司)
ModuleName(或 Generic,如果应用于整个应用程序)
Descriptor00/Descriptor01/...
(客户端定义;站点主题描述符应使用指向目标 UIElement 的路径)
示例
this.RootWorkItem.UIExtensionSites.RegisterSite(
"ste://XS/Shell/Menu", this.Shell.MainMenuStrip);
this.RootWorkItem.UIExtensionSites.RegisterSite(
"ste://XS/Shell/Menu/File", fileMenuItem);
命令主题格式
cmd (command)
XS (Xtensible Solutions, Inc. 或最终用户公司)
ModuleName(或 Generic,如果应用于整个应用程序)
Descriptor_Event
(客户端定义;命令主题描述符应使用事件的简要说明,后跟正在处理的实际事件,例如 "FileExit_Click")
命令调用者:Descriptor_Event(例如,FileExit_Click)
命令处理方法:OnDescriptor_Event(例如,OnFileExit_Click)
示例
命令调用者
workItem.Commands["cmd://XS/Shell/FileExit_Click"].AddInvoker(fileExitMenuItem,"Click");
命令处理程序
[CommandHandler("cmd://XS/Shell/FileExit_Click")]
public voidOnFileExit_Click(objectsender,EventArgse) { myObject.MyMethod(); }
事件主题格式
evt(事件)
XS (Xtensible Solutions, Inc. 或最终用户公司)
ModuleName(或 Generic,如果应用于整个应用程序)
描述符
(客户端定义;事件主题描述符应使用要广播的事件的简要说明)
事件发布处理程序:BroadcastDescriptor(例如,BroadcastFoo)
事件订阅方法:OnReceiveDescriptor(例如,OnReceiveFoo)
示例
事件发布
发布处理程序本身...
[EventPublication("evt://XS/Generic/Foo")]
public 事件 EventHandler<DataEventArgs<字符串>> BroadcastFoo;
用于从引用类调用发布处理程序的公共方法。虽然对于不应由发布类本身以外的类调用的事件不是必需的,但如果适用,它为可能也需要调用事件的引用类提供了一个接口,例如,视图可能会调用其所属表示器上定义的事件...
public voidDoBroadcastFoo(objectsender,字符串thisMessage)
{
this.BroadcastFoo(sender,new DataEventArgs<字符串>(thisMessage));
}
事件订阅
[EventSubscription("evt://XS/Generic/Foo")]
[EventSubscription("evt://XS/Generic/Bar")]
public voidOnReceiveGeneric(objectsender,DataEventArgs<字符串> e)
{
myObject.MyMethod(e.Data);
}
示例模块
XSShell
XSShell 应用程序模块提供了核心 UI 项,如菜单、工具栏和工作区。
- 模块复合映射器文件 (XSModuleCompMppr.xml)
为 Foo 工作空间类型指定一个工作空间主题
<Workspace_Composite
XSWorkspaceType_Descriptor="Foo"
XSWorkspaceType_Enum="0"
Workspace_Topic="wks://XS/Shell/Foo"/>
在标准文件菜单上指定一个用户界面元素
<UIExtensionSite_Composite
Parent_Topic="ste://XS/Shell/Menu"
Insert_Priority="1.0"
UIElement_Properties="Text|&文件"
Register_Topic="ste://XS/Shell/Menu/File"/>
<UIExtensionSite_Composite
Parent_Topic="ste://XS/Shell/Menu/File"
UIElement_Properties="Text|E&xit"
Command_Topic="cmd://XS/Shell/FileExit_Click"/>
为表示器上的 UI 元素指定一个命令处理程序
<Command_Composite
Command_Topic="cmd://XS/Shell/FileExit_Click"
Command_HandlerName="OnFileExit_Click"/>
在 POC 框架中,XSShellApplication 类重写了 AfterShellCreated 方法,以注册核心 UIExtensionSites 来支持模块复合映射器服务
this.RootWorkItem.UIExtensionSites.RegisterSite(
"ste://XS/Shell/Menu",
XSToolStripUIAdapterFactory.GetAdapter(this.Shell.MainMenuStrip));
this.RootWorkItem.UIExtensionSites.RegisterSite(
"ste://XS/Shell/Toolbar",
XSToolStripUIAdapterFactory.GetAdapter(this.Shell.MainToolStrip));
MyServerModule
MyServerModule 在外壳上提供了一个用户界面,用于在应用程序运行时动态加载另一个模块 (MyClientModule)。
- 模块复合映射器文件 (XSModuleCompMppr.xml)
在标准工具菜单上指定一个用户界面元素
<UIExtensionSite_Composite
Parent_Topic="ste://XS/Shell/Menu/Tools"
Insert_Priority="1.0"
UIElement_Properties="Text|&加载客户端"
Command_Topic="cmd://XS/MyServerModule/ToolsLoadClientModule_Click"/>
为表示器上的 UI 元素指定一个命令处理程序
<Command_Composite
Command_Topic="cmd://XS/MyServerModule/ToolsLoadClientModule_Click"
Command_HandlerName="OnToolsLoadClientModule_Click"/>
指定对 MyClientModule ClientEvent 的事件订阅
<EventSubscription_Composite
Event_Topic="evt://XS/MyClientModule/ClientEvent"
Subscription_MethodName="OnReceiveClientEvent"/>
- 表示器类 (MyServerPresenter):定义一个命令处理程序(OnToolsLoadClientModule_Click),该处理程序...
禁用标准工具菜单上的用户界面元素
在工作项上调用 LoadClientModule
- 视图类 (XSView):未定义特定于模块的视图类(基础视图实现在表示器上实例化)
- 工作项类 (MyServerWorkItem):
定义一个方法(LoadClientModule),该方法使用模块加载器服务加载另一个模块(MyClientModule,路径硬编码)
定义一个订阅方法(OnReceiveClientEvent),在接收到 MyClientModule ClientEvent 时显示一个消息框
MyClientModule
MyClientModule 在 shell 上提供了一个用户界面,允许最终用户在整个应用程序中广播模块定义的事件,以及显示或隐藏其视图。
- 模块复合映射器文件 (XSModuleCompMppr.xml)
在标准视图菜单和工具栏上指定用户界面元素(注意 Checked 和 Image 属性设置)
<UIExtensionSite_Composite
Parent_Topic="ste://XS/Shell/Menu/View"
Insert_Priority="1.0"
UIElement_Properties="Text|&Client|Checked|true"
Command_Topic="cmd://XS/MyClientModule/ViewMyClient_Click"/>
<UIExtensionSite_Composite
Parent_Topic="ste://XS/Shell/Toolbar"
Insert_Priority="1.0"
UIElement_Type="ToolStripButton"
UIElement_Properties="Image|LoadClientModule.ico|Checked|true"
Command_Topic="cmd://XS/MyClientModule/ViewMyClient_Click"/>
为表示器上的 UI 元素指定一个命令处理程序
<Command_Composite
Command_Topic="cmd://XS/MyClientModule/ViewMyClient_Click"
Command_HandlerName="OnViewMyClient_Click"/>
通过其在表示器上的发布处理程序发布一个模块定义的事件
<EventPublication_Composite
Event_Topic="evt://XS/MyClientModule/ClientEvent"
XSEventPubSubType_Enum="1"
Publication_HandlerName="BroadcastClientEvent"/>
- 表示器类 (MyClientPresenter):
构造时在 Bar 工作区(而不是 Foo)显示视图
定义一个发布处理程序 (BroadcastClientEvent),用于广播模块定义的事件
定义一个命令处理程序 (OnViewMyClient_Click),用于显示/隐藏其视图
OnViewMyClient_Click 命令处理程序设置视图的可见性,并使用表示器的UIExtSiteCompMppr.GetUIElements 方法在命令调用时设置菜单项和工具栏项的 Checked 属性
boolvisible = (!(view.Visible));
foreach (ToolStripItemuiElementin
this.UIExtSiteCompMppr.GetUIElements(((命令)sender).Name))
uiElement.GetType().GetProperty("Checked").SetValue(uiElement, visible,null);
view.Visible = visible;
- 视图类 (MyClientView): 定义一个本地用户界面事件 (uiButtonBroadcastClientEvent_Click),该事件...
调用表示器上的发布处理程序 (DoBroadcastClientEvent)
结论
模块复合映射器服务为在基于 CAB 的应用程序中动态构建工作区、UI 元素、命令以及事件发布/订阅提供了一种一致、可通过 XML 配置且每个模块单一持久化的范例。无论微软 patterns & practices CAB 团队未来实现何种复合构建器架构,模块复合映射器服务都为从当前(相对未定义)的方法过渡到任何面向生产的模块复合开发过程提供了一个清晰、简洁且良好分离的框架。事实上,鉴于目前已有的面向 XML 配置的复合构建器代码片段,尽管其范围通常比模块复合映射器服务有限,但人们应该能够相对无缝地从模块复合映射器服务迁移到任何后续方法,或在两者之间进行集成。