Thunderclap, the Newsletter of Rolling
Thunder Computing
Volume 8, Number 1, Spring 2006
In this issue:
Public Training Class on Composite UI Application Block and SC-BAT in
Boston on July 10-13
Public Training Class in Iceland on .NET 2.0 May 2 - 5
New Book from David Platt: Why Software Sucks (and What You can Do About It)
Blatant Self-Promotion: New in-house class on Composite UI Application Block and SC-BAT
As I wrote in the last issue of this newsletter, the Composite UI Application Block (CAB) is an excellent way of organizing the development of a rich client application. As the MFC was a very good prefabrication of a monolithic single-user desktop file-oriented application, so CAB is a very good prefabrication for today’s applications, built of components developed by independent teams, controlled by runtime configuration, delivered over a network, and generally dealing with network operations instead of desktop-based files. CAB also works well with today's automated testing mechanisms and test-driven development, which we didn't often do back in the MFC days but frequently do today.
The only real drawback to CAB, as I described it in my previous newsletter is that it was somewhat inconvenient to use because it lacked the rapid development tools that today’s programmers demand and generally get in Visual Studio. For example, the original release of CAB didn’t provide a wizard to automatically generate a shell application or a module or an event subscription. So I found myself doing large amounts of cutting and pasting from sample code, reminiscent of how I (dating myself here) used to develop Windows SDK apps in the old days of Charles Petzold – remember how we'd cut and paste a WinMain with its message loop, with GetMessage, TranslateMessage, DispatchMessage, often adding TranslateAccelerators and sometimes PeekMessage to support background processing? Developing for CAB sometimes made me feel that way, as though swimming in tar. It was nice to gain architectural correctness and some amount of prefabrication; I just wanted to reap it much more quickly. If you remember the MFC and subtract its project generation and Class Wizard, you'll have some notion as to how it felt. I tried to improve it somewhat by providing a couple of Visual Studio project templates (again, see last newsletter), but there's a limit to how much any one guy can do.
These problems have now been solved. Microsoft’s new Smart Client Baseline Architecture Toolkit (SC-BAT) provides a much-improved set of tools that greatly expedite your development of CAB projects. SC-BAT also helps you use a some features from the Enterprise library in your CAB applications, mostly logging and exception handling. I'll probably cover these in a future newsletter. Developing a CAB application is now quicker than developing a non-CAB application, since many architectural decisions are now made for you and supported with prefabricated code.
SC-BAT is currently in its Community Technology Partners stage, from which I expect it to emerge sometime this summer. It's still a little tricky to get your development setup in place, requiring five separate downloads, including CAB itself. I expect this to get easier in future releases, but it's still not too bad, since I’ve collected them here for you. First, if you don’t already have it, you need to download and install CAB from (C# at this link, VB at this link). Second, you have to download and install the Guidance Automation Extensions at this location and the Guidance Automation Toolkit at this location. These are code extensions that allow developers to write better plug-ins for Visual Studio. The wizards and tools in SC-BAT are based on these, and I might devote an edition of this newsletter to them if I get enough requests for it. Third, you have to download and install the January 2006 Enterprise Library at this location. Finally, you must download and install the SC-BAT at this location. To install SC-BAT into your Visual Studio 2005 environment, open the readme file for the last download and follow its directions EXACTLY.
After you’ve done all this, you can start generating an SC-BAT project. Start Visual Studio, select File – New Project from the main menu, and you’ll find the Smart Client Development item under the Guidance Packages folder, as shown in the screen shot below. You can then generate project of the type called Lightweight Smart Client, which I will now discuss. (What a heavyweight smart client would be, the tools do not say).
When you generate this type of project, you will find a number of new and interesting files in your Solution Explorer, which looks like the screen shot below. I will now discuss some interesting parts of it.
First, look at the folder labeled Common. This is a frequently-used design pattern in which items that are shared among all components are placed in a separate assembly. This assembly is then made available to any project team that needs to develop code for the CAB project. All developers can then use the classes and definitions inside it without having to know anything about the other components of the application. And the definitions are kept in one place so they (hopefully, if you adhere strictly to this design pattern and resist the urge to allow back-channel sharing via other mechanisms) can’t get skewed between one project team and another. For example, any user interface extension sites exposed by the shell need to have their names known by the modules and work items that will be doing the actual extending. Instead of just sprinkling these string names through the code, you can now put them in the Constants object of the Common folder. You do the same for other shared development objects, such as commands and events.
This is the sort of thing that I meant earlier when I said that some “architectural decisions were already made for you.” You don’t have to sit around scratching your head, saying to yourself, “Now how the hell are we going to provide a single point of reference for command names?” You would probably have come up with something like this, but it’s already done for you in a reasonable way, so it’s easier to simply accept what SC-BAT has done for you instead of taking the trouble to undo it and then write your own. It saves time, and also makes your code similar to that of other developers, which again saves time and reduces the chance of errors.
In a similar manner, the shell application and shell form are likewise generated for you and set up the way that most app designers will want them most of the time. The shell form looks like this:
It contains a main menu strip, a tool strip, and a status strip. It also comes with two deck workspaces on it, not because you’ll necessarily want to use this type of workspace in this manner, but rather to demonstrate the sort of things that are possible rather than leaving a blank.
In the form’s code, you’ll see that the status strip’s main message area has been connected to a CAB event controlled by the event broker service. The name of the event is defined in the Common assembly, so the string is nicely shared among all developers that use it. And this means that changing the message in the status string does not require the component firing the event to know anything about the internal implementation used in the shell. Again, this is nothing that you couldn’t have done yourself, and you probably would have eventually gotten around to doing something similar, but here you are handed an implementation that is a) architecturally correct for most applications most of the time, so you don’t have to spend your time and effort designing it and possibly getting it wrong, and b) already implemented for you, so you don’t have to spend your time and effort implementing it and possibly getting it wrong, and c) done the same way in every project, so you will understand other developers code and they will understand yours. Thus:
[EventSubscription(EventTopicNames.StatusUpdate,
ThreadOption.UserInterface)]
public
void StatusUpdateHandler(object
sender, EventArgs<string>
e)
{
_statusLabel.Text = e.Data;
}
The shell application also contains pre-generated code that saves you time and effort. For example, the class types of the shell work item and shell form are automatically put into the generic angle-brackets of the main application class, so you don’t have to edit the code generated for you by the project wizard as CAB developers had to do in the early days. It also automatically adds a hander for unhandled exceptions (do I sense an oxymoron here?) so that you don’t forget it. This exception handling code uses the Exception Handling Block from patterns and practices, so it represents Microsoft’s current view of best practice for doing this sort of thing. I’ve already written about the advantages of doing it this way, so I won’t repeat that point, other than to say that here is another instance. Here are some portions of the shell application's startup code:
public
class
ShellApplication : FormShellApplication<WorkItem,
ShellForm>
{
[STAThread]
static void
Main()
{
AppDomain.CurrentDomain.UnhandledException +=
new
UnhandledExceptionEventHandler(AppDomainUnhandledException);
Application.SetCompatibleTextRenderingDefault(false);
try
{
new
ShellApplication().Run();
}
catch (Exception
ex)
{
HandleException(ex);
}
}
private
static void
AppDomainUnhandledException(object sender,
UnhandledExceptionEventArgs
e)
{
HandleException (e.ExceptionObject as
Exception);
}
private
static void
HandleException(Exception ex)
{
if (ex ==
null)
return;
ExceptionPolicy.HandleException (ex,
"Default Policy");
MessageBox.Show ("An
unhandled exception occurred, and the application is terminating.");
Application.Exit ();
}
}
The shell application also overrides the AfterShellCreated method, in which it registers the menu strip, the tool strip, and the status strip, as extension sites that other work items can manipulate. Again, this is what most developers will want most of the time, and it’s done using the names from the Common assembly. If you don’t want to allow extensions of one or more of these sites, it’s a trivial matter to comment them out. The code looks like this:
protected
override void
AfterShellCreated()
{
base.AfterShellCreated();
RootWorkItem.UIExtensionSites.RegisterSite(
UIExtensionSiteNames.MainMenu,
this.Shell.MainMenuStrip);
RootWorkItem.UIExtensionSites.RegisterSite(
UIExtensionSiteNames.MainStatus,
this.Shell.MainStatusStrip);
RootWorkItem.UIExtensionSites.RegisterSite(
UIExtensionSiteNames.MainToolbar,
this.Shell.MainToolbarStrip);
}
Now that we’ve examined the shell and common folders, let’s consider the case of adding a module to the CAB project. This is now easy. When you right-click on the solution and select Add, you’ll see that the menu now provides the option of a CAB Module, as shown in the screen shot below.
If you select it, you’ll , a wizard will ask for its name, then generate code similar to that shown below. It adds a new namespace to that of the root project, then adds a new class deriving from ModuleInit, the default implementation of the IModule interface. It provides an injection constructor that fetches and stores the root work item, again, what most modules want most of the time. It also overrides the Load method, and provides code that creates and adds a new work item to the root. Thus:
namespace
LightweightSmartClient1.MyOwnModule
{
public class
Module :
ModuleInit
{
private
WorkItem _rootWorkItem;
[InjectionConstructor]
public Module([ServiceDependency]
WorkItem rootWorkItem)
{
_rootWorkItem = rootWorkItem;
}
public override
void Load()
{
base.Load();
_rootWorkItem.WorkItems.AddNew<ControlledWorkItem<ModuleController>>();
}
}
}
The module uses the new ControlledWorkItem class, which is defined in the Common assembly (note that this location may change in the final release). This represents the evolution of architectural thought in the CAB world in which the WorkItem class is seen as primarily a container of items for a use case – of smart parts, of extension sites, of views, etc., and not a location for business logic code. In general, the Controller class is seen as the location for this code. The ControlledWorkItem class therefore automatically creates a Controller-derived class (LightweightSmartClient1.MyOwnModule.ModuleController in the example above) when it is created, and calls its Run() method to tell it to start up. This method is shown in the code below. You can see that there are now new callouts for doing useful things like extending the toolbar and menus, thus:
public
class
ModuleController : WorkItemController
{
public
override void Run()
{
AddServices();
ExtendMenu();
ExtendToolStrip();
AddViews();
}
private void AddServices()
{
//TODO: add services provided by the
Module. See: Add or AddNew method in
}
private void ExtendMenu()
{
//TODO: add menu items here,
normally by calling the "Add" method on
}
private void
ExtendToolStrip()
{
//TODO: add new items to the
ToolStrip in the Shell
}
private void AddViews()
{
//TODO: create the Module views, add
them to the WorkItem and
// show them
in a Workspace.
}
}
With the release of SC-BAT, CAB has become both more rigorous architecturally and also easier to use. That’s a rather neat trick. Because both of these qualities operate in tandem, I expect CAB and SC-BAT to become the standard for implementing rich client applications on the .NET platform, as the MFC became the standard for writing single-desktop file-related applications a decade ago.
As always, there is far too much to discuss in any single issue of this newsletter. For example, there it a wizard for adding event publications and subscriptions, which time and space won’t allow me to do more than mention the existence of. If you’d like to learn more about using CAB and SC-BAT applications, you can come to my public class at the Microsoft Technology Center in Waltham on July 10-13. Or you can have me teach it in-house at your company.
Until next time, as Red Green would say, "Keep your stick on the ice."
Why Software Sucks (and What You Can Do About It)
ISBN 0-321-46675-6
To Be Published by Addison-Wesley in Fall of 2006
You Can Pre-Order through Amazon.com
Anyone whose spoken with me in the last couple of years probably got an earful about the latest bee in my bonnet, the book entitled Why Software Sucks. I’m sure that I’ve inflicted sample chapters on just about everyone I know. You can hear me discuss it in Roy Osherove’s audio interview with Juval Lowy and me, recorded last summer. It’s online at this link.
I’ve now sold the book project, and we’re getting ready to go to press. It took a while to find the right publisher, A-W, (Microsoft Press wouldn’t touch it with the proverbial 5-meter pole, I can’t imagine why), and then to negotiate the contract, but we’re now all signed, and I’ve received, cashed, and spent the advance check. All eight chapters are in the can, and editing will commence shortly.
The title was originally my idea, but I also love the subtitle, suggested by my editor at A-W. I’ve always thought that the right subtitle can really make a book. Like the 60’s bestseller Everything You Always Wanted to Know About Sex (But Were Afraid to Ask). Or Werner von Braun’s autobiography, entitled I Aim for the Stars. Humorist Mort Sahl suggested that its subtitle ought to be, But Sometimes I Hit London. (If you don’t get that last one, go look up von Braun online. As Tom Lehrer famously sang about him in the sixties: “ … A man whose allegiance is ruled by expedience … ‘Once the rockets are up, who cares where they come down? That’s not my department,’ says Werner von Braun.”)
This is my first book aimed at end users, not programmers. Early returns from this market are highly positive. My barber, the librarian at my local public (dead tree edition) library, and the contractor who built my house, all report that early chapters are informative, entertaining, and easy to read.
I’m still working on the “what you can do about it,” piece. If you have any thought as to how ordinary users can make their voices heard, I’d like to hear them. Use the contact info link of this web site, if you don’t already have my email. Thanx.
I’ll have more to say as publication gets closer. Watch this space.
Blatant Self Promotion: Would you buy a used car from this guy?
NEW! 4-day In-House Training Class on Composite UI Application Block
The CAB that I describe above is useful, but has a steeper learning curve than other parts of .NET. My in-house training class on it will get you up and spinning in no time. See the online syllabus here, then call me to schedule yours.
5-day In-House Training Class on .NET or .NET for Insurance
.NET is here, and it's hot. It changes everything in the software business, and you can't afford to be without it. Rolling Thunder Computing now offers in-house training classes on .NET, using my book as the text. See the syllabi online here, then call to schedule yours.
ACORD XML for Insurance In Depth, Including Web Services
Insurance carriers, learn ACORD XML from David Platt. This 5-day class will give you everything you need to know to jump-start your application development. Learn about security and plug-and-play, and combining ACORD XML with XML Web Services. See the syllabus online here. It can be customized to your needs.
And now, the moment for which I know you've all been waiting -- the pictures of my two girls. Lucy, on the left, is now three. She loves cats, and she wants to grow the cat grass for our Simba. The grass came up, by unfortunately Simba hasn’t been interested. You can see Lucy with big sister Annabelle, who you can see has had a couple of visits from the tooth fairy. Those of you who have been watching this space will remember the pictures of her at birth, which I know I posted here about five minutes ago. Finally, you see Annabelle in her ballet class, which she loves. She’ll be in her first recital this coming June. Jackson Browne’s song For A Dancer” has since taken on a whole new meaning for me.
Photographs by Ellen Spector Platt
Thunderclap is free, and is distributed via e-mail only. We never rent, sell or give away our mailing list, though occasionally we use it for our own promotions. To subscribe, jump to the Rolling Thunder Web site and fill in the subscription form.
Legal Notices
Thunderclap does not accept advertising; nor do we sell, rent, or give away our subscriber list. We will make every effort to keep the names of subscribers private; however, if served with a court order, we will sing like a whole flock of canaries. If this bothers you, don't subscribe.
Source code and binaries supplied via this newsletter are provided "as-is", with no warranty of functionality, reliability or suitability for any purpose.
This newsletter is Copyright © 2005 by Rolling Thunder Computing, Inc., Ipswich MA. It may be freely redistributed provided that it is redistributed in its entirety, and that absolutely no changes are made in any way, including the removal of these legal notices.
Thunderclap is a registered trademark ® of Rolling Thunder Computing, Inc., Ipswich MA. All other trademarks are owned by their respective companies.