Partilhar via


Composite Application Library Baseline Architecture

Retired Content

This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This page may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.

The Composite Application Library addresses a number of common requirements for building composite applications. These compositional needs are described in detail in the Composite Application Guidance for WPF. As a whole, the Composite Application Library accelerates development by providing out-of-the-box the services and components to address these needs.

The architecture the Composite Application Library seeks to address primarily consists of a shell application that defines regions for hosting content with views and services offered by multiple modules—possibly dynamically loaded. Underlying the application, and the Composite Application Library, is a service layer to provide access to the application services based on the Composite Application Library, as illustrated in see Figure 1.

Ff649198.a9a1000e-510c-43eb-b8d0-8e8c7cdd604c(en-us,PandP.10).png

Figure 1
A composite application architecture with the Composite Application Library

The architectural pieces of a composite application are the following:

  • Shell. This is the top level window to host different user interface components. The shell itself defines the layout structure, but it is typically unaware of the exact contents it will contain. It typically has minimal capability, so most of the application's functionality and content is provided by modules.
  • Shell presenter. Any logic for the shell presentation is handled by the shell presenter. This follows the separated presentation pattern and helps separate the display of content from the user interface logic. This separation improves testability and maintainability.
  • Regions. These are placeholders for content and host visual elements in the shell. These can be located by other components through the RegionManager to add content to those regions. Regions can also be used in module views to create discoverable content placeholders.
  • Modules. These are separate sets of views and services, frequently logically related, that can be independently developed, tested, and optionally deployed. In many situations, these can be developed and maintained by separate teams. In a composite application, modules must be discovered and loaded, in the Composite Application Library this process is known as module enumeration and module loading.
    • Module enumeration. This is the process of locating individual modules for loading. This location can be done statically, through a configuration file, or by examining a directory. This includes the following types of enumeration:
      • Static enumerators. These allow the shell application to specify the set of modules in-code and are statically referenced from the shell application.
      • Configuration-baseenumeration. This specifies the modules to load in a configuration file.
      • Directory sweep enumeration. This examines a folder for the modules to load.
    • Module loading. This feature allows a component to specify, in code, when a module should be loaded. Modules discovered during enumeration may be immediately loaded or loaded on-demand.
    • Initialization. The ModuleLoader initializes each module when it is first loaded.
  • Views. Views are responsible for displaying content on the screen. In a composite application, views are frequently the element of composition by the shell or other views. The following are considerations for use when developing views in WPF:
    • The user interface should be testable and implement appropriate design patterns for separations of concerns. Typically, this involves some type of binding-oriented design pattern, such as Supervising Controller or Presentation Model.
    • Windows Presentation Foundation (WPF) data binding should be used wherever possible.
    • WPF commands should be used for binding user interface actions.
  • Communication. Different components in the application may need to communicate with one another whether they reside in the same or different modules. This needs to happen without the modules requiring hard dependencies on one another. The Composite Application Library provides mechanisms to do this with the CompositeCommand and EventAggregator. Communication strategies may need to consider thread-safety issues. The following describes the CompositeCommand and EventAggregator:
    • CompositeCommand. Frequently, when compositing views, commands those views support must also be composited. The composite command is a strategy to combine the execution of commands. This allows the command invoker to interact with a single command that affects multiple commands.
    • EventAggregator. In views that need to send an event to other views or components and do not require a response, use the EventAggregator. Multiple components can publish an event, and multiple subscribers can receive the event.
  • Services. The application and modules expose services for their own and shared use. These are exposed through a service container that locates and, often, constructs the services. By default, the Composite Application Library uses the Unity container for this service location.

When to Use the Composite Application Library

The Composite Application Library is most useful when building brand-new composite WPF applications. The Composite Application Library provides core services for building composite views and loading modules, and it help solves challenges in communication across decoupled components.

Discrete services offered by the Composite Application Library also help when seeking to upgrade an existing WPF application to a composite WPF application.

A New Application Based on the Composite Application Library

Depending on application complexity, a composite WPF application can consist of a shell project with a number of module projects. The activity diagram in Figure 2 illustrates activities needed to develop a composite WPF application using the Composite Application Library.

Ff649198.da1608e2-b4d3-4a55-99d3-fb100373c85b(en-us,PandP.10).png

Figure 2

Activities for creating a WPF composite application

The core activities needed when starting a new composite WPF application are

  • Define the shell
  • Create the bootstrapper
  • Create a module
  • Add a module view to the shell

More detailed references for each activity can be found in "More Information."

Define the Shell

The application shell provides the basic layout for the application. This layout is defined using regions that modules can use to inject views. Views, like shells, can use regions to define discoverable areas that content can be injected into, as illustrated in Figure 3. Shells typically set the look and feel for the entire application and contain the styles that are used application-wide.

Ff649198.51e4c4cd-8b1b-4feb-9e21-1f6445741f61(en-us,PandP.10).png

Figure 3
Shells, Views and Regions

Create the Bootstrapper

The bootstrapper is the glue that connects the application with the Composite Application Library services and the default Unity container. Each application creates an application-specific the bootstrapper inheriting from UnityBootstrapper and defines the enumeration strategy for its modules, such as static or configuration-based, as illustrated in Figure 4.

The bootstrapper, by default, logs events using the .NET Framework Trace class. Most applications will want to supply their own logging services, such as Enterprise Library logging. Applications can supply their chosen logging service in their bootstrapper.

The UnityBootstrapper enables all of the Composite Application Library services by default. These can be disabled or replaced in your application-specific bootstrapper.

Ff649198.581294e5-0f4d-4bc2-8023-83700fde80be(en-us,PandP.10).png

Figure 4
Diagram demonstrating connecting to the Composite Application Library

Create the Module

The module contains the views and services specific to a piece of the application’s functionality. These most often are contained in separate assemblies and developed by separate teams. A module is denoted by a class that implements the IModule interface. These modules, during initialization, register their views and services and may add one or more views to the shell.

Depending on your module loading approach, you may need to apply attributes to your module classes or define dependencies between your modules.

Add a Module View to the Shell

Modules take advantage of the shell’s regions for placing content. During initialization, modules use the RegionManager to locate regions in the shell and add one or more views to those regions. The RegionManager is responsible for keeping track of regions throughout the application and is a core service initialized from the bootstrapper.

Solution Organization

Applications based on the Composite Application Library are typically organized by shell, module, and shared projects. Figure 5 illustrates the solution layout for the Stock Trader Reference Implementation.

Ff649198.34ef9732-308d-42f1-8042-39b086b12cdf(en-us,PandP.10).png

Figure 5
Solution layout

Deploying Your Application

You can deploy and update your application using familiar desktop-based techniques, such as by a Windows Installer package or ClickOnce. Some of these scenarios introduce more challenges because there are often no references between assemblies, unlike in non-composite applications. Therefore, tools that support building Windows Installer packages or ClickOnce packages are unable to automatically locate the required pieces for deployment. The Composite Application Library offers some tools and techniques to help with managing ClickOnce deployments.

Extending the Baseline Architecture

The Composite Application Library was designed to be extended to fit your specific scenario. Common areas to extend include creating or customizing the bootstrapper to select an enumeration strategy for module loading, call you own logger or use your own container, and creating your own region adapters. For more information about extending the Baseline Architecture see Customizing the Composite Application Library.

More Information

This section includes links to more information about these areas.

Bootstrapper

For more information about the bootstrapper, see the following topics:

Container and Services

For more information about the container and services, see the following topics:

Commands

For more information about commands, see the following topics:

Deployment

For more information about deployment, see the following topics:

Events

For more information about events, see the following topics:

Modules

For more information about modules, see the following topics:

Regions

For more information about regions, see the following topics:

Shell and Views

For more information about shells and views, see the following topics:

Solution

For more information about building a solution, see the following topic:

Retired Content

This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This page may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.