Rich Newman

July 14, 2007

An Introduction to the Smart Client Software Factory and Composite Application Block: Part 1 Modules and Shells

Introduction

Microsoft’s Smart Client Software Factory (SCSF) and associated application blocks are excellent pieces of software. However, for a developer coming to them for the first time they can be extremely daunting. There are many things that can be confusing. Firstly we have modules, workitems, workspaces, and shells, all of which sound similar. Then there’s dependency injection, command patterns, event brokers, model-view-presenter patterns and other high-level concepts, none of which are easy to understand. There’s a load of other concepts as well, multiple example applications, and plenty of documentation. Microsoft’s documentation has a very steep learning curve indeed.

I’m going to write a series of short articles that assume you are a developer coming to this for the first time and are confused as I was. To do this I’m going to focus on one or two basic concepts in each article. There’s quite a lot of blogging about CAB/SCSF on the web, but I couldn’t find anything that gave me a quick, basic introduction with a gentle learning curve. This is what I will try to achieve here.

To start I’m going to look at the basic set up of modules and shells in the Composite Application Block. This is the starting point for most SCSF projects. I’m not going to cover WorkItems until my second article as I found them quite confusing initially.

Requirements

For this example you only need download the code. This contains the CAB dlls it needs to run.

Composite Application Block

The starting point for many developers coming to the Composite Application Block (CAB) is the need to either

1. To design a complex user interface that has some kind of separate components that can be developed and released independently, or
2. To take several existing user interface applications and combine them in such a way that they can continue to be developed independently, but appear in the same window with common menus etc and can interoperate on some level.

This is certainly where I started. The key point in both cases is that if we want our components to be released independently then they can’t have direct references to each other. In short we want ‘applications’ or components that appear in the same user interface (same window) with common menus and some ability to talk to each other, but don’t directly reference each other.

The CAB allows us to do this. It clearly offers us a lot more than just this, but in this article I will show the basics.

Modules and Shells

The first concept you need to understand for this is that of a ‘module’. This is what I am referring to as a ‘application’ or ‘component’ in the paragraph above: a block of code, usually with a user interface that can be displayed in a common window, but which doesn’t reference other modules. In reality these are separate .NET projects within our solution that don’t reference each other.

The second concept is that of the ‘shell’. This is simply the ‘common window’ I’m referring to in the paragraph above. It will contain our modules, or at least the visual parts of them. In reality the shell is usually contained in its own .NET project, but one that doesn’t reference any of the modules, nor is referenced by them.

So, simplistically:

Module = standalone project to be used in a composite user interface
Shell = the host form for the composite user interface

Our Example

Let’s start with a really simple example. Assume we have a C# project that just displays a red form, and another separate project that just displays a blue form. These are going to be our two modules. Then we want a third project to contain a shell, which in this case will just be another form that we want displayed. To keep this example really simple we won’t try to display the red and blue forms actually inside the shell: this will be done in part 2.

The difficult bit is that although all these projects will be in the same solution, none of them will reference each other directly, yet all three forms will display at start up. Obviously we could do this fairly simply with reflection, but we will use the CAB to do it.

Naïve Application Example

The code for this example is available.

To implement the example:

1. We set up three projects (all Windows applications) in a solution. We’ll call these Red, Blue, and Shell. For the Red and Blue projects (which will be our modules) we simply change the BackColor property of the form to red and blue as appropriate.
2. We add references to the CAB dlls (Microsoft.Practices.CompositeUI.dll, .Practices.CompositeUI.WinForms.dll, and Microsoft.Practices.ObjectBuilder.dll) to all three of the projects. We also make sure all three build into the same build directory (via the Properties/Build tab). Shell is the startup project.
3. Now if we run the projects all three will build, but clearly only the form from the Shell project will get displayed, since that is the start up project. We need to tell the other modules to show their forms. To do this we change Program.cs in Shell (our start up code) to inherit from FormShellApplication<,> as below:

 using System;
 using Microsoft.Practices.CompositeUI.WinForms;
 using Microsoft.Practices.CompositeUI;       

 namespace Shell
 {
     public class Program : FormShellApplication<WorkItem, Form1>
     {
         [STAThread]
         static void Main()
         {
             new Program().Run();
         }
     }
 }

The two types passed in to FormShellApplication<,> both get instantiated when Program is instantiated and .Run() is called (this calls into the base classes clearly). Form1 is our shell form and gets displayed, WorkItem I will discuss in part 2. After this change the application will still only display the MDI form, but the .Run() call will enable us to show the other two screens with some other simple changes.

4. In fact the application is now looking for an XML file telling it what other modules to load. Again this happens as a result of the call to .Run(). The XML file has to be called ProfileCatalog.xml, has to be copied always into the output directory, and has to look like the XML below:

<?xml version="1.0" encoding="utf-8" ?>
<SolutionProfile xmlns="http://schemas.microsoft.com/pag/cab-profile">
  <Modules>
    <ModuleInfo AssemblyFile="Red.exe" />
    <ModuleInfo AssemblyFile="Blue.exe" />
  </Modules>
</SolutionProfile>

We add this file to the Shell project. Now if you get the names of the modules wrong and then run the application it will throw an exception, showing that it’s trying to find the relevant files.

5. Finally we need something in the Red and Blue projects that will actually run as a result of this (the CAB doesn’t just call the usual start up code). We can do this by adding a class that inherits from Microsoft.Practices.CompositeUI.ModuleInit and overrides its Load() method. The CAB code will call this Load method from the .Run() call above:

using Microsoft.Practices.CompositeUI;
namespace Blue
{
    public class BlueModuleInit : ModuleInit
    {
        public override void Load()
        {
            base.Load();
            Form1 form = new Form1();
            form.Show();
        }
    }
}

That’s it: if we put the code above in the Blue project, and the equivalent in the Red project, the three forms will now load and we have our first composite application. None of the three separate projects has a direct reference to any other.

Summary

The difficult thing to understand when you see this for the first time is that the CAB is doing a lot of work for us when we call that .Run() method on a FormShellApplication class. It’s instantiating and showing our Form1 (our shell). It’s checking for an XML file called ProfileCatalog.xml. If it finds ProfileCatalog.xml, it is loading the assemblies it finds listed in there. It’s then looking for any ModuleInit classes in them, and calling .Load if it finds them. None of that’s too complicated, but it can feel a bit like smoke and mirrors are being used.

This article is continued in part 2, where I explain WorkItems, and part 3 where I will explain dependency injection, and show how we can get the two forms in the Red and Blue projects in our example to be MDI children in the shell.

 
i
 
13 Votes

Quantcast


Be the first to like this post.

54 Comments »

  1. The zip file seems to be corrupted. Thanks doe the nice article to start off …

    Comment by Aneel — August 14, 2007 @ 6:53 pm

  2. the zip file is corrupted.

    Comment by divya — August 17, 2007 @ 7:43 am

  3. Zip file is corrupted. Kindly upload a new one..
    Article is very good for a start

    Comment by Ratheesh — August 22, 2007 @ 8:18 am

  4. I’ve reposted the zip file, it should be fine now.

    Comment by richnewman — August 22, 2007 @ 11:03 pm

  5. The article was really useful.
    Thanks..

    Comment by Uma — August 27, 2007 @ 3:41 am

  6. A very well written article..

    Comment by Kumaresan — August 30, 2007 @ 3:00 pm

  7. Your article was very useful. Thanks for your work!

    Comment by Jozsef Csaba Juhasz — September 12, 2007 @ 12:32 pm

  8. Thanks for the article, nice to have a dead simple primer when you’re new to something.

    Comment by Jon — September 13, 2007 @ 12:21 pm

  9. The article was helpful. Thanks for the efforts.

    Comment by Jayant — September 17, 2007 @ 9:27 am

  10. Thank you for explaining complex technology clear with simple example.

    Comment by hong — September 20, 2007 @ 5:15 am

  11. Simple superb article. THANKS A TON for making things easier !!!

    Comment by Om Bajpai — October 19, 2007 @ 7:52 am

  12. Thank you for your help. I’ve read a lot of info and could not start. Now I can! Would you be so kind to provide VB.NET code in parallel? Thanks again.

    Comment by Edouard Tomberg — October 22, 2007 @ 9:02 pm

  13. My dev team thanks you! After being immersed in the blogs, docs, HOL etc for the past week this is like a breath of fresh air!

    Comment by John Pether — October 24, 2007 @ 6:57 am

  14. Hurray. At last a clear understandable CAB/SCSF article. Many thanks.

    Comment by Ed — October 26, 2007 @ 5:56 pm

  15. Rich,
    Great article! We have been exploring the CAB and SCSF for a few months, but now it appears that both are being put out to pasture by Microsoft. What are your thoughts? Should we (or anyone else for that matter) invest any more energy in CAB/SCSF?

    Greg Bayer

    Comment by Greg Bayer — October 31, 2007 @ 5:19 pm

  16. Was really glad to find your article on the CAB – I have struggled with it for some time now. Eagerly, I tried your example coding it into a VS solution – it compiles ok but only shows the shell form! I downloaded your code, loaded it into VS and it runs fine! I’ve compared every line of code in every class and they look identical but mine still only shows the shell window. Also, tried deliberately changing one of the assembly names in the ProfileCatalog.xml file but it doesn’t throw an exception. Any ideas where I should look?

    Comment by John Smith — November 1, 2007 @ 2:26 pm

  17. Hi Rich,
    Managed to sort it out myself. Forgot this part “The XML file has to be called ProfileCatalog.xml, has to be copied always into the output directory” – I had the file in the VS Shell project but didn’t copy it to the output directory (the bindebug directory in my case). The light dawns :-)

    Comment by John Smith — November 2, 2007 @ 2:11 pm

    • John – Copying the ProfileCatalog.xml file to the Output directory was the exact same issue that I ran into. I was fumbling around for the last couple of hours trying to figure it out. Thanks for posting the solution. :)

      Comment by Shawn White — July 9, 2010 @ 4:30 pm

  18. Greg

    I posted some thoughts on your question

    http://richnewman.wordpress.com/2007/11/04/composite-application-block-or-wpf-composite-client/

    Rich

    Comment by richnewman — November 5, 2007 @ 12:27 am

  19. Hey Rich,

    I was really looking for such an article which can take me from the ground zeor level for CAB, and you have written such a SIMPLE and WONDERFUL article that i can grasp CAB concept very easily and can start development on it fairly quickly. Thanks alot for such an excellent article.

    ATHER

    Comment by Ather Ali — November 26, 2007 @ 6:33 pm

  20. very very nice article. After reading your articles I got a clear idea about SCSF.

    Comment by Prakash — December 31, 2007 @ 8:44 am

  21. Nice job, simple and to the point – exactly how it should be – thank you!

    Comment by jpratt — February 5, 2008 @ 6:39 pm

  22. Getting the following Error :

    Could not load type ‘Microsoft.Practices.CompositeUI.WinForms.WindowsFormsApplication`2′ from assembly ‘Microsoft.Practices.CompositeUI.WinForms, Version=1.0.51205.0, Culture=neutral, PublicKeyToken=null’.

    When i try to add a 3rd project as yellow and try to launch all the four forms……please help me in this.

    Comment by S.UMA — February 13, 2008 @ 12:27 pm

  23. article was really very good.

    Comment by S.UMA — February 13, 2008 @ 12:27 pm

  24. really a nice article for beginners

    Comment by Mohsin — March 28, 2008 @ 6:01 am

  25. Regarding comment 22.

    S.UMA it seems like you’ve solved the problem: Could not load type ‘Microsoft.Practices.CompositeUI.WinForms.WindowsFormsApplication`2′ from assembly ‘Microsoft.Practices.CompositeUI.WinForms, Version=1.0.51205.0, Culture=neutral, PublicKeyToken=null’.

    Can you post solution?

    Comment by Andrey — April 1, 2008 @ 2:38 pm

  26. Andrey

    I found the same error and corrected the same. The error is due to mismatch of the version of the 3 DLL
    -Microsoft.Practices.CompositeUI.dll
    -Microsoft.Practices.CompositeUI.WinForms.dll
    -Microsoft.Practices.ObjectBuilder.dll

    When adding reference to the above 3 in the new project make sure you pick the DLL’s up from CABPart1Resources and the error will vanish.

    Alternatively (this is what I did) you can also point to the ‘C:Program FilesMicrosoft Smart Client FactoryLib’ location for all projects ( 3 from Rich and the new ones)

    Comment by Siddhartha — April 16, 2008 @ 6:51 am

  27. Exactly what I was looking for.
    Thanks

    Comment by Ariel — August 7, 2008 @ 11:10 am

  28. Thanks for this simple, yet very effective lesson on CAB.

    Comment by Edgardo — August 8, 2008 @ 6:05 am

  29. Nice one for start up Reader of SmartClient and CAB.

    Comment by PompanaGouda — August 12, 2008 @ 2:16 pm

  30. Does the associated code only work with VS 2005? (I want to use VS 2008 for my SCSF project.)

    Comment by Rod — August 19, 2008 @ 10:44 pm

  31. nice article,when we made new exe like Yellow.the form is not show.i wrote the code in xml.how solve my problem

    Comment by samiksha — September 19, 2008 @ 6:34 am

  32. Very good explanation.
    I followed the same steps and the build succeeded but I get the message ModuleEnumeratorException unhandled. Any idea?

    Comment by Vaishnavi — September 22, 2008 @ 1:26 pm

  33. Thanks for this post finally I really got the point of CAB, after reading tons of bla bla bla on MSDN i as not able to speed up with CAb yet

    Comment by Jaime Calahorrano — September 30, 2008 @ 3:43 pm

  34. I am a first time user of CAB. This post really helps me understand the basic without wasting time.

    Comment by Josh — November 25, 2008 @ 6:07 am

  35. Excellent intro to CAB. Tired of reading lots of blah blah , this one was short and gets right to the point. Excellent !!!

    Comment by Kodez — January 10, 2009 @ 3:01 am

  36. nice intro to cab. I like this. i will be expecting for more great tuts from you. :) thanks!

    Comment by Eldon — March 2, 2009 @ 6:29 am

  37. thank you for excellent intro to CAB.

    Comment by filip — March 7, 2009 @ 9:53 pm

  38. Thanks, this is very good stuff.

    Comment by SomRad — June 3, 2009 @ 8:13 pm

  39. Thanks, this is a good article
    but when i debugging a solution it displays me only one Form-Shell.. that is why where are only 3 folders in solution directory: shell, blue, red.. these folders contains only one exe files. There is no bin folder which have to contain three exe and other files of blue red and shell programs..
    How can i slow this prolem??

    Comment by eminach — June 12, 2009 @ 8:42 am

  40. Kudos to RichnewMan.I was also struggling to understand CAB mechanism.This set of articles are one of the best in explaining CAB

    Comment by Rajesh — August 19, 2009 @ 6:17 am

    • A very simple, clear article to start with. After read MSDN for 30 minutes, not sure what they are talking.

      Comment by Clark — August 28, 2009 @ 5:03 am

  41. excellent article. very clear and to the point

    Comment by Allen — November 25, 2009 @ 4:14 pm

  42. Thanks for your time and effort. Well written and helpful.

    Comment by Gord — December 11, 2009 @ 6:26 pm

  43. I must say – this is way better than MS documentation, which gave me nothing but headaches.
    Thanks so much for this!

    Comment by Raihan — January 5, 2010 @ 6:43 pm

  44. I agree with all the other viewers that this is the best article/sample i have found so far on Smart Clinet/CAB. I have been struggling for days. This articles also helps you understand all the files generated automatically in SCSF. Thanks a bunch.

    Comment by Saleha — January 18, 2010 @ 3:52 pm

  45. Its a good article.

    Comment by Srinivas Donavalli — February 4, 2010 @ 6:20 am

  46. Its really a gr8 article, thanks a lot for providing the same

    Comment by Subhash — April 24, 2010 @ 7:44 am

  47. Its nice and understandable. Thanks

    Comment by Maha — June 12, 2010 @ 11:25 am

  48. Its a nice article. I didnot just follow with your code but I have done an application on my own following the steps that were explained in the article. I have the Application with 3 Projects The ShellApp ,2 Others namely : Module1 & Module2. I have added the ProfileCatlog.xml to the ShellApp. I have configured the application so that all the projects output is set to a specific directory but even then I see only ShellForm not others. Any Idea where I am missing out . . . Thanks in advance

    Comment by Shyam — August 5, 2010 @ 6:34 am

  49. Wow! Crystal clear explanation. Awesome. Thanks much!!

    Comment by Anonymous — September 30, 2010 @ 6:32 pm

  50. Maybe you should make changes to the page subject An Introduction to the Smart Client Software Factory and Composite Application Block: Part 1 Modules and Shells Rich Newman to something more better for your content you create. I liked the post withal.

    Comment by Pointer Men's Basketball — October 30, 2010 @ 11:44 am

  51. You made it look so easy … thnx :-)

    Comment by Anonymous — November 1, 2010 @ 9:37 am


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <pre> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Blog at WordPress.com.