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

Migrating a Legacy WPF Application to Prism - Part 1

0.00/5 (No votes)
14 Apr 2010 1  
How to migrate a legacy WPF application to Prism

This is the first of several posts on my journey migrating a legacy application to use the Composite Application Guidance for WPF, which (like Brian Noyes) I prefer to call Prism, mainly because it's shorter, but it's also cooler!

I've watched the "Brian Noyes on Prism" dnr TV episode intently, read through the guidance documentation, I've done the hands-on lab, all of the quick starts and dissected and analysed the StockTraderRI sample application, so now I figure I'm ready to start cranking some Prism code for our legacy application1.

1By "legacy", I mean that it's a regular WPF application that was not created using the Prism (or any other specific) guidance, so it's not a green field project.

Understanding the Terminology

I don't pretend to be completely clued up on all aspects of design patterns, but I'm aware of the key concepts behind Model-View-Controller (MVC) and its numerous variants, so when I opened up the StockTraderRI sample application, I was initially a bit confused to see a combination of Presenters from Model-View-Presenter (MVP; also referred to as Supervising Controller in the guidance), Controllers from MVC, and PresentationModels from Presentation Model, or Model-View-ViewModel (MVVM) to give it its more WPF-focused name.

After a bit of digging, it was clear that the Prism team were using a mixture of approaches and for good reason (of course), which I thought I'd just quickly explain for my own recording purposes if nothing else.

  • Model: The underlying business entities that represent the data in your system (pretty much standard throughout all of the MV* patterns). E.g. StockTraderRI.Infrastructure.Models.NewsArticle class in the StockTraderRI sample.
  • View: The user interface representation of the underlying Model (also pretty much standard throughout all of the MV* patterns). E.g. StockTraderRI.Modules.News.Article.ArticleView class in the StockTraderRI sample.
  • Presenter: When the Model can provide the data that the View requires without any complex manipulation or transformation, then the View binds directly to the Model and the Presenter handles the state of the View in the cases where complex user interface logic is required, such as changing colours of controls and showing/hiding controls. E.g. StockTraderRI.Modules.News.Article.NewsReaderPresenter class in the StockTraderRI sample. The NewsReader View binds directly to properties of the NewsArticle Model class, which is supplied by the NewsReaderPresenter.
  • PresentationModel: When the View cannot bind directly to the Model, a PresentationModel class is used to provide the Model in a format more easily consumed by the View acting as a façade. The PresentationModel class also manages UI-specific state and behaviour. E.g. StockTraderRI.Modules.News.Article.ArticlePresentationModel class in the StockTraderRI sample. The ArticleView class binds Articles property exposed by the ArticlePresentationModel class.
    Note: Given that MVVM is a WPF-specific variation of Martin Fowler's Presentation Model pattern, I prefer the term ViewModel to PresentationModel; if nothing else, it's shorter. :)
  • Controller: The StockTraderRI sample application uses Controller classes to manage the interaction between multiple views. E.g. StockTraderRI.Modules.News.Controllers.NewsController class, which manages interactions between the ArticleView and the NewsReader View via the ArticlePresentationModel and NewsReaderPresenter.

There is a discussion about the patterns used in Prism (and hence the sample application) in the guidance documentation, but the above helped to put things straight in my mind.

Getting Started

The first thing I did to get me started down the road to a Prism-based application was to implement the Bootstrapper, which I did as follows:

  1. Added references to the following Prism assemblies in my main (shell) project:
    • Microsoft.Practices.Composite.dll
    • Microsoft.Practices.Composite.Wpf.dll
    • Microsoft.Practices.UnityExcetions.dll
    • Microsoft.Practices.Unit.dll
    • Microsoft.Practices.ObjectBuilder.dll
  2. Added a new class called MyApplicationBootstrapper2, which inherits from UnityBootstrapper as shown in the following code example.
     public class MyApplicationBootstrapper : UnityBootstrapper
     {
         protected override DependencyObject CreateShell()
         {
             MainWindow window = new MainWindow();
             window.Show();
             return window;
         }
    
         protected override IModuleEnumerator GetModuleEnumerator()
         {
             return new StaticModuleEnumerator();
         }
    }
    
  3. Removed the StartupUri property from App.xaml.
  4. Created an instance in the Application.Startup event handler as shown in the following code example:
    private void Application_Startup(object sender, StartupEventArgs e)
    {
        MyApplicationBootstrapper bootstrapper = new MyApplicationBootstrapper();
        bootstrapper.Run();
    }

2 I've substituted "MyApplication" for the name of the actual application to protect the interests of my employer.

So far so good. The application runs as it did before but now it uses a Bootstrapper. Nothing dramatic and no big benefits yet, but it works. Next step, start writing some tests and a some modules to contain the existing UI controls as views in a more Prism-like approach.

Note: I welcome (encourage even) any corrections/comments/etc. about the approach that I'm taking or on any of the details that I've included in this post (and future posts).

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