Showing posts with label Prism. Show all posts
Showing posts with label Prism. Show all posts

Thursday, 7 April 2011

MVVM Revisited

I have been working with MVVM and Prism for a couple of years now and have had some recent revelations which you may find useful.  Working with MVVM by itself, is relatively straightforward.   Combine it with other patterns, such as MVC and IoC, and things can get complicated.

Here is a common implementation of MVVM:

This example also utilises a CustomerController along with some services, all of which are supplied by the “Model”.  If you’ve worked with Prism you’ll probably recognise this rather unorthodox implementation of MVC, something I’ve never been comfortable with.  Injecting a controller into a ViewModel seems backasswards to me.  I would prefer to have the Controller be aware of the ViewModel and indirectly control/manage the Views.

Aside from being awkward, this approach does work.  But don’t expect your modules to be “modular”.  Sure, within your solution it will have the appearance of being a module, but it won’t very portable.  If you’re persistent and are dedicated, you can try to “reuse” the Customer module above, but be prepared to drag a half dozen dependent assemblies with it.

So, what is modularity without portability?  Without portability, modularity is reduced to a code organisation concept.  

Looking over this situation it occurred to me that the injection of dependencies in the ViewModel was pretty much unrestrained.  If the ViewModel needed it, just add another parameter to the constructor.  The entire Model was wide-open for consumption, provided it was registered with Unity.  Needless to say, this leads to greater and greater consumption, until finally the ViewModel is entrenched in implementation.

When viewed as a microcosm, MVVM can act like a tiered architecture.  And tiered architectures are great for scalable server applications, but pretty much ruin any hopes of portability.  

The other undesirable aspect of this is, while the ViewModel may require the ability to display a MessageBox (provided by the IMessageService), it has no use for the other 10+ methods provided by the service.  So, why not give it exactly what it needs – and no more.

One way to accomplish this through the introduction of a custom Model class:

Here the CustomerModel class defines exactly what the ViewModel demands of the Model.  In effect, it is a subset of the Model and is specific to that ViewModel.   It’s the ViewModel’s shopping list – “if you’re going to use me, this is my list of demands”.  It is now up to the implementer to provide this functionality – which is where the responsibility belongs.

With this approach the ViewModel has now been liberated and all of the “dependencies” removed.  Service methods have been replaced with delegates.  The ICustomerService can reside in the module itself, effectively making the CustomerModule a self-contained, standalone assembly.

A side benefit is that the View now contains no code-behind and is no longer dependent on the ViewModel interface.

While working through this I’ve created a new Prism sample solution, which includes a CustomerModule and an OrdersModule, Implementation project and a Shell.  I have reduced the module dependency down to a single Core assembly.  The Implementation project contains controllers, core services, a persistence manager, etc.  It knows about the modules and can orchestrate the workflow and manage the views.  The controllers “wire up” the Model and inject them into the ViewModels.   

At the moment, CustomerModule + Core is about as portable as it gets.

Wednesday, 24 March 2010

New Composite/Pattern Forum

A new developer forum has been launched dedicated to composite technologies and design patterns, including Prism, MEF and MVVM.

http://www.compositedevpatterns.com/forum.php

Wednesday, 10 February 2010

Prism Guidelines

Introduction
Due to the number of projects and files which can make up a Prism solution, it is important to adhere to conventions which are intuitive and sensible.  Maintaining these conventions takes the guesswork out of working with Prism and makes navigating through a solution predictable.
This document assumes a basic understanding of Prism, the Model-View-ViewModel (MVVM) design pattern, the Model-View-Controller (MVC) design pattern and Windows Presentation Foundation (WPF).

Modules
Prism requires that each module contain a class which implements IModule.  This effectively serves as a stub, allowing Unity to load the module.  IModule has an Initialize method that is often overridden and is used to register items in the container.


Avoid using the Initialize method to register the module’s items, instead create an entry in your unity.config file.  It is easier to maintain and does not involve code.

Views
GOAL: To maintain a separation of UI and business logic.
It is rare that a UI requirement cannot be expressed using Xaml alone.  Effort should be made to eliminate any UI logic contained in the View. 

Views always have a corresponding ViewModel.

Setting the ViewModel
Each View should contain a setter for its ViewModel, as shown below.
This property uses the Microsoft.Practices.Unity.DependencyAttribute, which gets picked up by Unity and automatically set.

Use of Styles
Avoid defining custom styles which effect appearance within your module or view.  Instead, use styles defined in your application resource assembly.  If you need to modify a control’s behaviour through the use of a Trigger, use the BasedOn property of the Style, referencing the resource Style.
Always reference the resource Style by using a ComponentResourceKey defined in your Interfaces assembly.
Style="{StaticResource {ComponentResourceKey TypeInTargetAssembly={x:Type Resources:Styles}, ResourceId=DialogBorderStyleKey}}"

Use of Converters
Avoid excessive use of custom converters (IValueConverter).  Often the same can be accomplished using Triggers or DataBinding.  Converters can act as “hidden” code-behind, making testing difficult.  Always look for a Xaml solution before resorting to the use of converters.

Naming Conventions
TYPE NAMING RULE EXAMPLE
View <name>View CustomerDetailView
Interface I<name>View ICustomerDetailView


ViewModels
GOAL: To encapsulate all UI-related logic in a single, testable class.

The ViewModel exists to serve the View, so use it.  Instead of using custom Converters do it in your ViewModel.

Avoid passing the IUnityContainer (or an abstract version) in your ViewModel constructor.  This hides the actual dependency and makes testing difficult.

Consider implementing INotifyPropertyChanged on your ViewModel so your View can respond to changes in the ViewModel.

Naming Conventions
TYPE NAMING RULE EXAMPLE
ViewModel <name>ViewModel CustomerDetailViewModel
Interface I<name>ViewModel ICustomerDetailViewModel


Interfaces
GOAL: To provide contracts that define a public interface, separate from its implementation.

Prism relies heavily on the use of interfaces.  All entities registered in the UnityContainer must include an interface and an entity that implements the interface.

Do not include public interfaces in your implementation assemblies, as this defeats the purpose of decoupling interface from implementation.


UserControls
GOAL: To provide reusable UI elements independent of implementation.

WPF UserControls differ from Views in that they do not have a related ViewModel.

Consider adding DependencyProperties to your UserControl to take advantage of DataBinding and Triggers, this makes your UserControl more versatile and reusable.

Avoid including binding to specific properties in your UserControl as this can greatly limit its reuse.

Naming Conventions
TYPE NAMING RULE EXAMPLE
UserControl <name>UserControl AddressUserControl


Services
GOAL: To provide static, stateless business logic and functionality across domains.

Services are normally registered in Unity as a singleton.

It is best to think of Services as a static library of methods.  If state persistency is required consider using a Controller (MVC pattern).

When consuming Services, avoid accessing them through IServiceLocator, instead explicitly use the service interface in your class constructor.  This makes for predictable testing and does not hide functionality or dependencies.

Naming Conventions
TYPE NAMING RULE EXAMPLE
Service <name>Service LoggingService
Interface I<name>Service ILoggingService

Events
GOAL: To provide multicast notifications across domains.

Note: The events referred to here are to be used by the EventAggregator, not standard .Net events.

Do not define events in your implementation assemblies. Since other assemblies will need to reference your event class placing them in an implementation assembly forces you to create a strong reference. Instead, place it in your interface assembly or, if appropriate, a shared core assembly.

Naming Conventions
TYPE NAMING RULE EXAMPLE
Event <name>Event SaveCustomerEvent
Handler <name>EventHandler SaveCustomerEventHandler


Commands
GOAL: To provide an input mechanism which allows for multiple and disparate sources to invoke the same command logic.

Include command logic in your ViewModel, or if using a Controller you may want to defer execution to the Controller.

Consider using a Command Behavior AttachedProperty to convert events to Commands on controls that do not natively support ICommand.

Naming Conventions
TYPE NAMING RULE EXAMPLE
Command <name>Command SaveCommand
Handler <name>CommandExecute SaveCommandExecute
<name>CommandCanExecute SaveCommandCanExecute

Conclusion
Prediction and consistency go a long way in working with Prism. Not subscribing to agreed upon conventions adds confusion and slows down development.

Monday, 25 January 2010

Code Complexity and Prism

I've recently had to review a number of problem areas of a large Prism project.  In the course of review, I had a number of realisations regarding design patterns, WPF and code complexity.  We use MVVM and MVC design patterns throughout our project.  Not surprising, many of our problem areas were related to divergence from these patterns.

In our implementation of MVVM we strive to have a complete decoupling of our Xaml views and any business logic.  So, finding views riddled with code-behind indicated a lack of understanding of:

  1. The MVVM design pattern, or
  2. The benefits of code separation

Or as I was to find out, a limited understanding of Xaml.  The view in question utilised over ten custom converters.  Not that converters are inherently evil, however, these converters were being used where Triggers or Data Binding could have easily gotten the job done.  But, if one is unfamiliar with these, they tend to use techniques they are familiar with -- in this case, IValueConverter.  Poor use of custom converters effectively becomes "hidden code-behind," and is difficult to debug and test.

Additionally, I found the ViewModel being underused and misused, providing a sparse selection of high level properties for binding.  This, in part, prompted the excessive use of custom converters.

The offending code-behind was an unusual solution brought about by a lack of Xaml know-how.   All of this code could have been expressed using Xaml.  Conclusion: Knowing a little about Xaml can reek havoc on a well-structured Prism project.

The hallmark of these decisions is code complexity, your first clue things have gone astray.

After much refactoring, including the removal of all the custom converters, the code-behind and reworking the ViewModel, the whole area straighten out and was greatly simplified.  It was a prime example of the power and importance of design patterns in maintaining good form and structure.

Sunday, 27 December 2009

Prism Sample: Resources

An area of Prism development that often gets overlooked is the management of resources.  I mentioned in a previous blog that View reuse is unlikely, but that doesn't mean you should create unnecessary dependencies to a resource assembly.

Similar to modules, resource assemblies can have an accompanying interface assembly.  This is done by defining ComponentResourceKeys in your interface assembly and using them as resource keys in your resource dictionary and in your Views.

public static class Styles
{
    public static ComponentResourceKey LargeTextStyleKey
    {
        get { return new ComponentResourceKey(typeof (Styles), "LargeTextStyle"); }
     }
}

and in your Xaml...

<textblock text="My Sample TextBlock Style"
           Style="{StaticResource {ComponentResourceKey TypeInTargetAssembly={x:Type Interfaces:Styles}, ResourceId=LargeTextStyleKey}}" />

Taking this approach decouples your modules from the resource assembly.  The advantage to do this is not so much in the area of reuse, but more in the implementation of themes.  Any Views that require the use of a resource can simply refer to it by its ComponentResourceKey.

Additionally, I would only have the Shell load the external resources, since the View modules are now unaware of the external resource.  The only draw back in doing this is you will lose your Visual Designer when editing your Xaml, because the designer cannot resolve the resource to render it.

It is also worth setting up default styles based on control types, by using the control type as the resource key (e.g. {x:Type TextBlock}).  This does not require the use of ComponentResourceKeys.

The area of theming WPF applications is a common one and there are a number of resources on CodePlex which address this area.  One example is the Razre WPF Framework, or you can build your own ThemeManager.

Conclusion
I think this pretty much concludes the PrismSample articles.  This was meant as an introduction for developers starting out with Prism and to provide some guidelines in setting up a Prism solution.  I hope this was of some use.  I'm certain others will have differing opinions, and that's okay too.  I'm always on the hunt for new approaches and new ideas.

I think Prism has a real future in WPF development.  Once you get into it and see the benefits, it changes how you think about and view WPF development; afterwards it is difficult not to think and develop that way, which is a good thing.

As always, comments/feedback welcome...

Saturday, 26 December 2009

Prism Sample: Services

In addition to Views and ViewModels, your Prism application will likely have one or more Services.  Per the CAL documentation, a service is defined as:

A service is an object that provides functionality to other components in a loosely coupled way through an interface and is often a singleton.

This is a fitting definition, but doesn't indicate belongs in a service or when something should be service.  Services reside outside the View-ViewModel pattern and provide functionality to anything that needs it.  In practice a service should address an area of business logic and have an appropriate name which describes the functionality it contains, like CustomerService or DataService, etc.
Avoid making a service a dumping ground for functionality you don't know where to put.  I tend to view services as static libraries of functionality, generally consisting of methods (think WCF Service Contracts).  My personal preference is to avoid storing state or exposing properties in services.  I don't use services to control workflow.  Instead I would implement a Controller to govern the workflow, and have the Controller consume the service.
On one Prism project, we would have regular design meetings where we would discuss where a given piece of functionality should reside.  The governing rule that came about, was that the ViewModel is directly concerned with the View and servicing the View; code that belongs in the ViewModel is there because of some requirement dictated by the View.  If that wasn't the case, we were probably looking at a general piece of business logic which likely belonged in a service (or Controller, if one existed).
Following this line of thinking, we found more and more of our code moving to services, until we had a robust services layer, and a lean ViewModel which simply became a consumer of the services.  This approach prevented business logic getting lost or hidden in ViewModels.  It also supported our decision to separate out our services into their own assemblies, which I would highly recommend.

Sunday, 20 December 2009

Prism Sample: Modules

Central to Prism is the concept of modules and modular design, therefore it's worth spending some time defining exactly what a module is, what it contains and what it shouldn't contain.  Per the Prism documentation:

A module in the Composite Application Library is a logical unit in your application. Modules assist in implementing a modular design. These modules are defined in such a way that they can be discovered and loaded by the application at run time. Because modules are self-contained, they promote separation of concerns in your application. Modules can communicate with other modules and access services in a loosely coupled fashion. They reduce the friction of maintaining, adding, and removing system functionality. Modules also aid in testing and deployment.

Having worked on a number of Prism projects with a wide range of developers, each interpreting this from their own perspective and experience.

Two of the guiding principles behind this are:
Single Responsibility Principle
Separation of Concerns

While most can agree on these principles, views differ on the depth and extent to which they are applied.  On one end of the spectrum we have the theorist, whose motivation may be to strictly adhere to these (some times with religious fervor).  And on the other end we have the realist, who simply wants to build a working piece of software that meets the business requirements.

The theorist looks beyond the business requirement, while the realist may argue that strict allegiance to these principles is outside the scope of the requirements.  Somewhere, somehow these views are resolved, usually by an architect or team lead; and the result usually falls somewhere in the middle.

Personally, I fall in the middle, and maybe lean towards the realist.  I don't feel software development should be an academic exercise.  If someone entertains the idea of using a certain design pattern, I'm always interested in "what problem does this solve?" and "what does it buy me?"  Unacceptable answers are "because Fowler said so" or "because that's what the Prism team does".

Enough of this, let's talk about modules...

In an earlier post, I talked about creating an Advertising module for Blogger and said I would create the following modules:

Blogger.Advertising.Interfaces
Blogger.Advertising.Views
Blogger.Advertising.ViewModels
Blogger.Advertising.Services
Blogger.Advertising.Services.Interfaces

Some developers would be tempted to bundle these up into two assemblies:
Blogger.Advertising
Blogger.Advertising.Interfaces

storing their Views, ViewModels and Services in a single assembly.

And I could be convinced of this.  It's certainly easier to maintain.  But I would argue that Views/ViewModels and Services are logically separate and warrant their own assemblies.  It's not inconceivable that another module or system could be a consumer of these services, without the need for Views or ViewModels.

So, why separate out Views from ViewModels?

I think it is somewhat idealistic to expect Views designed for Product A to be simply dropped into Product B (two different implementations).  In theory this is possible, but in practice I've never seen it happen.  Here we get into areas of look and feel and layouts.  While we can do a lot to make a view generic and use themes and skins to alter its appearance, at the end of the day there is always going to be something different or required which makes the view unusable.  So why bother?

I always assume my views are not going to be reusable; that they're part and parcel to a specific implementation.  My ViewModels, however, are completely reusable.  I would also argue that mocking up Views is far less time consuming than the creation of ViewModels.

Regardless of what I think, your design decisions are going to be driven by a number of factors.  I think its important to consider all views and options, and decide which is suitable.

Thursday, 17 December 2009

Prism Sample: Basic Concepts

As stated in my earlier post, this model solution attempts to illustrate how Prism and Unity are used, what is a module, what belongs in one and what doesn’t, the use of interfaces and design patterns.
One of the most basic aspects of code organisation is knowing “what goes where”.  This is especially true with Prism projects.  Given you will likely have a dozen or more projects in your solution, it’s pretty important to sort out early on where things belong.
I always try to minimise dependencies between my assemblies; and from time-to-time work-out what would be required to take a module and drop it into another application.  I’m always looking for ways to remove a dependency or decouple.  Even if I don’t have an immediate requirement to do that, as a general rule it’s a good idea.

Namespaces
Picking the right naming convention for your projects and namespaces is pretty important.  I would spend ample time on this before embarking on any serious coding.  Maybe start with a prototype solution and put in some basic modules, a shell, some services, and their accompanying interfaces.  Play around with it and massage it into something you're comfortable with.  I think there is a natural order and organisation for these various projects and components.

Microsoft's recommended namespace convention is:
Company.(Product|Technology)[.Feature][.Subnamespace]

for example, if I were creating an advertising module for Blogger, I would see something like...

Blogger.Advertising.Interfaces
Blogger.Advertising.Views
Blogger.Advertising.ViewModels
Blogger.Advertising.Services
Blogger.Advertising.Services.Interfaces

Microsoft has an excellent guideline for create .Net components at: http://msdn.microsoft.com/en-us/library/ms229026.aspx

Implementation vs Interface
It's important to understand the difference between implementation and interface as it applies to modular development.  An interface is simply a public contract that defines an exposed surface.  Whereas, implementation deals with the deploy or realisation of the interface.  Interfaces do not contain business logic,  simply a definition of what something will look like once it is implemented.
Prism and Unity makes heavy use of interfaces.  Interfaces are mapped to your implementation classes, either in code or in a configuration file.

The following tips may be obvious to some, but I felt it was worth mentioning:

Tip #1 - Do not create strong references to implementation assemblies.
The exception to this are assemblies which comprise your Model.

Tip #2 - Do not place anything in your implementation assemblies which forces other assemblies to create a strong reference.
An example of this are Event classes.  You may have a module which publishes events, presumably to be subscribed to by other modules.  Do not include the Event class in your module assembly, instead place it in your module's interface assembly.  This makes it available to other assemblies though the interface reference.  Another common example are enumerations.

Tip #3 - Do not register your implementation classes in the Module Initialize method.
Registering classes in the Initialize method implies a specific implementation, but not all implementations.  Instead map your classes in a Unity configuration file.

Tip #4 - Do not inject views into regions in the Module Initialize method.
I never understood why anyone would want to do this, as it pretty much ruins any chance of reusing the module.  Instead, delegate view orchestration to another module, layer or layout manager.

In fact, I can't think of good reason to put any code in the Module Initialize method.

These tips address some hidden or covert implementation that commonly occurs in Prism development.

Wednesday, 16 December 2009

Prism Sample: Introduction

I had a request to post some sample code illustrating the use of Model-View-ViewModel pattern, Controllers and DelegateCommands.  This lead to the creation of a sample Prism solution.  An interesting exercise, since it gave me a chance to incorporate many of what I consider to be Prism best practices.
I consider proper solution setup and organisation to be critical in working with Prism.  Mistakes made in this area often come back to haunt you.  There are many ways to organise your projects and code.  What is probably more important is pick a solution structure that everyone can agree with and stick with it.  A lack of agreement or ignorance of architecture can make team development a nightmare.

I intend to write a series of postings detailing out what I consider to be areas of interest, and why I've organised things as I did.
You can download the solution here (408kb).  You will require Visual Studio 2008 SP1.  I've stripped out all XML documentation and PDBs to keep the file size down.

Please let me know if you run into any problems loading and running this solution.

Tuesday, 25 August 2009

Layout Manager for Prism v2

One of the issues you may encounter when working on a Prism project is the management of regions and views within your application. While the RegionManager does an adequate job of managing regions, the orchestration of views and regions is pretty much left up to the developer.

A common approach is to define string constants in a common infrastructure assembly and injecting views into regions using these constants. This gets the job done, but adds rigidity to your application. For applications which require multiple layouts, coordinating regions and views can be a bit tedious.

One common approach I would not recommend is injecting your views in your module's Initialize method.
public void Initialize()
{
    var view = new MyView();
    _Container.RegisterInstance<IMyView>(view);
    _RegionManager.Regions[RegionNames.Shell].Add(view);
}
This violates the encapsulation of the module, restricting the reuse of the module.

On one project, we opted to create a "layout module". The sole purpose of this module was to load a layout UserControl into the Shell region of the main application window, and injecting the views into its own defined regions. Definitely a step in the right direction by decoupling the module views from the regions. The layout module was defined and loaded like any other module, but had to be the last module loaded due to its dependencies. One drawback to this approach was the increasing number of dependencies. The layout module had to reference all the infrastructure assemblies of the views it was required to manage.

Still this solution felt a bit too purpose-built. And other issues quickly arose, such as multiple layout support.  Ideally we were looking for a complete decoupling of regions and views with the ability to dynamically load layouts as required.

We quite liked the idea of using layout views, views whose sole purpose was to define regions, and providing no business or UI logic. But, the source and introduction of these views needed to be dynamic and flexible. The LayoutManager is my first attempt at tackling this issue. Its purpose is to dynamically manage one or more layout configurations for a Prism application.

To compile and run the LayoutManager you will need Visual Studio 2008 SP1 and the latest version of the Composite Application Guidance for WPF and Silverlight - February 2009.

The solution is fairly standard Prism solution, consisting of an Infrastructure, Shell and Modules projects. For the sake of simplicity, I've only included a single Modules project, where normally there would be more.

The LayoutManager maintains a collection of Layout objects, which define layout controls, along with the views that will reside in the layout.

Configuration
The LayoutManager is configured by a LayoutProvider specified in your app.config file.

<section name="layoutProvider" type="Composite.Layout.Configuration.LayoutProviderSection, Composite.Layout"/>

Currently, two providers are available: ConfigLayoutProvider and XamlLayoutProvider. Custom providers can be used by inheriting from LayoutProviderBase.

ConfigLayoutProvider
Defines the LayoutManager in the app.config file as shown below:
<layoutProvider name="ConfigLayoutProvider" type="Composite.Layout.Configuration.ConfigLayoutProvider, Composite.Layout">
    <layoutManager shellName="Shell" >
      <layouts>
        <layout name="FirstLayout" 
              filename="Layouts\FirstLayout.xaml" 
              fullname="First Layout" 
              isDefault="True"
              description="This is the default layout" 
              thumbnailSource="pack://application:,,,/LayoutManager.Infrastructure;component/Resources/Images/layout1.png">
          <views>
            <view typeName="LayoutManager.Infrastructure.IViewA, LayoutManager.Infrastructure" regionName="Left"  />
            <view typeName="LayoutManager.Infrastructure.IViewB, LayoutManager.Infrastructure" regionName="Right" />
            <viewModel typeName="LayoutManager.Infrastructure.IMenuViewModel, LayoutManager.Infrastructure" regionName="Menu"  viewProperty="View"/>
          </views>
        </layout>
        ...
          </layouts>
    </layoutManager>
</layoutProvider>

XamlLayoutProvider
Defines the LayoutManager in Xaml

<layoutProvider name="XamlLayoutProvider"
type="Composite.Layout.Configuration.XamlLayoutProvider, Composite.Layout"
filename="Layouts\LayoutConfiguration.xaml"/>

The source of the Xaml can be specified by type or by filename.
<Layout:LayoutManager xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                      xmlns:Layout="clr-namespace:Composite.Layout;assembly=Composite.Layout"
                      xmlns:Infrastructure="clr-namespace:LayoutManager.Infrastructure;assembly=LayoutManager.Infrastructure"
                      ShellName="Shell">
    <Layout:LayoutManager.Layouts>
        <Layout:Layout x:Name="FirstLayout"
                       Fullname="First Layout"
                       Filename="Layouts\FirstLayout.xaml"
                       Description="This is the default layout"
                       ThumbnailSource="pack://application:,,,/LayoutManager.Infrastructure;component/Resources/Images/layout1.png"
                       IsDefault="True">
            <Layout:Layout.Views>
                <Layout:ViewModel RegionName="Menu"
                                  Type="{x:Type Infrastructure:IMenuViewModel}"
                                  ViewProperty="View" />
                <Layout:View RegionName="Left"
                             Type="{x:Type Infrastructure:IViewA}" />
                <Layout:View RegionName="Right"
                             Type="{x:Type Infrastructure:IViewB}" />
            </Layout:Layout.Views>
        </Layout:Layout>
 ...
    </Layout:LayoutManager.Layouts>
</Layout:LayoutManager>

Each Layout contains a Views collection. The views collection accommodates both Views and ViewModels. The View specifies what view control is to be loaded and what region it is to be placed in. You can also set the visibility for the view. Use the ViewProperty of the ViewModel to specify the name of the property on your ViewModel which holds the View.

The LayoutManager is loaded after all of the modules have initialized. In the Bootstrapper.cs:

protected override void InitializeModules()
{
     base.InitializeModules();
     InitializeLayoutManager();
}

private void InitializeLayoutManager()
{
     var layoutManager = LayoutConfigurationManager.LayoutManager;
     layoutManager.Initialize(Container);
     Container.RegisterInstance(layoutManager, new ContainerControlledLifetimeManager());
     //parameterless LoadLayout loads the default Layout into the Shell
     layoutManager.LoadLayout();
}
The LayoutManager requires use of the Container. Once your layouts have been loaded, call the Initialize method passing in the container.

Once that is done, you can register the LayoutManager in the container making it accessible to other modules.

Loading a Layout
Layouts are loaded by calling the LoadLayout method of the LayoutManager.

LoadLayout() loads the default layout in the Shell

LoadLayout(string layoutName) loads the named layout in the Shell

The MenuViewModel.cs illustrates the use of LoadLayout:
private void LayoutCommandExecute(ILayout layout)
{
var layoutManager = _Container.Resolve<ILayoutManager>(); 
layoutManager.LoadLayout(layout.Name);
}

The basic sequence of loading a layout is:
  1. If there is a current layout, remove it from the RegionManager.
  2. Clear out any controls that were bound to any regions. This step is necessary otherwise you will get an InvalidOperationException ("This control is being associated with a region, but the control is already bound to something else") when you try to reload it in the future. Currently, the LayoutManager only supports ItemsControls, ContentControls and Panels using the RegionManager.RegionName attached property.
  3. Add the new Layout Control to the RegionManager.
  4. Register any Regions contained within the Layout Control.
  5. Load any views associated with the new layout.
Events
There are several events raised by the LayoutManager:

  • LayoutManagerInitializedEvent raised at the end of Initialize (see MenuViewModel.cs for an example of subscribing to this event)
  • LayoutLoadingEvent raised at the beginning of LoadLayout
  • LayoutLoadedEvent raised at the end of LoadLayout
  • LayoutUnloadingEvent raised before the current layout is about to be unloaded
  • LayoutUnloadedEvent raised after the current layout has been unloaded
All of these events are published through the EventAggregator.

Limitations
Currently there are several limitations with the LayoutManager, these are:
LayoutManager currently only supports UserControls as layout controls. There is also the basic assumption that your application main window has a single region defined, where layout controls are injected. Regions must be defined in XAML using the RegionManager.RegionName attached property.

Other Considerations
While the LayoutManager does decouple the regions from the views, it does not entirely do away with string-based region names. Dynamic manipulation of regions and views in code will still rely on region names (see the AddCommandExecute method in MenuViewModel.cs on how to programmatically add layouts). And region name attributes must match actual region names in the Layout control.

A possible approach to addressing this dependency may be to introduce a RegionType enumeration such as Top, Bottom, Left, Right, Center, StatusBar, Menu, Toolbar, etc. In which case, the LayoutManager could resolve these regions regardless of string names.

I have not tested the LayoutManager in all possible scenarios, such as nested layouts and custom RegionAdapters, or with Silverlight.

You can download the LayoutManager source code here.