Click here to Skip to main content
16,016,527 members
Articles / Desktop Programming / WPF

Migrating a Legacy WPF Application to Prism - Part 2

Rate me:
Please Sign up or sign in to vote.
2.33/5 (2 votes)
14 Apr 2010CC (Attr 3U)3 min read 21.3K   8   3
After my initial successes in moving to a Prism-style bootstrapper in Part 1, it was time to move onto the next step. But in the case of a legacy application, what's the next step?

Prism.FirstView.Structure

After my initial successes in moving to a Prism-style bootstrapper in Part 1, it was time to move onto the next step. But in the case of a legacy application, what's the next step?

Application Structure Overview

Our legacy application consists primarily of a WPF user interface, a WCF service that provides access to a SQL Server database and a few support libraries. One of those support libraries provides some classes that deal with the interaction between the user interface and the WCF service and is my prime candidate for making some improvements using the Prism guidance.

There are two main entities, one that relates to a Project that is handled by the application and one that relates to Pages, which make up the contents of a Project. So these seemed to me to be good choices for modules. But, the existing infrastructure merges the roles of Service and ViewModel into a single class, which I'd like to separate.

So, my plan (so far at least) is to create Prism Modules for the Project and Page and create the relevant Views, ViewModels, Services, and Controllers that are required to implement the functionality. Rather than having to fully re-write the underlying code that handles UI/WCF Service interaction, I'm planning on writing a Prism-facade that will simply call out to the existing infrastructure, which I can eventually replace as time progresses. This gives me the testability advantages of Prism without having to rip out the heart of the application and re-write it completely, which would be a costly and time consuming task.

Getting Started

Prism.FirstView

For my next step, I'm focusing on the Project aspects of the application, so (as you can see in the screen shot above) I've created a Project module containing the ProjectModule, a ProjectService, ProjectTreeView, ProjectTreeViewModel and a ProjectController, which will handle the interactions between the different views of a project (when I get that far).

Each of these classes implements an interface, which enables me to easily mock these implementations to test specific aspects of the application. At this stage, my implementations are very simple in that they just initialise the relevant Views, ViewModels, etc. The View itself is simply a UserControl that contains a root Grid element with a pink background. The important thing is to get it loaded and displayed first.

Implementation Specifics

In the application's shell, the existing user control was removed and replaced with the following region definition.

XML
<ContentControl x:Name="_navigation"
                cal:RegionManager.RegionName="{x:Static inf:RegionNames.Navigation}"
                DockPanel.Dock="Left" />

The "cal" XML namespace resolves to "http://www.codeplex.com/CompositeWPF" and the "inf" XML namespace resolves to an infrastructure assembly that contains constants for the region names.

The ProjectController class retrieves the relevant region that is the destination of the View and adds the View for the associated ViewModel to that region and then activates it as shown in the following code example:

C#
public void Run()
{
    IRegion region = this._regionManager.Regions[RegionNames.Navigation];
    region.Add(this._projectTreeViewModel.View);
    region.Activate(this._projectTreeViewModel.View);
}

The call to the Activate method is essential if you want to be able to see your View. Until the Activate method is called, you will not be able to see your View.

The Run method of the ProjectController is called in the Initialize method of the ProjectModule after registering the required views and services, as shown in the following code example:

C#
#region Private Methods  private void RegisterViewsAndServices()
{
    // NOTE: The ContainerControlledLifetimeManager ensures that the same
    //       instance is returned by any call to Resolve or ResolveAll.
    this._container.RegisterType<IProjectService, 
	ProjectService>(new ContainerControlledLifetimeManager());
    this._container.RegisterType<IProjectController, 
	ProjectController>(new ContainerControlledLifetimeManager());
    this._container.RegisterType<IProjectTreeView, ProjectTreeView>();
    this._container.RegisterType<IProjectTreeViewModel, ProjectTreeViewModel>();
}

#endregion Private Methods  #region IModule Members

public void Initialize()
{
    RegisterViewsAndServices();
    IProjectController controller = this._container.Resolve<IProjectController>();
    controller.Run();
}

#endregion

As you can see in the screen shot above, apart from writing all the tests, putting some simple content in the ViewModel, a bit of work on the infrastructure and doing a lot of head scratching, that's it! Granted it's just a pink rectangle at the moment, but I now have a View that is loaded into the right place.

My next step is to put some useful UI code into the View and try to gradually incorporate some of the visual functionality of its predecessor.

License

This article, along with any associated source code and files, is licensed under The Creative Commons Attribution 3.0 Unported License


Written By
Software Developer (Senior)
United Kingdom United Kingdom
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralMy vote of 1 Pin
sandippatil25-Sep-12 7:34
sandippatil25-Sep-12 7:34 
QuestionWPF Legacy? Pin
Crisan Radu22-May-09 0:39
Crisan Radu22-May-09 0:39 
AnswerRe: WPF Legacy? Pin
Derek Lakin22-May-09 1:17
Derek Lakin22-May-09 1:17 
I wasn't talking about WPF as legacy, as I was referring to the application (which happens to have been written using WPF) as being a legacy application, i.e. it's not a start from scratch project. Apologies for the confusion.

If you don't understand the benefits of Prism (or Composite Application Guidance for WPF and Silverlight[^] to use it's formal name) then perhaps you should start by reading the guidance first Poke tongue | ;-P
In Prism, there are absolutely no config files for you to maintain, unless you explicitly decide that you want to configure your modules using a config file, but static module enumeration, XAML module enumeration, and directory-based module enumeration are other options.

To put my own argument fairly succintly, Prism is a set of guidance that happens to include a framework to help you create a composite application (dependency injection, separation of concerns, UI composition, and so on). You don't have to use their frameowrk, but the guiding principles are sound for creating a composite application. If you're not creating a composite application, then you'll probably find Prism an unnescessary overhead.

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.