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, 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 first thing I did is create a WinForms project for the Application Shell and created a custom Work Item:
using Microsoft.Practices.CompositeUI.WinForms;
public class AcmeShellWorkItem : WorkItem {
}
public class ShellApplication : FormShellApplication
AcmeShellForm>
{
}[STAThread]
static void Main() {
new AcmeShellApplication().Run();
}
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. 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.AddNewAcmeWorkItem>();
acmeCatalogService.RegisterWorkItemAcmeWorkItem>();
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. We then register our WorkItem with CAB and then we call Run on it telling it to place in a Workspace called “tabWorkspace1”. 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