Thunderclap, the Newsletter of Rolling Thunder Computing

Volume 9, Number 3, Spring 2008

In this issue:

Blatant Self Promotion: Public Training Class on Prism, Taught ONLINE July 8-10  

Feature Article: Introduction to Prism

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

Annabelle and Lucy's Latest

Subscription Information

 


New Online Class on Prism, July 8-10

I'm offering a three-day online instructor-led class on Prism this coming Jul 8-10. It will be the same high-quality class you would get in person, and nobody has to get on a plane. Information is online at www.programprism.com .  If those dates don't work for you, call or email me and we'll discuss in-house classes or additional online deliveries.  


Feature Article: Introduction to Prism

Readers who have followed this space for the last two years have watched the evolution of the Composite UI Application Block (CAB). Launched in January of 2006 by the Patterns and Practices group, extended with the Smart Client Software Factory in July of 2006, and then again in May of 2007, it was a pretty good first cut at a framework for solving the problems of loosely-coupled desktop applications.

Around a year ago, Microsoft’s tools groups started discussing a successor to CAB that would be called Acropolis, which I wrote about here. Microsoft made much of it last summer, starting at Tech Ed in Orlando, then pulled the plug on it around September, for reasons too boring to discuss here. This caused the P&P group to revisit the notion of a successor to CAB, which they initially called the  WPF Composite Client. This evolved into a platform called Prism, design kickoff for which took place in January of 2008. (There may or may not be a name change at release.)

Now the first release of Prism is just about ready to go. End of June is what I'm hearing now, before the end of Microsoft's FY. The code is on Codeplex at http://www.codeplex.com/prism . The next drop is meant to test the documentation, that’s how close they’re getting to release. So I thought I’d start giving you a first look at what it’s going to have and what’s in it for you. If the prospect intrigues you and you’d like to learn more, I’m offering a three-day online class on July 8 – 10. Information is online at www.programprism.com

The main design goal for Prism was to take what the P&P community had learned about composite applications from CAB/SCSF, and apply it in today’s development environment. To use more interfaces and less inheritance. To make it easier to test using automated tools. To remove the parts of CAB that nobody ever used and that only got in the way. To remove support for legacies such as Windows Forms, thus making it cleaner.

P&P didn’t set out to write CAB 2.0, and CAB code won’t work on Prism without a port. But the problems of loose coupling haven’t changed, and therefore the architectural principles of their solutions haven’t changed all that much either. The internal implementation of these principles has indeed changed. A framework architect would call these changes drastic – “look, we stopped using inheritance, we’re all about implementing interfaces now.” An application programmer who uses the framework would probably call these changes minor – “same ‘:’ operator on my class for inheritance as for implementation, same ‘.’ operator to access a method.” Etc. If you understood the principles, not just the syntax, of CAB; if you understood not just what you were doing but WHY you were doing this instead of that (as all graduates of my training classes do), you will find Prism quite familiar. Here is my first cut at what an application programmer or architect needs to know about Prism.

A CAB application required you to derive a class from CabApplication, often through several layers of intermediary. This base class contained the rather intricate startup code for the CAB framework. A Prism application accesses its framework via composition, not inheritance, thereby allowing it to work with many different types of containers, and making it easier to test. The sample code I’m about to show you comes from the UIComposition sample in the Prism download.  But as you’ll see, the framework doesn’t depend on any particular contains. You could put it in Silverlight, for example, without changing the code very much.

The sample program project is shown in following screen shot:

The App and Shell classes are the WPF program’s application and main window classes, respectively. Instead of deriving from a Prism base class, you instantiate and contain the Prism framework objects instead. That’s what the Bootstrapper class is for.  You modify the App code to include it, thus:

public partial class App : Application
{
   
public App()
    {

        // Instantiate our own class that will start
        // up the Prism framework, and call its
        // initialization method

        Bootstrapper bootStrapper = new Bootstrapper();
        bootStrapper.Initialize();

    }
}

 

When you start looking at this Bootstrapper class, you see the following startup code. This article will discuss the first and the last of the auxiliary methods inside the Initialize () method.

internal class Bootstrapper : IDisposable
{

    private IUnityContainer container;

    public void Initialize()
    {

        this.InitializeContainer();

        this.RegisterRegions();

        this.InitializeShell();

        this.InitializeModules();

    }

}

 

Anyone who’s worked with CAB recalls, probably not fondly, the WorkItem chain. It was originally intended both as a scoping container (think of the various collections, such as Services and Events)  and also as a container for business logic (the Active/Deactivate methods and their associated events, for example). The former worked fairly well, the latter confused a lot of people.  

Prism uses the same concept of a chain of universal scoping containers, without any of the business logic. Prism implements this concept via the P&P Unity Application Block (online at http://msdn.microsoft.com/en-us/library/cc468366.aspx), more or less as CAB used EntLib’s Object Builder Block. As we will see in this and later articles, the UnityContainer stitches together and provides access to the services, display regions, modules, commands, and events.  The shell application creates an instance of the UnityContainer, usually in the Bootstrapper class. Here’s the startup code so you can see it happening:

 

private void InitializeContainer()
{

   // Instantiate the Prism-provided UnityContainer class

   this.container = new UnityContainer();

   // Register the UnityContainer with itself

   this.container.RegisterInstance<IUnityContainer>(this.container);

   // Place a reference to the UnityContainer into a static
   // class from which it can be accessed by anyone in this .exe

   PrismContainerProvider.Provider = new UnityPrismContainer(this.container);

}

Once we have the UnityContainer, we use it to register Regions, which are visual frames that can contain views. Regions are roughly analogous to Workspaces in CAB, and views in Prism and roughly analogous to views in CAB. Registering the regions with the UnityContainer is roughly analogous to the CAB framework recognizing the existence of workspaces and placing them into the WorkItem chain’s Workspaces collection. The RegisterRegions and InitializeShell helper methods shown in the Bootstrapper class are logistically convenient places to put this code. The whole notion of regions and views can get complex, so I’ll save its discussion for a future newsletter.

Prism uses the concept of modules, separate assemblies to which the shell is more-or-less loosely coupled.  You can see the EmployeeModule and ProjectModule in the project screen shot shown previously. CAB's default implementation required you to use a module enumerator service to figure out the list of modules to be loaded into an application, and then to use the module loader service to load those modules and perform CAB framework processing on them (i.e. scan them for CAB-related objects and place those objects into the WorkItem chain, and perform dependency injection at the module’s request.) One of the main complaints about CAB was that it was hard to ignore its complexity if you didn’t want a particular feature. (Bypassing the automatic load and loading modules manually actually was pretty easy to do, but hard to figure out how to do.) It is a fairly common case among the developer community that they don’t care about dynamically determining different sets of modules at runtime. It’s universally handy to separate the program into modules to be developed and maintained by different teams, but having an application automatically configure itself, based on the user’s identity, to be a customer service agent app or a supervisor app is a feature that some developers want and others don’t want.

The simplest module loading case in Prism is to manually load the modules through the UnityContainer. In this case, the shell knows which modules it wants to load. (I call this the “somewhat-loosely-coupled case”.) The shell has references to the assemblies in which these modules live. The InitializeModules method loads each module by calling the UnityContainer’s Resolve method, which you will see a great deal of in Prism programming. Basically it means, “Go get me this thing, following the rules based on its class.” In the case of a module, it means to load the assembly into the  application’s address space, perform dependency injection on the new module (of which more anon), and return a reference to that module. The code looks like this:

// This program doesn't use an enumerator to
// figure out which modules to load. We know it
// at compile time. I call this "slightly
// tighter" coupling

private void InitializeModules()
{

    // The Resolve method instantiates an object
    // of the class that represents a module.
    // The Initialize method invokes the
   
// module’s initialization code

     IModule employeeModule = this.container.Resolve<EmployeeModule>();
     employeeModule.Initialize();

     IModule projectModule = this.container.Resolve<ProjectModule>();
     projectModule.Initialize();

}

 

Now, suppose you don’t want that somewhat-more-tightly-coupled behavior. Suppose you want the module load list to be fetched from a config file (default CAB behavior), or from some other service (replacement ModuleEnumeratorService in CAB). How would you do that in Prism?

It turns out to be relatively easy, but you do have to think a little. Prism contains two enumerator classes that can provide this behavior, each of which implements the IModuleEnumerator interface.  The ConfigurationModuleEnumerator class reads the module list from a config file, similar to the default behavior in CAB. The DirectoryLookupModuleEnumerator class infers the module load list by examining a specified folder on the disk.

Unlike CAB, Prism does not register a default module loader or module enumerator service. It provides classes that implement this functionality, but it doesn’t place them into the application. It’s up to you to do that if you want to. If, for example, you wanted the default CAB behavior of reading the module load list from a config file, you would write code similar to the following. In your Bootstrap class, you would place a utility method such as RegisterGlobalServices, which you would call from your Boostrap.Initialize. The method would contain code that registers the module loader and enumerator services, perhaps like this:

private void RegisterGlobalServices()
{

    // Register Prism's default module loader service
    // with the unity container as a singleton object

     container.RegisterType<IModuleLoaderService, ModuleLoaderService>(
       
new ContainerControlledLifetimeManager());

 

    // Register a new instance of the Prism module enumerator
    // service that reads its data from a config file.

    ConfigurationStore store = new ConfigurationStore();

    container.RegisterInstance<IModuleEnumerator>(new ConfigurationModuleEnumerator(store));

 }

 The UnityContainer requires somewhat non-intuitive parameters, but it was written by framework architects for framework architects, so what do you expect? Here’s what they mean. The method RegisterType means that when someone first queries the container for the IModuleLoaderService interface, the container should instantiate an object of class ModuleLoaderService. The ContainterControlledLifetimeManager parameter means that the ModuleLoaderService should be instantiated as a singleton object, and subsequent requests return a reference to that instance. (Why not just “bSingleton = true”? Too easy for application programmers to understand, I guess.) The method RegisterInstance means for the container to take the instance of ConfigurationModuleEnumerator that it’s being passed, hang onto it, and hand out a reference to it whenever anyone asks for the IModuleEnumerator interface – the same singleton behavior as for the module loader, but different syntax, since the enumerator object already exists when it gets passed to the container while the loader does not. We have to instantiate the enumerator first, as we need to pass it a parameter (the configuration store containing its file) in its constructor. It’s a good thing that Prism simplifies the framework, because CAB was really confusing, right?

Having done this, we would write our InitializeModules to fetch the enumerator and loader services from the UnityContainer and then use them, like this:

private void InitializeModules()
{

    // Fetch the module loader and module enumerator services
    // from the UnityContainer

    IModuleEnumerator enumerator = container.Resolve<IModuleEnumerator>();

    IModuleLoaderService loaderService = container.Resolve<IModuleLoaderService>();

 

    // Enumerate and load the modules

    loaderService.Initialize(enumerator.GetStartupLoadedModules());

}

 

For that matter, one can reasonably say, “Hey look, my shell code is the only one touching these services, and it’s only touching them here at initialization time. Why should I bother putting them in my UnityContainer at all? Why don’t I just do this:

private void InitializeModules()
{

    // Instantiate module loader and module enumerator services

    ConfigurationStore store = new ConfigurationStore();

    IModuleEnumerator enumerator = new ConfigurationModuleEnumerator(store);

 

    IModuleLoaderService loaderService = new ModuleLoaderService(
       
PrismContainerProvider.Provider,
       
 container.Resolve<IPrismLogger>());

    // Enumerate and load the modules

    loaderService.Initialize(enumerator.GetStartupLoadedModules());

}

And the answer is, you can, easily, and if you’re stated the usage conditions correctly, there’s no reason why you shouldn’t.

The main drawback to Prism so far is that there aren’t a whole lot of tools like the Smart Client Software Factory had, for generating an application, adding a module, things like this. I’ve protested against that on the Prism advisory group forum (see http://tech.groups.yahoo.com/group/PrismAdvisors/message/2),  but to no avail. Perhaps the community will step up here. Maybe I’ll do a wizard, if I get the time.

To summarize, Prism is the next turn of the screw in the composite application space, and it’s scheduled for release soon (end of June 2008, before the end of Microsoft’s FY, is what I’m hearing today). Developers who are familiar with CAB and SCSF will find its concepts familiar. Porting code from CAB to Prism will be tedious but not difficult. Developers who are new to the concepts of composite applications will find it useful and probably easier to understand and use than CAB/SCSF was.

If the prospect intrigues you and you’d like to learn more, I’m offering a three-day online class on July 8 – 10. Information is online at www.programprism.com

In my next issue of this newsletter, I’ll discuss the service mechanism in Prism, and dependency injection. I hope to see you soon in one of my classes.

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

Click here to order 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.


 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 5 1/2, and Annabelle is just about to turn 8. Whose idea was that, I ask you? Certainly not mine.

Annabelle is reading anything and everything she can get her hands on. She whips through an American Girl Doll book in under a day, so we've stopped buying them for her. We gave her Little Women to try to slow here down, and that took her a couple of weeks. Now she's whizzing through the Wizard of Oz series -- did you know that L. Frank Baum wrote 14 books about Oz, two of which were published after his death? And did you know that Ruth Plumly Thompson then continued the series for another 19 volumes? I didn't. That's what happens when you're the father of a bookworm.

Lucy and Annabelle both learned how to ride two-wheelers this year. It took them about an hour to go from, "Daddy, help me!" to "Daddy, you can't catch me, ha ha!"

Last night they appointed themselves the fashion police and dressed up for their roles, like this:

   

As you can see, Lucy's had her first visit from the tooth fairy. She pulled them both out on the same night. 

Here they are having a tea party for their dolls.

And here they are with their cat Starlight, no longer a kitten


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.