CAB Smart Clients in an Agile World Part 2

Published 14 March 06 06:57 AM | Sam Gentile

So I was going to show how to tame this CAB beast by sharing what I learned on that “CAB Spike” about a month and 1/2 ago. Again, from Part 1 of this series, the Spike is when you have no clue what you are doing, have to leave the schedule of User Stories to go investigate some technical subject, understand it, and minimise risk to the project! So I combined one of the CAB walk-thrus during the Spike with our code base to see if I could up with an Application Shell. Lets call our company Acme to protect the guilty.

For me, CAB starts with the Module. What is a Module? Microsoft says, “One of the key goals of the Composite UI Application Block is to support the development of applications by using independent, but collaborating, modules.

The Composite UI Application Block promotes modularity by allowing you to implement business logic, visual SmartParts, infrastructure components, presenter or controller components, and any other objects the application requires, in separate modules.” CAB then does a lot of cool “wiring” type things underneath for you like placing SmartParts into workspaces, components to publish and subscribe to events without having to know about each other, allow components to share state and information by placing it into the State property of the WorkItem and many more. So the Module is the dynamic unit of stuff that CAB loads up that does a distinct composable unit of the UI.

So the first thing I did is create a WinForms project for the Application Shell and created a custom Work Item:

using Microsoft.Practices.CompositeUI;

public class AcmeShellApplication : FormShellApplication
AcmeShellForm> {

}
[STAThread]
static void Main() {
    new AcmeShellApplication().Run();
}

public class AcmeShellWorkItem : WorkItem {

}

he root of the non-display stuff in CAB is our class AcmeShellApplication,, which derives from the class FormShellApplication in the namespace Microsoft.Practices.CompositeUI.WinForms. This class derives from other base classes, namely WindowsFormsApplication, CabShellApplication and CabApplication. The AcmeShellApplication derived class, known as the application class, creates the root WorkItem, which contains the services and child WorkItems within the application.

The next thing to do is get CAB to load your module. CAB creates dynamic composable UIs by reading the list of Modules from, what else? An XML file of course! In this case, it reads from a file called ProfileCatalog.xml. This work is done in our derived ModuleInit class. The code looks like the following in the AcmeModuleInit.cs file:

// Initial : Sam Gentile

// ********************************************************************************

using System;

using System.Windows.Forms;

using Microsoft.Practices.CompositeUI;

using Microsoft.Practices.CompositeUI.Services;

using System.ComponentModel;

namespace Acme.Collateral.GUI.Core {

/// When it starts, the CAB automatically instantiates any class  that inherits from the ModuleInit class. We are adding a AcmeModuleInit class to our AcmeModule project so that the module can register its WorkItem when the application starts.///

 

public class AcmeModuleInit : ModuleInit {

    private IWorkItemTypeCatalogService acmeCatalogService;

    private WorkItem parentWorkItem;

    [ServiceDependency]

    public WorkItem ParentWorkItem {

        set { parentWorkItem = value; }

    }

/// Use the [ServiceDependency] attribute on this property so that the dependency injection feature of the underlying ObjectBuilder utility will create an instance of the service and pass back a reference to it:

    [ServiceDependency]

    public IWorkItemTypeCatalogService AcmeCatalogService {

        set { this.acmeCatalogService = value; }

    }

    public override void Load() {

         base.Load();

         AcmeWorkItem acmeWorkItem = parentWorkItem.WorkItems.AddNew<AcmeWorkItem>();

         acmeCatalogService.RegisterWorkItem<AcmeWorkItem>();

         acmeWorkItem.Run(parentWorkItem.Workspaces["tabWorkspace1"]);

         }

    }

}

The really cool thing here is the [ServiceDependency] attribute which uses the Dependency Injection pattern so that the WorkItem and the Catalog Service get automatically created. The Catalog Service is one of the services that CAB provides to read the modules from the Profile Catalog and load them. We then register our WorkItem with CAB and then we call Run on it telling it to place in a Workspace called “tabWorkspace1”.

WorkItems are a very interesting thing. The CAB docs say all this stuff of how they are the encapsulation of one use case scenario in your UI with everything related to that (Model, View, Presenters, Controls, Smart Parts, etc). So you may have a WorkItem that deals with Importing a file in your UI or to Print or to brew coffee-). But the interesting point brought up here in Redmond yesterday in the SCBAT workshop is that they are not really that. They are really Containers, nothing more, nothing less. They can be used to encapsulate and fulfill a Use Case but that’s not what they are. WorkItems You can use a WorkItem to encapsulate different use cases or areas of an application to share events and state. CAB also has a State service and an Event Broker system for events, among others. You can scope state and events to a WorkItem or globally. A WorkItem really bcomes a Container for implementing MVC or MVP.

Once we have registered the WorkItem with CAB, we call its run method, passing the Workspace of the parent WorkItem. Workspaces are components that encapsulate a particular visual way of displaying controls and SmartParts. They are like a canvas to project stuff into visually and lay it out. CAB ships with 5 pre-built Workspaces out of the box. We’ll look at this next in Part 3.

Now playing: The Rolling Stones - A Bigger Bang - She Saw Me Coming

Now playing: The Rolling Stones - A Bigger Bang - This Place Is Empty

Comments

# TrackBack said on March 14, 2006 09:42 AM:

Interesting Finds

# TrackBack said on March 14, 2006 09:42 AM:

Interesting Finds

# Chris Donnan said on March 14, 2006 06:25 PM:

Your article has reminded me that I was to do some comparing/ contrasting of Spring.net vs the ObjectBuilder, Injection Model of CAB. I am a huge CAB fan - but I have been a user of <a href="springframework.net/.../a> for my IoC needs. My 1st post in this series is <a href"chrisdonnan.com/.../a>. As it goes - over the next days/ weeks I will be giving CAB's injection model the old college try.

-Chris

PS - thanks for always providing an interesting read :)

# Chris Donnan said on March 14, 2006 06:25 PM:

Your article has reminded me that I was to do some comparing/ contrasting of Spring.net vs the ObjectBuilder, Injection Model of CAB. I am a huge CAB fan - but I have been a user of <a href="springframework.net/.../a> for my IoC needs. My 1st post in this series is <a href"chrisdonnan.com/.../a>. As it goes - over the next days/ weeks I will be giving CAB's injection model the old college try.

-Chris

PS - thanks for always providing an interesting read :)

# TrackBack said on March 20, 2006 01:58 AM:

CAB, SCBAT and GAT

# TrackBack said on March 20, 2006 01:58 AM:

CAB, SCBAT and GAT

# TrackBack said on April 5, 2006 01:05 AM:

New Drop of SCBAT

# TrackBack said on April 5, 2006 01:05 AM:

New Drop of SCBAT

# TrackBack said on July 20, 2006 07:10 PM:

Fowler Begins to Update Patterns of Enterprise Architecture

# TrackBack said on July 20, 2006 07:10 PM:

Fowler Begins to Update Patterns of Enterprise Architecture

# TrackBack said on October 19, 2006 12:06 PM:

New and Notable 116

# TrackBack said on October 19, 2006 12:06 PM:

New and Notable 116

# TrackBack said on December 4, 2006 04:18 PM:

Agile Project Use of CAB

# TrackBack said on December 4, 2006 04:18 PM:

Agile Project Use of CAB

# Sam Gentile said on December 11, 2007 06:16 PM:

Note 12/11/07 Reader reporting broken links. These have now been updated In comments to my post about

Leave a Comment

(required) 
(required) 
(optional)
(required) 

This Blog

News

    The content of this site are my own personal opinions and do not represent my employer's view in anyway.

    Profile for SamGentile

MVP

Blog Information Profile for SamGentile

Syndication