Tuesday, July 7, 2009

Calcium: A modular application toolset leveraging the Composite Application Library (PRISM) – Part 2


Calcium is a WPF composite application toolset that leverages the Composite Application Library. It provides much of what one needs to rapidly build a multifaceted and sophisticated modular application.

In part one of this series, we explored some of Calcium’s core infrastructure, including module management, region adaptation, and the Bootstrapper. Now we will examine the Messaging system, and take a look at two other modules, namely the WebBrowser module and the Output module.

Calcium screenshot
Figure: Calcium with Web browser and Output modules visible.

In the first article we saw that Calcium consists of a client application and server based WCF services, which allow interaction and communication between clients. Out of the box, Calcium comes with a host of modules and services, and an infrastructure that is ready to use in your next application.

We’ve got a lot of ground to cover. For that reason I’ve decided to break this article up into a series of three, maybe four articles.

  1. Introduction to Calcium, Module Manager.
  2. Message Service, WebBrowser module, Output Module. (this article)
  3. File Service, User Affinity Module, Text Editor Module
  4. TBA

In this article you will learn how to:

  • build a location agnostic messaging system;
  • use WCF custom headers to identify specific client application instances;
  • create a web browser and output window modules for Calcium;
  • inject RoutedCommand handlers into the shell (main window);

Some of the content in this series of articles are not at an advanced level and will suit even those that are new to Prism. While others, such as the messaging system, will suit more advanced readers. Hopefully there are things here to learn for everyone.

These series of articles are, in some respects, an introduction to some areas of Prism. Although, if you are completely new to Prism, you may find yourself somewhat overloaded at times, and I would recommend taking a look at some beginner Prism articles before you tackle Calcium, such as Jammer's Introduction or the Technical Concepts on MSDN

Location Agnostic Message Service

When developing an application, clearly it’s prudent to have uniformity in the manner certain tasks are carried out. An example of such a task is displaying common dialog boxes. But wait, if you think this section is just going to be about an abstracted dialog box system, it isn’t. That would be far too boring. While Calcium does provide a common dialog system, it also allows us to display a dialog to the user from the server during any WCF call! Moreover, it allows us to consume the same API on the client and the server. We don’t need to worry about interpreting the result of a WCF call in the client. This means we are able to interact with the user directly from anywhere, without having to know where our business logic is executing i.e., client or server.

Out of the box, Calcium comes with a number of IMessageService implementations. There is a client implementation for WPF, another client-side implementation for command line driven applications, and a server-side implementation that sends messages back to the client via a callback, and leverages the client-side IMessageService implementation.

Firstly I want to provide you with an overview of the client-side message service, and then we will examine how it is leveraged from the server-side to provide the location agnosticism.

Client-side Message Service Implementation

Obviously it’s unwise for each member of a development team to be creating his or her own dialogs for simple tasks such as asking the user a closed ended question (a Yes/No question box). We would end up with lots of duplication, and that degrades maintainability. If we decide to change the caption in the dialogs across the board, it is rather more difficult if dialogs are scattered throughout the project. Likewise if we wish to port the application from WPF to Silverlight, or even to a command line interface (think Powershell or mobile applications), it’s great to be able to swap out the implementation for any given scenario. Clearly an abstracted layer is in order.

The Message Service has various overloads which allow errors, captions, and messages to be specified.

Let’s take a look at the IMessageService interface and client-side implementations.

IMessageService Class Diagram

Figure: IMessageService allows us to interact with the user in a UI agnostic manner.

The Message Service allows for a Message Importance level to be specified. This allows for a threshold noise level to be specified by the user. If the MessageImportance is lower than the user’s preference, then the user won’t be bothered with the message. In a later version of Calcium we shall see a Preferences Service for specifying the preferred level.

MessageServiceBase Class Diagram

Figure: MessageService and CommandLineMessageService both override ShowCustomDialog method of MessageServiceBase to cater for their particular environments.

By applying variation through merely overriding the ShowCustomDialog method it also makes it very easy to mock the MessageServiceBase class for testing.

Our client-side WPF implementation channels all messaging requests through the ShowCustomDialog method as shown in the following excerpt.

See full detail: http://www.codeproject.com/KB/WPF/CalciumPart02.aspx

No comments: