摘自电子书Programming Microsoft® Composite UI Application Block and Smart
Client Software Factory
Table 1-2. Definitions of Basic Terms
Used in a CAB Application
Shell Application |
The main
Windows Forms application, the outer container of all parts of a CAB
application.. The Shell Application manages the CAB startup process. |
Shell Form |
The main
window of the Shell Application. The generic term Shell used on its own usually means Shell Form, although not always. It usually contains
Workspaces and user interface elements such as
menus and toolbars |
Workspace |
The container window for a
SmartPart owned by a WorkItem;. The Workspace can control
how the SmartPart is displayed or hidden. The CAB provides several standard
Workspace classes, and you
can also write your own. |
WorkItem |
A
runtime container of the objects and services used by a discrete part of a CAB
application. Think of it as a logical sub-process or sub-application. It is the
basic unit of software scoping in a CAB application. Your business logic lives
in one or more WorkItems. |
SmartPart |
A
visual presentation, a view, of the data owned by a WorkItem; it is owned by a WorkItem and displayed in a Workspace. A SmartPart is
usually implemented as a Windows Forms User Control, often containing other
Windows Forms controls. Besides displaying the data of a WorkItem, it often allows the
user to modify it. |
Service |
A
supporting class that provides programmatic functionality to other objects in a
loosely coupled way. It usually contains utility methods that are not tied to a
specific work item. |
Module |
A .NET
assembly that provides the physical container for WorkItems, services, and their supporting
classes. |
如果以Excel来举例就是这样的
Table 1-3. CAB Equivalents of Common OLE
Functionality
CAB Item
OLE Equivalent
Shell
Application |
Word, the running
program |
Shell Form |
Word's main
window |
Workspace |
The area on Word's main window in which Word allows Excel
to display its editing window |
SmartPart |
The editing window created by Excel |
WorkItem |
Excel's business
logic |
Service |
OLE
libraries |
Module |
The physical file containing the business logic code,
Excel.exe |
WorkItem是一个运行时容器,该容器中包含完成一个用例所需要了各种各样的组件,组件可以是可视化的也可以是非可视化的,比如:SmartPart,Service,Commonds等等。
WorkItem中定义了如下的属性:
Services是一个集合,用来管理所有和实现一个用例相关的Service,可以通过如下代码将一个Service添加到WorkItem中:
WorkItem.Services.AddNew<TestService, ITestService>();
上述的代码中,第一个参数是一个具体Service的实现,第二个参数是该Service的接口。
一旦将一个Service添加到WorkItem中,该WorkItem中的其它组件(比如SmartPart)可以使用如下代码获取该Service的一个引用。
ITestSerivce service = WorkItem.Services.Get<ITestService>();
同样,我们也可以向一个WorkItem中添加一个SmartPart:
TestView view = WorkItem.SmartParts.AddNew<TestView>("TestView");
我们也可以通过下面方法获取一个已经存在的SmartPart
TestView view = WorkItem.SmartPart.Get("TestView");
同时使用下面代码将一个SmartPart显示在Workspace中:
if(view == null )
{
TestViewview=WorkItem.SmartParts.AddNew<TestView> ("TestView");
WorkItem.Workspaces[WorkspaceNames.XXXXX].Show(view);
}
else
{
WorkItem.Workspaces[WorkspaceNames.XXXXX].Activate(view);
}
在这段代码中,我们不难发现,当一个SmartPart已经存在的时候,我们不需要再添加一个实例到WorkItem中,这样可以保证对同一个SmartPart来说,只有一个实例在WorkItem中。
Workspaces的设计和上面SmartParts的设计一致,我们可以通过一个Workspace的唯一名字来获取对应的Workspace实例。
WorkItem.Workspaces[WorkspaceNames.XXXXX]
同样,UIExtensionSites也是一个集合,用来管理UIExtensionSite,我们可以通过下列方法将一个UIExtensionSite添加到WorkItem中:
WorkItem.UIExtensionSites.RegisteSite(UIExtensionSiteNames.XXXX, XXXXXXX;
将一个UIExtensionSite添加WorkItem之后,我们可以用下列方法添加一个UIElement到UIExtensionSite中,比如在ToolBarStrip上添加一个Button:
WorkItem.UIExtensionSites[Constants.UIExtensionSiteNames.ButtonsBar].Add(new ToolStripButton());
Commands集合用来管理Command,
WorkItem.Commands[Constants.CommandNames.TestButtonClick].AddInvoker(element, "Click");
WorkItem中还定义了其它一些集合变量,比如Events,WorkItems和Items。这里我们就不一一详述。
WorkItem hierarchy
在CAB中,WorkItem具有一定的层次,最顶端的WorkItem是RootWorkItem,它在整个应用程序中是唯一的。RootWorkItem会在应用程序开始的时候加载,当我们使用SCSF创建一个业务模块的时候,它自动会创建一个WorkItem,并在该模块加载的时候,将该WorkItem添加到RootWorkItem中去。一个WorkItem中的组件可以访问同一WorkItem中的其它组件,同时也可以访问父WorkItem中的组件。基本的访问规则如下,一个组件可以访问下列组件:
- 同一WorkItem中的
- 父WorkItem中的
- 祖父WorkItem中的(以此类推)
由此我们可以看出,RootWorkItem中的组件对于整个应用程序来说是共享的。我们可以activated and deactivated WorkItem。在同一时刻,只有一个WorkItem是处于激活状态。
从更高的层次上来说,一个WorkItem封装了一个Use-Case。WorkItem的层次性关系反映了业务中UseCases之间的关系。这样的一种关系可以帮助我们在设计阶段识别出相应的WorkItems。但是也并不是粒度越细越好,详细WorkItem设计参考其它文章。
CAB中我们使用Event Broker Service来处理不同Module之间的通信。这样的目的是为了保持各个业务模块之间的松耦合。当CAB加载一个Module的时候,它会遍历该模块中所有标记为EventPublications的事件和标记为EventSubscriptions的方法,将他们放入事件容器中,所有的EventTopic的实例都会放在WorkItem.EventTopics集合中。
Publish an Event
在CAB中,我们可以通过在一个Event前面添加一个EventPublication属性来发布一个事件。该属性(Attribute)有两个参数,一个是事件名,另外一个是事件发布的范围。这里我们有三种发布方式:
- PublicationScope.WorkItem,只对该WorkItem下有效
- PublicationScope.Descendants,对该WorkItem有效,同时对它子的WorkItem也有效
- PublicationScope.Global,对整个应用程序有效,对所有的WorkItem有效
下面的例子告诉我们如何发布一个全局有效的事件:
[EventPublication("event://UpdatesAvailable/New", PublicationScope.Global)]
public event SomeEventHandler UpdatesAvailable;
Subscribe an Event
同样,我们可以在一个方法前面添加EventSubscription属性来订阅一个事件(方法必须在事件发布范围之内)。不同的方法可以订阅同一个事件。在订阅事件的时候,我们可以指定该方法运行的线程规则,有三种可选的方案:
- ThreadOption.Background,系统会创建一个独立的后台线程运行该方法。
- ThreadOption.Publisher,该方法的执行和Publisher线程同步。
- ThreadOption.UserInterface,在当前激活的界面线程中执行。该选项可以保证编辑数据同时没有更新的数据。
下面的例子说明如何订阅一个事件,并其和当前界面同一线程处理:
[EventSubscription("event://UpdatesAvailable/New", Thread=ThreadOption.UserInterface)]
public void NewUpdates(object sender, SomeEventArgs numUpdates)
{
MessageBox.Show(numUpdates.ToString(), "Updates available");
}
Event Broker 的实现
在CAB中,Event Broker系统包含了下面几个类和接口:
- EventTopic,定义一个在Publisher和Subscriber之间的事件主题
- WorkItem,暴露一个EventTopics集合,它拥有一个注册EventTopic实例列表
- EventInspector,检查所有的对象或组件,看是否存在事件发布和订阅(EventPublication或EventSubscription属性)。如果有,将publications和subscriptions注册到EventTopic中,同时将EventTopic添加到WorkItem.EventTopics集合中。
当我们处理界面事件的时候,往往会遇到不同的界面元素处理同样的事件,比如:定义一个OpenFile菜单选项用来打开一个文件,同时定义在ToolBar上定义一个按钮来打开一个文件,这两个界面元素处理相同的业务。这时候,我们可以使用Command模式来处理此类设计。在CAB中,我们可以写一个事件处理方法,将该方法绑定到多个界面元素事件处理。
[CommandHandler(“TestButtonClick”)]
public void OnTestButtonClick(object sender, EventArgs e)
{
MessageBox.Show("Successful");
}
上述代码定义了一个Command处理方法,CommandHandler属性(Attribute)“伴随一个Command名字”,用来申明该方法是用来处理名为TestButtonClick的命令。我们可以通过下列方法将一个Command绑定到一个UIElement事件:
WorkItem.Commands[Constants.CommandNames.TestButtonClick].AddInvoker(element1, "Click");
WorkItem.Commands[Constants.CommandNames.TestButtonClick].AddInvoker(element2, "Click");
其中参数element1或element2是我们想要绑定的UIElement,比如一个Button和MenuItem。我们可以看出不同的UIElement绑定到相同的事件处理方法。
参考:Command Patterhttp://www.cnblogs.com/zhenyulu/articles/69858.html
一个CAB应用程序是由若干个Modules(DLLs)组成的。每个Module包含了很多的组件(Componet),这些组件既可以是可视化的也可以非可视化的组件,比方说SmartPart,Workspace,WorkItems,Services等等。
Component
CAB应用程序的最小单元是Component,它包含了下列类型的Component;
Visual Element
- SmartParts
- Items(Views 和 Controls)
Support for visual elements
- WorkItems
- Workspaces
- UIExtensionSites
Non-visual elements
- Commands
- EventTopics
- Services
Module
前面我们提到CAB应用程序是由Modules组成的,每个Module是一个独立的部署单元,CAB中提供一个在运行时加载Module的服务,在缺省情况下,该服务使用一个名为ProfileCatalog.xml文件来加载Modules。
当CAB加载一个模块的时候,它使用反射(Reflection)来判断该Module中是否包含一个实现IModule接口的类(通常情况下通过集成ModuleInit类来实现)。
我们可以使用SCSF来创建两种不同类型的Module:
- Functional Module -- 只是给其它模块提供一些服务,并不实现一个Use-case,不包含一个WorkItem
- Business Module -- 实现一系列相关的用例,包含WorkItems。
在CAB中,按Module来部署的这种设计可以让我们很容易的开发一个容易扩展的应用程序,每一个Module我们可以定义为一个Plugin,当一个成熟应用程序运行在客户现场的时候,我们可以很容易根据客户的需求开发一个独立的业务模块,而不会影响整个应用程序。各个业务模块之间的关系是松耦合的,我们可以通过EventPublisher和Subscribe模式来实现各个模块之间的相互操作或服务的调用。
对于一些通用的界面元素,比如MenuItem,Toolbar,StatusBar等等,CAB有它统一的定义和实现。
在CAB中,将这些统一的界面元素定义为UIExtensionSite,每一个UIExtensionSite是用一个唯一名字标识的。开发人员(通常来说是Shell开发人员)将一个界面元素注册为一个UIExtensionSite,下面代码描述将一个MenuStrip注册为一个UIExtensionSite:
RootWorkItem.UIExtensionSites.RegisterSite(“FileMenu”, Shell.MainMenuStrip);
一旦注册成功后,模块开发人员就可以使用它添加相关的界面控件,比如下面代码将一个MenuItem添加到菜单栏中:
ToolStripMenuItem printItem = new ToolStripMenuItem("Print"); RootWorkItem.UIExtensionSites[“FileMenu”].Add(printItem);
注意:虽然开发人员可以直接使用RootWorkItem.UIExtensionSites["XXXX"]来获取相关的UIExtensionSite,并添加相应控件,但是一般来说这不是一个好的设计,Shell开发人员最好定义一组通用的Shell服务接口,在这些接口中实现如何添加控件到UIExtensionSite中,对于Module开发人员,他们只需要调用相关的接口去添加控件到UIExtensionSite中,这样,Module开发人员不需要关心Shell实现的具体细节。比如:AddButtonToToolBarStrip, AddMenuItemToMenuStrip,等等。
SmartPart是一个应用程序的可视化组件,我们可以通过继承System.Windows.Forms.UserControl类来实现。一旦继承了UserControl类,开发人员就可以进行界面的设计。接下来我们需要将SmartPart显示在界面中(Workspace)。下面的代码描述了如何将SmartPart显示在指定的Workspace中:
TestView view = WorkItem.SmartParts.AddNew<TestView>();
WorkItem.Workspaces[“TestWorkSpace”].Show(view);
在上面的代码中,我们将TestView添加到WorkItem的SmartParts集合中,并且显示在名为“TestWorkSpace”的Workspace中。
Workspace是用来显示控件或SmartPart的组件,在CAB中包含了如下的Workspace类型:
- WindowWorkspace.
- MdiWorkspace.
- TabWorkspace.
- DeckWorkspace.
- ZoneWorkspace.
分享到:
相关推荐
微软官方的Smart Client Software Factory 2010 CHM 文档,不过是英文的,配合VS 2010,SCSF 3.0使用,以下是简介: The Smart Client Software Factory is a collection of assets that enables architects and ...
《Smart Client Software Factory》教程是深入理解CAB(Composite Application Block)和SCSF(Smart Client Software Factory)技术的重要参考资料。本教程旨在帮助开发者构建松耦合的复合UI(用户界面)应用程序,...
智能客户端软件工厂(Smart Client Software Factory,简称SCSF)则是微软提供的一个工具集,用于简化基于CAB的智能客户端应用的开发过程。它包含了各种模板和指导,帮助开发者快速创建符合企业级标准的、具有丰富...
Programming Microsoft® Composite UI Application Block and Smart Client Software Factory WinForm的CAB/SCSF框架
CAB是Smart Client Software Factory (SCSF)的核心部分,主要用于桌面应用开发,尤其是基于.NET Framework的应用。本篇将深入探讨CAB框架,包括其核心概念、功能以及如何通过示例进行实践。 首先,理解CAB的前提是...
在"智能客户端例子"这个项目中,我们看到开发者使用了Smart Client Software Factory(SCSF)工具来构建这样的应用程序。 Smart Client Software Factory是微软提出的一个开发框架,用于指导和加速智能客户端应用的...
SCSF(Smart Client Software Factory)实例是基于微软的Composite UI Application Block(复合UI应用程序块)技术,这是一种设计和构建智能客户端应用的框架。这个实例旨在帮助开发者更好地理解和应用Cab技术,提升...
**CAB SCSF - 架构**是一本专为希望深入了解基于Microsoft的Composite Application Block (CAB) 和 Smart Client Software Factory (SCSF) 设计复合智能客户端应用程序的读者准备的书籍。该书由微软奥地利分公司的...
SCSF,全称为Smart Client Software Factory(智能客户端软件工厂),是微软提出的一种企业级应用程序开发框架,主要用于构建桌面客户端应用。这个框架结合了多种技术,如Windows Forms、Enterprise Library、WCF等...
**Smart Client Software Factory (SCSF)** 是基于CAB的工具集,它为智能客户端应用程序提供了指导和模板。SCSF旨在帮助开发者遵循最佳实践,快速创建出符合Microsoft Windows桌面应用程序设计模式的项目。这些模式...
2. **Composite Application Block (CAB)**:CAB是Smart Client Software Factory的基础,提供了一种用于构建复合应用程序的框架。它包含一系列服务,如事件总线、工作区管理、依赖注入等,这些服务可以轻松集成到...
在本案例中,"SCSF"(Smart Client Software Factory)是一个关键概念,它是由微软公司推出的开发框架,主要用于构建智能客户端应用。SCSF结合了Windows Forms、WPF等技术,并提供了可重用的服务和组件,帮助开发者...