Tuesday, 29 January 2008

Composite UI Application Block - Part Three

I know I promised to add another post a few months ago - I haven't managed to find the time until now.
Since then, I've started a new job which doesn't involve CAB at all. I still work on projects at home using CAB, but not as much as I'd like to.
I'm still confident the information I provide here will be accurate, but feel free to point out any mistakes I make.

Anyway, in my last post I talked about the main elements that make up CAB:
WorkItem, SmartPart, Workspace, Service and Event Broker.

I will now try to describe how these parts work together.

Your application could contain many different WorkItems - For example, an application I have worked on contains 3 WorkItems: Customers, Products and Orders.
WorkItems follow a tree structure - There is a single Root WorkItem, and all other WorkItems are descendants of this WorkItem.
Each WorkItem contains one or more SmartParts which are user controls that are displayed to the end user.
The Customers module contains a 'View Customer' form, 'Edit Customer' form and a 'List Customers' form. Each of these forms is a SmartPart.

When the application first loads, the modules registered with the application are instantiated.
All modules inherit from the ModuleInit base class.

It is up to the Module class to create an instance of a ControlledWorkItem - This is a generic class provided by CAB that represents a WorkItem that uses a ModuleController to perform it's business logic.
The module then invokes the Run() method of the ModuleController, which extends and modifies the toolstrips/menus/services associated with the application.
The ModuleController finally tells the module to add any default views to the application (via AddViews()).

So at a minimum, a standard Module is made up of two classes:

  1. The Module class, which specifies the Views to be added.
  2. The ModuleController class, which controls the Module and adds UI menus/toolstrips and services.

Back to the example I was using earlier -
My Customer module loads 'List Customers' as a default view. This is done with the following code inside the AddViews() method of the Module class:

CustomerList view = workItem.SmartParts.AddNew();
this._rootWorkItem.Workspaces["MainDockingWorkspace"].Show(view);

CustomerList is a SmartPart (ie: View). The first line creates a new instance of CustomerList and adds it to the current WorkItem (the Customer WorkItem). The second line then displays the view in the MainDocking Workspace. (I'll explain how these are added later). The MainDockingWorkspace is part of the RootWorkItem, so we must reference that WorkItem to retrieve the correct workspace.

This view is then displayed to the user. Each view has a Presenter - This Presenter is responsible for performing the business logic of the view.

A Workspace is anything that can display a UserControl. You can create your own Workspaces by simply implementing the IWorkspace interface. The Workspace is responsible for not only displaying the View, but deciding how to display it. For example, a TabWorkspace can display a single view, but switch between open views using a tab menu.

The shell application usually configures the workspaces that are available to use. For example, I have created a Windows Form that contains a DockingWorkspace. This DockingWorkspace is added to the RootWorkItem's Workspace collection.
This is also where you should configure any application-wide services (such as the UI Adapter Factories/Extension Sites).

In my application, I have created multiple 'Shells'. Each shell is looks completely different, but they all contain Workspaces/ExtensionSites (registered with the same names). This allows me to switch the look and feel of an application by simply swapping one Shell with another.

I will post more about Services and EventBroker tomorrow - hopefully this is enough for now to keep everyone interested.

3 comments:

Anonymous said...

Great! Now it makes some sense. I can wait for today's post.

Anonymous said...

Hi there!

Hope your promise will come true, and you post more of your experiences, as I'm just beginning to understand the concepts of CAB and Co.

Your explanations are about the best I found on the web today, so keep on going! :-)

BTW: Have you seen the PDF document by Sal Razzaq (http://www.razzaq.org/pub/ framework_composite_application_block.pdf)? The first overview is good, I just downloaded it and will have a look at it until tomorrow.

Anonymous said...

I second the second comment, please post more about CAB, its been months now!?

Also, you haven't put this post under the tag CAB.