Click here to Skip to main content
12,953,379 members (49,422 online)
Click here to Skip to main content
Add your own
alternative version


59 bookmarked
Posted 12 Aug 2009

CAL: Beginners guide to Modular applications: Part 1 of n

, 13 Aug 2009 CPOL
Rate this:
Please Sign up or sign in to vote.
A simpler series to learn the Composite application library


There are a lot of great articles about Composite; as an example, the Calcium articles from Daniel Vaughan, which are great, well documented, well implemented, etc... But, are very complex, and I have seen a lot of people that have dropped the study of this amazing technology because of the complexity of the articles available. Well, this is a bit of a problem, right? Great technologies should make our life easier, not bring so much complexity that we have to spend days and nights to get the point.

Composite has a beautiful purpose, and despite what has been painted about it, it is very simple to understand and to put it to work properly; so now is the time for let the small talk behind and look upon the future of WPF and Silverlight applications.


Since this is a part 1 of n, the content of this article set can vary, but my intension is to follow this sequence:

  1. Creating a basic Composite WPF application (this article)
  2. Commands in CAL (fancy name yet to be announced)
  3. Creating custom region adapters (fancy name yet to be announced)
  4. Log strategies (fancy name yet to be announced)
  5. Multiple developer teams, single solution (fancy name yet to be announced)
  6. Considerations of benefit-cost ratio of a CAL application for an enterprise (fancy name yet to be announced)

With this, I think we will cover the basics that will allow us to understand better the marvelous implementations of the complex articles available.


Obviously, we have one thing we need to get, the Composite Application Library. Here is the Composite website.

After the installation of the Composite Application Guidance pack, I strongly recommend you to read the documentation; I know it is enormous, but worthy sometime of study.


Starting up, you have the CAL downloaded and have built it, time to start playing with your newest toy. So let's begin with the basics.


CALient.Core is the core of our application, it’s the heart and soul of it, is a WPF application that will be the center of our CAL universe.

Let's create our solution. In my opinion, the best way of creating a Composite solution is to create a Visual Studio blank solution. Why? Because you can, and will, organize your solution in solution folders; this way, it becomes simpler to know where everything is on your solution.


As shown in the above image, select from your "Other Project Types", the "Visual Studio Solutions", and choose the "Blank Solution". This will give you, literally, a blank solution as shown below:


Now, inside the solution, create a solution folder called Client; inside of this folder, you will create a new project, a WPF Application Project, and will call it CAL.Core.

Now is the time for some personal preferences, such as the core of the application. I think the core of an application isn't meant to be a program/executable, but a library, so you right click and open the properties of the project, and the following screen will open for you:


On this tab, simply change the output type of your project to a class library. Now, simply delete your window1.xaml and your App.xaml, you won’t need them.

Now, we will add to the project the name of the Regions we will register our modules, like:

namespace CALient.Core
    public class RegionMapping
        public static string REGION_Content = "Region_Content",
            REGION_Menu = "Region_Menus";

Inside this project, create a folder called DesktopShell, and inside of it, you add a Window called Shell.xaml.

Then, you add the references for the Composite Application Library, and in Shell.xaml, you add the following lines:







    Title="Shell" Height="300" Width="300">

           CAL:RegionManager.RegionName="{x:Static CALient:RegionMapping.REGION_Menu}" 


           CAL:RegionManager.RegionName="{x:Static CALient:RegionMapping.REGION_Content}"/>

The Desktop shell is ready for the scope of this article... pretty simple, right? No secrets there.

Now for the application to work, we will need something called a Bootstrapper. This will extend from the UnityBootstrapper in the Composite Application Library, so let’s do that now:

class Bootstrapper : UnityBootstrapper
    protected override System.Windows.DependencyObject CreateShell()
        var shell = new Shell();
        return shell;

    protected override 
         Microsoft.Practices.Composite.Modularity.IModuleCatalog GetModuleCatalog()
        // To be simpler to understand we use here
        // just a Directory Module Catalog that will search
        // for available modules in a certain directory,
        // in this case our application root directory
        var modules = new DirectoryModuleCatalog() { ModulePath = @"./" };

        return modules;

Now, we create a class to start up everything like this:

public class ApplicationStarter
    public static void Run()
        Bootstrapper b = new Bootstrapper();

Great. Core set up and ready to go.

Now, let’s create an application to start that up.

Create another project inside the Client Solution folder, call it CALient, remove Window1.xaml and remove StartupURI="Window1.XAML" in App.xaml. Add the reference to the CALient.Core and now go to App.xaml.cs and add the following line in the CTOR method:

public App()

Run it... and bam! A blank window =D, all this for a blank window... yep, now is the time to build the interesting part, the Modules.

How do I anyway?????

We will do the following. Let’s add a project for the modules, inside a new solution folder called Modules. In this Module, just add a WPF UserControl Library and call it any name you like; in this project, it is called CALient.One.

Then, you will delete UserControl1.xaml and add a class to this newly created assembly, call it with [name]Module, and you will have the following:

Open the file and add the following code snippet:

[Module(ModuleName = "Module One")]
public class OneModule : IModule
    IRegionManager regionManager;

    public OneModule(IRegionManager regionManager)
        this.regionManager = regionManager;

    public void Initialize()
        regionManager.RegisterViewWithRegion(RegionMapping.REGION_Menu, typeof(MenuView));

This module will be composed of three Views and a menu that calls the 3 Views, like this:




So the MenuView will be like:

<UserControl x:Class="CALient.One.MenuView"



    <StackPanel Orientation="Horizontal">
        <Button Margin="10" Width="100" Click="Button1_Click">
                <Image Source="/CALient.One;component/Images/imgOK.png" />
        <Button Margin="10" Width="100" Click="Button2_Click">
                <Image Source="/CALient.One;component/Images/imgCancelar.png" />

In the code behind (since our focus here is to explain this approach and the plan is for using commands only, in the next article, we won't use commands here, but if you like, you can use them just fine =D):

//... removed for clarity ...
UserControl current;

private IRegionManager regionManager;

public MenuView(IRegionManager regionMgr
    regionManager = regionMgr;

private void Button1_Click(object sender, RoutedEventArgs e)
    if(current != null)
    current = new ModuleView1();

private void Button2_Click(object sender, RoutedEventArgs e)
    if (current != null)
    current = new ModuleView2();
//... removed for clarity ...

Another important issue is that once we build the application, the module won't be deployed in the correct position (in the root folder); for that to happen, you will have to add the following line in the Post-build event commandline in the module project:

xcopy "$(TargetDir)*.*" "$(SolutionDir)CALient\bin\$(ConfigurationName)\" /Y

As you have seen, our Views are just static UserControls containing different background colors and different content text.

Run it again

As you can see now, by running the solution again, our solution has been built successfully, and that by clicking the buttons on our MenuView of the Module, we start up the View, without knowing what is it, or from where it comes from; that’s the beauty of Composite; decoupled development at its maximum.

Finish up

Hope this turns out to be useful and that you like it. See you in the next article (sooner this time I hope).


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Raul Mainardi Neto
Brazil Brazil
Senior .NET Architect from Brazil.

You may also be interested in...

Comments and Discussions

GeneralMy vote of 3 Pin
Lucian-aSterX29-Nov-10 1:32
memberLucian-aSterX29-Nov-10 1:32 
GeneralMy vote of 4 Pin
Collin Jasnoch2-Nov-10 3:28
memberCollin Jasnoch2-Nov-10 3:28 
GeneralNice Intro but... Pin
Collin Jasnoch2-Nov-10 3:27
memberCollin Jasnoch2-Nov-10 3:27 
GeneralGreat Pin
BigNat19-Jan-10 2:38
memberBigNat19-Jan-10 2:38 
GeneralRe: Great Pin
Raul Mainardi Neto20-Jan-10 7:48
memberRaul Mainardi Neto20-Jan-10 7:48 
GeneralWell done! Pin
Daniel Vaughan31-Aug-09 8:54
memberDaniel Vaughan31-Aug-09 8:54 
GeneralRe: Well done! Pin
Raul Mainardi Neto31-Aug-09 9:10
memberRaul Mainardi Neto31-Aug-09 9:10 
GeneralUnit Tests Pin
Yazid30-Aug-09 10:39
memberYazid30-Aug-09 10:39 
GeneralRe: Unit Tests Pin
Raul Mainardi Neto30-Aug-09 17:17
memberRaul Mainardi Neto30-Aug-09 17:17 
GeneralRe: Unit Tests Pin
Yazid30-Aug-09 21:45
memberYazid30-Aug-09 21:45 
GeneralGreat intro Pin
Daniel McGaughran17-Aug-09 16:28
memberDaniel McGaughran17-Aug-09 16:28 
GeneralRe: Great intro Pin
Raul Mainardi Neto18-Aug-09 1:47
memberRaul Mainardi Neto18-Aug-09 1:47 
GeneralExpecting part II Pin
ucha14-Aug-09 4:13
memberucha14-Aug-09 4:13 
GeneralRe: Expecting part II Pin
Raul Mainardi Neto14-Aug-09 4:51
memberRaul Mainardi Neto14-Aug-09 4:51 
GeneralThanks so much Pin
NewYoda14-Aug-09 3:01
memberNewYoda14-Aug-09 3:01 
GeneralRe: Thanks so much Pin
Raul Mainardi Neto14-Aug-09 3:41
memberRaul Mainardi Neto14-Aug-09 3:41 
GeneralBest Article Pin
Thanigainathan.S13-Aug-09 19:22
memberThanigainathan.S13-Aug-09 19:22 
GeneralRe: Best Article Pin
Raul Mainardi Neto14-Aug-09 1:59
memberRaul Mainardi Neto14-Aug-09 1:59 
Generalgood 1st article on PRISM Pin
Sacha Barber12-Aug-09 22:10
mvpSacha Barber12-Aug-09 22:10 
GeneralRe: good 1st article on PRISM Pin
Raul Mainardi Neto13-Aug-09 2:01
memberRaul Mainardi Neto13-Aug-09 2:01 
GeneralRe: good 1st article on PRISM Pin
Sacha Barber13-Aug-09 2:52
mvpSacha Barber13-Aug-09 2:52 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.170525.1 | Last Updated 13 Aug 2009
Article Copyright 2009 by Raul Mainardi Neto
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid