Thunderclap, the Newsletter of Rolling Thunder Computing

Volume 8, Number 3, Spring 2007

In this issue:

Public Training Class on Composite UI Application Block and Smart Client Software Factory in Boston on July 10-13

Feature Article: An Event Visualizer for CAB

New Book from  David Platt: Why Software Sucks (and What You can Do About It)

ANOTHER New Book from  David Platt: Programming CAB and SCSF from Microsoft Press

Blatant Self-Promotion: New  in-house class on Composite UI Application Block and SCSF

Annabelle and Lucy's Latest

Subscription Information

 


Feature Article: An Event Visualizer for CAB

The last three articles in this newsletter have dealt with the Composite UI Application Block and its Smart Client Software Factory. I've been teaching so much in that arena lately that I'm going to continue the trend in this article, discussing a problem that crops up in essentially every class that I teach on the topic, that of visualizing the internals of the CAB framework during the development process.

The CAB Event Broker service is a very popular object. Programmers use its loosely-coupled publish and subscribe event system for many purposes, from setting the status bar label text to specifying the order in which the shared user interface is modified. When I debug a CAB program and an event doesn't seem to be doing what it's supposed to do, the first thing I do is to check to see if it's getting fired or not, because sometimes it isn't. Checking this is sometimes difficult, depending on where the firing code lives. So I figured I'd write an event spy program, as I once did for the COM+ system back in 1999. (see this link here).

To host my spy programs visual elements and to connect it to the CAB framework, I decided to use the CAB Visualizer mechanism. Perhaps you've seen the WorkItem sample visualizer, which shows you all the WorkItems in the system, thus:

This visualizer shows you all of the WorkItems' collections, including the event topics, but it doesn't show you when an event gets fired. That's what I decided to write. Here's what it looks like. The event topics are show in the left-hand list box. When an event gets fired, the time, the event name, the thread from which it is fired, and the data that it passes are shown in the right-hand list box.  I was surprised how easy this was to write, which I hope will inspire you to write other CAB visualizers. I've placed the code online, you can download at by clicking on this link.

A visualizer is, first and foremost, a control, so I started by deriving from UserControl. When the shell application creates its visualizers, it looks in its config file (see later in this article) for the list of them and creates one of each class that it finds. Since the control is being created by the CAB framework, we can request dependency injection in the same manner as any other CAB objects. In this case, my injection constructor requests the IVisualizer interface, which contains references to application's root work item and the CAB object builder, and the visualizer's own WorkItem. 

Since the visualizer is a control, we have to show it in a workspace. The visualizer's own WorkItem  provides a workspace called "MainWorkspace", which is of class TabWorkspace. It's not on the application's root WorkItem, so you can't see it there, and the WorkItem visualizer doesn't display its own WorkItem, so you can't see it there either. But it does exist, for the express purpose of holding visualizer resources. In this sample, we find the workspace by means of its name, and place our control into it.

I want to display all events that get fired in the CAB application. To do this, I need to add a subscription to each event. To be notified when a new EventTopic  object is added to the root WorkItem, I set up a handler on the EventTopics collection, for the .NET tightly-coupled event named Added.  The root WorkItem is on the IVisualizer interface that I was passed in the injection constructor.  This handler gets called every time an EventTopic is added to the root WorkItem's collection. Extending this to child WorkItems is left as an exercise to the student.  Thus:

public partial class EventVisualizerControl1 : UserControl
{

    IVisualizer visualizer;

    [InjectionConstructor]
   
public EventVisualizerControl1(IVisualizer visualizer, WorkItem workItem): this()
    {

        // Retain injected parameter for future use

                 this.visualizer = visualizer;
 

        // Create lists for holding event catchers

        CatcherList = new List<EventCallCatcher>();

                  // Show our control in the workspace provided for visualizers

        workItem.Workspaces["MainWorkspace"].Show(
           
this, new SmartPartInfo("Events", String
.Empty));

                  // Hook the added and removed events of the EventTopics collection
        // of the CAB root WorkItem

        visualizer.CabRootWorkItem.EventTopics.Added +=
           
new EventHandler<DataEventArgs<EventTopic>>(EventTopicAddedHandler);

    }

    ... rest of the class

}

When an EventTopic gets added to the root WorkItem's collection, it fires the .NET tightly-coupled event named Added, which I catch it in the handler function shown below. I fetch the event topic parameter from the EventArgs parameter and place its name in the first list box for the user to see. Now I want to subscribe to the CAB event so that I can notify the user when it gets fired. The CAB event doesn't send any identifying parameters, such as its name, that its handler function can use to identify it.  In order to differentiate the firing of one event from that of another, I have to create a separate listener object for each event. I created the class EventCallCatcher for this purpose, which accepts the event name. I have to maintain a list of these because the CAB event broker system does not maintain a strong reference that would keep the subscriber object alive. Thus:

public void EventTopicAddedHandler(object sender, DataEventArgs<EventTopic> e)
{

    // Fetch the event topic out of the EventArgs

        EventTopic et = e.Data;   

    // Add name to first list box

    this.listBox1.Items.Add(et.Name);

    // Create a new EventCallCatcher to respond to this particular CAB event

    EventCallCatcher ecc = new EventCallCatcher(et.Name, this.listBox2);
   

    // Add it to my catcher list so as to maintain a reference to it,
    // thereby keeping it from becoming garbage.

    CatcherList.Add(ecc);


   // Subscribe the CallCatcher to the CAB event.

    et.AddSubscription(ecc, "CatchEvent", visualizer.CabRootWorkItem,
    
ThreadOption
.UserInterface);

}

The EventCallCatcher class is shown below. It remembers its name and the list box in which it is to display its results in its constructor. When the call comes in, I check the EventArgs property to see if it has a property called Data, which will be the case if it's an generic EventArgs<> object. It not, I call ToString on the EventArgs itself. If so, I get the Data object and call ToString on it. That's how I get the event's data to display. Finally, I assemble a string to put into the list box: the time the event is fired, the name of the event, the thread from which it is fired, and the data that it contains. Thus:

public class EventCallCatcher
{

    string Name;
    ListBox lb;

    public EventCallCatcher(string name, ListBox lb)
    {
        Name = name;
        this.lb = lb;
    }

    public void CatchEvent (object sender, EventArgs e)
    {
        string data ;

        // Get type of event args

        Type t = e.GetType();|
        PropertyInfo pi = t.GetProperty("Data");

        if (pi == null)
        {
            data = e.ToString();
        }
       
else
       
{
            object o = pi.GetValue (e, null) ;
            data = o.ToString();
        }

        lb.Items.Add (DateTime.Now.ToLongTimeString() + ": " + Name + ", from Thread " +
        System.Threading.Thread.CurrentThread.ManagedThreadId + ", Data: " + data);

    }

}

Finally, I have to tell CAB to use my visualizer in addition to the WorkItem visualizer. I do this by making entries in the App.config file, thus:

<visualizer>
    <
add type="EventVisualizer.EventVisualizerControl1, EventVisualizer" />|
    <
add type="SampleVisualizations.WorkItemVisualization, SampleVisualizations" />
</
visualizer>

Now you've learned something about the visualizer system and the event broker system too. If you'd like to learn more about CAB and SCSF, I'm teaching a public class on it in Waltham MA on July 10-13, 2007. Or I can teach it in-house at your company, which you'd probably find cost-effective if you had five or more attendees. Information on both is online at this link,

Until next time,  as Red Green  would say, "Keep your stick on the ice."


Another New Book from David S Platt

Programming CAB and SCSF

ISBN 0-735-62414-3

Release Date July 26, 2007

Click here to Preorder from Amazon.com

 

To complement my course offerings in CAB and SCSF, I've compiled my notes and sample code into a book, published by Microsoft Press. Get hands-on guidance for developing smart client applications using Windows Forms with the Composite UI Application Block (CAB) and the Smart Client Software Factory.  This book details a simple, approachable method for building these applications. With just your fundamental Visual Basic or Visual C# skills, this guide will help you understand the prefabricated classes of CAB and the proven patterns that the Smart Client Software Factory provides. This book offers classroom-tested guidance, hands-on instruction, and a proven building-block approach. Through eight modular lessons, developers of moderate experience with learn how to create functional, robust smart client applications.

Chapter List:


  1. Introduction     
 
  5. Shared User Interface

  2. Shell and Services
 
  6. Events

  3. WorkItems
 
  7. Action Catalog Service


  4. Workspaces and Views
 

  8. Using CAB and SCSF with WPF

             


New Book from David S Platt

Why Software Sucks (and What You Can Do About It)

ISBN 0-321-46675-6

Sample Chapter Online at www.whysoftwaresucks.com

       

It's finally out! 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.

It's gotten a storm of publicity, primarily from a Reuters wire service article that ran during the first week of the new year. It was picked up in the electronic editions of such publications as the such as the New York Times (http://www.nytimes.com/reuters/technology/tech-software-platt.html) , Fox News, (http://www.foxnews.com/story/0,2933,241578,00.html), and PC Magazine (http://www.pcmag.com/article2/0,1759,2078820,00.asp).

I've started a new blog based on it, at www.suckbusters.com . It's dedicated to the notion that software shouldn't suck. Instead, software should Just Work.

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.


Blatant Self Promotion: Would you buy a used car from this guy?

 

4-day In-House Training Class on Composite UI Application Block. Available In-House, or to the Public in Waltham MA,  July 10-13

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. 


 Annabelle And Lucy's Latest

And now, the moment for which I know you've all been waiting -- the pictures of my two girls. Lucy is now almost 4 1/2. She loves her preschool at Cape Ann Waldorf School, actually RUNS onto the playground when we drop her off. Annabelle is almost 7. Who'd-a thunk it? I told Annabelle that she can't be almost 7 because we just brought her home from the hospital about 5 minutes ago. She said, "No Daddy, your parents just brought you home from the hospital an hour ago." I told her, "Well, the next time Grandma comes to visit, you ask her about that, and she'll probably agree with you.

Here Annabelle cuddles with our new kitten that the girls named Starlight, a brother for the big one you saw in the last issue. They're half brothers, a year apart, and are already best buddies.

    

Here the girls show off the birthday cake they made for me:

 

And here's Lucy with both cats:


Subscription Information

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.