Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Simple Prism Application Templates

0.00/5 (No votes)
19 Jan 2010 1  
VS2008 templates to create simple WPF Prism based applications.

Introduction

This article describes a set of templates that I have written which are intended to help create simple WPF applications based on the Composite WPF Framework using the Prism libraries. Why write these templates when there are already templates available, e.g., Calcium? This is a very valid question. There are a number of reasons.

How many times do you have the need to create a simple application either at work or home? This could be a small utility you are creating, a prototype application to prove some new functionality / concept, or some code just to experiment with Prism etc. You know that you would like to use the Prism libraries to build it, but to be honest, you also know that to setup a Prism application from scratch, hooking the shell, infrastructure, and modules together, will take more time than you plan to spend creating the actual application. You could, of course, just take an existing Prism based application if you have one and throw out what you don't need, but this is not usually a clean way to go. The same applies if you use one of the existing Prism frameworks, e.g., Calcium.

What I need are a couple of VSTemplates that would allow me to create a Prism based application quickly and which will have a common format, e.g., Shell, Infrastructure, and modules that I could create quickly and that I could quickly instantiate, enabling me to focus on the task at hand. It is also important to me that they use the basic functionality of Prism without any adaptations. I don't want to have to learn a framework on a framework just to create my simple application. What I have read and learned from the web on Prism should just work out of the box. I also wanted to be able to add additional modules that would automatically wire themselves up, and have the flexibility to add new regions to the default shell.

The two VSTemplates described in this application provide just that. I don't, for one minute, compare these templates with the professional templates provided with Calcium. But my new templates have enabled me to create my simple applications quickly and with a standard architecture. They have also been useful for training and introducing new people to Prism concepts, allowing them to be able to prototype / test applications easily.

Although I have tried to incorporate many best practices when creating these templates, I have taken a pragmatic approach which not all people will support. For example, the MVVP modules created do have a reference to the view. Although none of the examples use it in favour of a more traditional MVVM, it is there should your simple application require it.

The templates in this article include code that have been collected from different sources over time and included for use by the developer if they need it. I have tried to only include those utilities that I have found useful in the past when creating simple apps. I have added references to the original location of such code, and added a reference to the author at the end of this article.

Key Features

This section provides a short summary of the features provided by the new templates. Below is a picture of the solution that is created by default when you create and execute a new solution directly out of the box.

PrismSolutionMainScreen.JPG

Simple Prism Solution

After selecting the Simple Prism Solution template and generating a solution, Visual Studio is loaded with a complete compliable solution. The solution generated uses the standard layout as seen in the Prism examples on the web, e.g., with a shell, infrastructure, and module projects. When compiled, the output is written to a single bin directory. The layout of this directory is such that it can be directly copied and the resulting application executed without any modifications to code or config files.

Automatically Linked MVVM View

The MVVMView is intended to be used when adding new MVVM modules into the modules folder of the Prism solution. It creates a new module project, the output of which is linked automatically into the CompositeWPF application. The implementation is based on the MVVM pattern. It provides a number of useful features by default, e.g., automatically hooks up the Data Context to the ViewModel, and provides references to key objects like the logger, UnityContainer etc., by extending a common base class.

Integrated Log4Net Logging

It is mandated in our organisation that Log4Net is the default logging component that shall be used for logging in .NET apps. The provided solution has overridden the default logger implementation with Log4Net logging. Some components that have been included use Log4Net, by default. Using Log4net as the default logger ensures that the logging provided in these components is integrated automatically. The default Log4Net is configured by default to log to the Console, a UDP output (for use by Chainsaw), and to a rolling file.

Consolidated Timer Service

The Consolidated Timer is a simple low resolution timer facility that enables a single Windows Timer instance to handle many timer operations within the application, reducing the number of system timer resources that need to be maintained. The base timer checks the timers every second, so this is a very course timer facility useful for many GUI tasks, e.g., refreshing, polling etc.

Integrated Dialogs

I have included the Dialogs Workspace as provided by the CompositeWPF Contrib so that it can be readily used.

Wait Cursor Support

This facility enables modules to activate the Wait Cursor on the Shell.

Simple Menus

Nothing special here, just a simple menu toolbar with a couple of basic commands implemented to perform basic functionality, e.g., exit application.

Example Usages

There is an example module included that demonstrates how to use all of the above features as required. Normally, this project is deleted and replaced with a module generated using the MVVMView template.

Template Installation

Enough of the high level information, let's talk about the installation of the templates. There is provided by an MSI, that when executed, will install the templates and all the required libraries. I have only tested these templates on Visual Studio 2008.

Third Party Libraries

Our development currently uses a number of third party libraries which are common to all application development. The list of libraries we use are shown below:

  • Prism Composite Application Library DLLs v2.0.0.0
  • Log4Net DLL v1.2.10.0
  • NUnit Framework DLLs v2.5.0
  • MOQ DLLs v3.1.0.0

These components could have been installed in the GAC, but I prefer to have these in a fixed location on each developer's machine. So, the setup places these in C:/Program Files/DotNetLibraries. Not all of these libraries are currently used in the framework, but are included for the convenience of developers. I intend to update the framework to incorporate these tools at some point.

Templates Files

The installation places the template files in the user's MyDocuments folder under "Visual Studio 2008 /Templates/ProjectTemplates". The templates are configured to appear in the MyTemplates Visual C# section of the New Projects dialog when selected. The two new templates are "Simple Composite WPF Solution" and "MVVMView". These two templates and their uses are described below.

Simple Prism Solution Template

This template, when selected, will create a new Prism Solution. I have tried to make the content of this solution as practical as possible and to comply with the traditional layout as used by many Composite WPF applications.

I made the assumption that the installation is on a 32 bit machine. If this is not the case, then you need to copy the above libraries into the correct Program FIles/DotNetLibraries directory. Secondly, if you have changed the location where your templates are read from in Visual Studio, then you will need to relocate the above templates accordingly.

The layout of the solution generated by this template is shown below:

SimplePrismSolution.JPG

As you can see, there are three sections to this solution: Shell, Infrastructure, and Modules.

Infrastructure

The Infrastructure project is the common area of the Prism application, and I use it to store any common artifacts that may be needed by the application. Infrastructure is divided into the sections described below. Storing common entities in the Infrastructure class is a common pattern when using the Prism framework, and it is the one I find most useful for small to medium size applications, which is why I have used it in the templates. For larger applications, I would tend to store the common data in Core classes, one for each module.

CommonEntities

This section contains common entity classes that are used throughout the application. By default, there are two: TimerJob.cs and ApplicationConfig.cs. These classes are self explanatory when you read about the corresponding services below.

CompositeWPFBase

There are three default classes in the CompositeWPFBase section: BindableObject, DispatchedObservableCollection, and CompositeWPFBase. BindableObject is a class from Josh Smith. This is an implementation of the INotifyPropertyChanged interface, and I use it for setting up the databindings in the ViewModel. So I added this into the base class for simplicity as he recommends. Have a read of his article for more information.

The CompositeWPFBase class is my base class that is used by all MVVM classes. It exposes a number of references to core components of the base classes, e.g., Entity Container, Event Aggregator, and the ILoggerFacade. This generic class is used to wire up my MVVM pattern. There is normally no reason for users to access these two base classes directly.

The DispatchedObservableCollection is included to solve the problem that the ObservableCollection cannot be used for databinding when the collection is updated from any thread that is not the primary GUI thread. The DispatchedObservableCollection implementation is that provided by the WPFExtensions library. As I did not require the other features of this library, I have included only the DispatchedObservableCollection classes directly into the Infrastructure project.

Configuration

This section contains the configuration objects used by the application. There is a class called RegionConstants. This class contains the definitions for the regions used in the Shell and Module components. If a developer decides to modify the shell with new regions, they will need to add the definition for the regions in this class.

There are also a number of Composite Presentation Events defined in this section that are used across the application, for example, StatusBarMessageEvent, WaitCursorEnabledEvent, etc.

Interfaces

This section contains the common interface definitions used by the application.

Services

The Services section is where I define the common services for use across the application. By default, I provide two services: the first is CompositeWPFTimerService, and the second is the Configuration Service.

CompositeWPFTimerService

This service is a low resolution timer service (by default, 1 second). The idea being that instead of using multiple timer operations throughout the application for common timer operations, you can register a TimerJob to this service for processing. The timer jobs are held in a queue and processed according to the TimerJob specification. The following timer base operations are supported by this service:

public interface ICompositeWPFTimerService
{
    void Start();
    void Stop();
    void AddJob(TimerJob job);
    void RemoveJob(string name);
    void UpdateJob(TimerJob job);
    void RemoveAllJobs();
    void PauseJob(string name);
    void ResumeJob(string name);
}

The user specifies how each TimerJob shall be processed in the TimerJob instance itself. Each job must have a unique name. The user can define if the timer is a one shot timer or if it should be rescheduled once expired. The user can specify the time when the timer shall execute and the reset time if the job shall be rescheduled. The user specifies the JobTask that shall be executed once the time period expires. This is executed on a separate thread per task.

public string Name { get; set; }
public DateTime ExecutionTime { get; set; }
public TimeSpan ResetDuration { get; set; }
public TimerJobState State { get; set; }
public JobTask Operation { get; set; }
public TimerType OneShot { get; set; }

One point, there is a considerable amount of Log4Net debugging in this feature which is on by default. To switch this off, add the following to the shell app.config file:

<logger name="CompositeWPFTimerService">
    <level value="OFF" />
</logger>

ConfigurationService

The configuration service is a work in progress. The current implementation is a simple example of how to read and write user preferences using the "Settings" feature which is adequate for my simple applications. However, with this simple abstraction, the service could be very easily modified to use an alternative storage medium, if necessary.

Workspaces

As Dialogs are not natively supported in the Composite WPF, I took this opportunity to incorporate DialogWorkspace from the CompositeWPF Contrib. I had some problems with this code as I could not find how to position the dialog correctly, so I modified the code to always centre a dialog in the centre of the screen.

Prism Shell

The shell is the main entry point to the application. In addition to the usual WPF artifacts like app.xml etc., it also contains the Prism specific components, e.g., Bootstrapper.cs etc.

Main Application Shell

The main shell of this application has three regions defined: MainMenu, StatusBar, and a StatusBar region. This is the minimum you would expect in a small application using Composite WPF. Following the standard Composite WPF documentation, developers can easily add additional regions into the shell for other areas of the GUI, e.g., Toolbars, Selection areas, etc.

Modules

The modules section is where the modules are stored. These modules are hosted in Shell containers. By default, there are four modules supplied in the default solution. All of the modules follow the same MVVM Design Pattern as discussed earlier.

MainMenu Module

The Main Menu module provides a basic Menu, see below. It comes prewired with Exit and an About dialog to show the use of the Dialog Workspace.

StatusBar Module

The status bar at the bottom of the screen uses the Event Aggregator to subscribe for messages to be displayed. Modules can publish messages that will be displayed in the Status Bar.

Dialogs Module

This module hosts the dialogs used by the application. These dialogs use the Dialog Workspace from the Composite WPF Contrib as described earlier.

MVVM Project

I have created a second template that creates a new project for each new module to be added to the application. The idea here is that the user will add modules to the Modules solution for each module needed for the application. When the user selects the MVVMProject template and executes it, a new project is created with the following structure:

MVVMModule.JPG

As you can see from the above example, the template renames all of the artifacts in the template using the name supplied by the user, in this case, prefixing all of the files in the project with "TestProject". It also renames the namespaces and class names etc., with the same prefix; see below:

MVVMCode.JPG

The template creates all of the plumbing necessary to integrate the module into the solution. The project is configured automatically to copy the output DLL to the output modules directory so that it is automatically picked up at run time. The modules are automatically configured to populate the DisplayRegion. If the user needs to change this location, then they only need to modify the constant for the Regions in the TestModule section, as shown above.

The goal here is that the developer need only add code to populate the user control and ViewModel classes to add the business specific code and not have to worry too much about Prism. In addition, the base classes of the view's ViewModel provide easy access to the logging, event aggregator, and Unity components.

Usage

The usage of the templates is simplicity in itself. The main screen of the application is shown below:

PrismMainScreen.JPG

Create a Prism Solution

Use the following steps to create a new Prism solution:

  • Start Visual Studio
  • Select the File - New Project option
  • Select the SimplePrismSolution option in the My Templates selection
  • Select the location of the solution and then OK
  • The solution will be created and can be built and compiled

Add a Module

Us the following steps to create a module:

  • It is normal to delete the Examples module from the generated solution before proceeding.
  • Select the File - New Project option.
  • Select the MVVMModule option in the My Templates selection.
  • Select the location of the Modules directory in the folder location selection to ensure the module is under the Modules location, and then OK.
  • A new module will be created and can be built and compiled.

Running the Examples Module

This section provides a short overview of the Examples module. The example module displays a tabbed view which has a number of basic tabs which provides facilities to show how to use some of the features provided.

Status Bar Example

Enter a text in the text box. Select the button, and the text will be published in the status bar for 3 seconds.

Timer Example

This example enables the user to play with the timers. You can add and manipulate the timers and watch the output in the window provided.

Configuration Service Example

This simple application shows how the configuration service can be accessed and used.

Logging Example

This application shows how to access the logger and to write different logger messages to the Log4Net output.

Wait Cursor Example

This application shows how to enable and disable the application wait cursor.

Summary

As with all such tasks, this is a work in progress. The intention is to continue to upgrade and add to these simple templates. I really do welcome feedback on this code to help me learn and improve as I go forward.

References

A lot of the libraries and code in these templates are a collection of useful utilities etc., I have collected over time. This section is a reference to these contributions without which my life would have been made a whole lot more difficult.

History

  • V1.0: Initial version of the templates 19th January 2010.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here