Foundational Modules and Names as Constants (Intro to CAB/SCSF Part 21)

Introduction

Part 19 and part 20 of this series of articles looked at business modules in the Smart Client Software Factory.

This article looks at foundational modules briefly, and also discusses the pattern for handling names in the SCSF.

Foundational Modules

In part 18 of this series of articles we saw how we can use one of the Guidance Automation Packages to add a business module to our solution. There’s also a Guidance Automation package that lets us add a ‘foundational module’ to our solution. This is on the same submenu as the ‘Add Business Module (C#)’ option we saw above. So to add a foundational module to our solution right-click the solution folder in Solution Explorer, select Smart Client Factory/Add Foundational Module (C#) and then click through the two setup screens.

A foundational module is identical to a business module except that it does not have a root WorkItem. This is because it is intended to contain supporting functionality rather than core business functionality for our solution. It is not expected that we will create business objects and add them to the various WorkItem collections.

So we are expected to create fairly generic services and supporting code in foundational modules, rather than business code. Of course we could do this in the Infrastructure projects mentioned in part 18, but a foundational module allows us to separate out supporting code into its own CAB module.

Note that we can create an interface component, ‘Module.Interface’, for our foundational module in exactly the same way as for a business module. This allows other components in the solution to use the module’s functionality without referencing it directly, as described above.

Constants Folders

In our examples above we have seen several Constants folders being set up. The main Smart Client solution has a Constants folder in both the Infrastructure.Interface component and the Shell component. Both the foundational modules and the business modules have Constants folders in both their main Module components and their Module.Interface components.

The Constants folders all contain four classes: CommandNames, EventTopicNames, UIExtensionSiteNames, and WorkspaceNames. In the Constants folders mentioned above most of these are empty by default, although Infrastructure.Interface has some constants set up in its classes.

The important thing to notice here is that the individual classes with the same name are arranged in an inheritance hierarchy. So if we have a business module in our Smart Client solution (as in the code example we have already seen) then CommandNames in the Module itself inherits from CommandNames in Module.Interface, which in turn inherits from CommandNames in Infrastructure.Interface. CommandNames in Shell also inherits from Infrastructure.Interface.

The reason these classes exist is to allow us to use standard constants throughout our solution for names, rather than having to use strings. The inheritance hierarchy lets us define these constants at the correct level in the hierarchy, but then to use any of them very simply by just accessing the class at the level the code is at.

The reason we don’t want to use strings in our code as names is they are prone to error in entry (since we can’t use intellisense) and can’t be checked by the compiler at compile-time: if we enter a string name wrongly we will get a run-time error. If we use constants to represent these strings we avoid both of these problems.

This will be clearer in an example:

We might call a Workspace on our Shell form “LeftWorkspace” when we add it to the Workspaces collection of the root WorkItem. Elsewhere in the code we may want to retrieve that workspace and interact with it, for example to call the Workspace’s Show method to display a SmartPart. Normally to do this the syntax would be, for example:

_rootWorkItem.Workspaces["LeftWorkspace"].Show(control);

The obvious difficulty with this is that we are just entering the name “LeftWorkspace” as a string, which is prone to error and the compiler can’t check.

So we add the code below to the WorkspaceNames class in Infrastructure.Interface. We add it to the Infrastructure.Interface component because the Workspace is being defined in the Infrastructure part of the solution, but we want it to be available outside of that:

public const string LeftWorkspace = "LeftWorkspace";

Now suppose we want to use this Workspace name in code in a business module. The WorkspaceNames class in the business module inherits from the WorkspaceNames class in Infrastructure.Interface, and hence the constant is available in that class. All we need do is reference that class to access any Workspace name. So we just import the appropriate namespace:

using SmartClientDevelopmentSolution.Module1.Constants;

And then we can do:

_rootWorkItem.Workspaces[WorkspaceNames.LeftWorkspace].Show(control);

Now intellisense is available when we enter the ‘LeftWorkspace’ name, and the compiler can check that what we have entered is correct.

Note that if we have a Workspace name defined just for the module (say ‘LocalWorkspace’) we can still just do WorkspaceNames.LocalWorkspace to access it.

So these Constants folders provide us with an easy way of using named constants for items in the WorkItem hierarchy throughout our code.

7 thoughts on “Foundational Modules and Names as Constants (Intro to CAB/SCSF Part 21)

  1. Hi Rich,
    i have been religiously following your articles on SCSF.These all articles are worth their weight in gold.Hope you will keep writing about “Smart Clients”.

  2. Hi Rich,

    the only problem with this solution is that if you are typing code and you are using the code completion a lot (e.g. adding using clauses!) you will end up with compiler class resolution conflicts (same class name found in two namesaces) because the class names are equal…

    so here you have to be very attentive 😉

  3. Holy Cow! I have scowered Amazon, Barnes & Noble, the CodeProject website… everywhere. Nowhere does anyone do as well a job as breaking down the complexities (imagined) and creating a comprehensive road-map that any seasoned developer can follow. By seasoned, I mean developers who started out in old Pascal/Fortran/Cobal, and migrated to the new 3GLs and are now facing yet another paradigm shift. Please, please PLEASE! continue to write such wonderful articles. You should compile these articles into a compendium that could be publish, or posted as a single download (ebook).

  4. Great work,i really appreciate your illustration,in fact it enhance my confidence to adopt CAB/SCSF for Smart Client App.
    Please It would be lovely to have the series compiled to PDF as a sing eBook as mentioned by one of the commentator.

  5. I am very thankful to you, Rich, for this well-led crash course on the topic. I have as little as 8 hours to come up with a tutorial on unit testing CAB-based applications — this material that you have put out here is a real timesaver!

Leave a reply to ola Cancel reply