Monday, May 14, 2012

Catel creates a perfect combination with PRISM

Introduction


I have been very "busy" watching the final of the baseball season. The past week, my team was eliminated on quarterfinals, so now I have  time to write.

Talking about competitions, I just remembered the history about how Catel.Extensions.Prism was born.

You may think that Catel and PRISM are competitors. The fact is that most people think that they are competitors. Actually I had the same idea when I discovered Catel, some time after I have been written LoB systems with PRISM. If you read the highlights, is not hard to notice the "isolated" features, mainly if you are looking for guidance or a stating point for the MVVM pattern implementation.

Catel has an out of the box view model base implementation, plus services, with full support for validation, property change notification and commanding. From my point of view Catel beats PRISM as MVVM pattern implementation guidance, with a cleaner approach on separation of views and view models and better testability. The fact is that PRISM has no a ViewModelBase implementation.

So, at some point, I considered removing all the PRISM references from my projects. But then I would loose many PRISM features, that allow you manage the modularity and view composition, that are hard to leave behind when you actually used it. I heard some people talking about the PRISM approach saying that it is a bit complex or strange. They provide example terms like bootstrapper, shell, module catalog, modules, region manager, etc. But the truth is that PRISM provides a good scaffold for modular application development.

That was the moment when we thought that they should be work together and that was the reason for we wrote Catel.Extensions.Prism and it is now available via NuGet.

User Interface Composition with Catel.Extensions.Prism


Starting with Catel 3.1 the Prism extension is available. PRISM includes a feature named "User Interface Composition". Basically it allows building a mosaic like application by loading multiple views that comes from different modules into an active region exposed by a control, also know as the shell.



The PRISM UI composition approach requires that you reference the view or the view type in order to associate it with one region. That is correct if you are coding a module class for instance, but all this is about view models.

In order to understand the code samples you need to read more about UIVisualizerService, and the way it can resolve a view from an instance of a view model. Now you are able to create a composite user interface without actually referencing any view from a view model class.

Making the region manager available

First of all, you must make available the region manager on the instance of ServiceLocator (IoC container of Catel). A PRISM based application uses MEF or Unity as primary IoC container. Therefore, you must synchronize this container with the Catel one, overriding the ConfigureContainer method of the application bootstrapper class, using the following code:

protected override void ConfigureContainer()
{
 base.ConfigureContainer();
 if (ServiceLocator.Instance.IsExternalContainerSupported(this.Container))
 {
  ServiceLocator.Instance.RegisterExternalContainer(this.Container);
 }
}

Activating a view into a specific region

To activate a view into a specific region from inside a view model, use the following code:
 var viewModel = new EmployeeViewModel();
 var uiVisualizerService = GetService<IUIVisualizerService>();
 uiVisualizerService.Activate(viewModel, "MainRegion");

Deactivating a view

To deactivate a view, use the following code:
uiVisualizerService.Deactivate(viewModel);

If you keep your view model alive (see: Keeping view models alive), you can reactivate a deactivated the view using Activate method without specify the region name. 

Deactivating a view automatically

If you close the view model using SaveAndCloseViewModel or CancelAndCloseViewModel or CloseViewModel methods, the view that belongs to this view model will be automatically deactivated from the region where it was activated.

Conclusions   

Nowadays, I enjoy write applications with Catel and PRISM, or with PRISM and Catel, the order doesn't matter. I will just give you one advice, try out this extension and like a host of a popular TV show that I know say, "draw your own conclusions by yourself" ;)