Skip to content

Part 3: Prism Modules

steve600 edited this page Sep 27, 2015 · 3 revisions

Prism provides support for modular application development and for run-time module management within your application. A modular application is an application that is divided into a set of loosely coupled functional units (named modules) that can be integrated into a larger application. A client module encapsulates a portion of the application's overall functionality and typically represents a set of related concerns. It can include a collection of related components, such as application features, including user interface and business logic, or pieces of application infrastructure, such as application-level services for logging or authenticating users. Modules are independent of one another but can communicate with each other in a loosely coupled fashion. Using a modular application design makes it easier for you to develop, test, deploy, and maintain your application. You can find more information here: https://msdn.microsoft.com/en-us/library/gg405479(v=pandp.40).aspx

Creating a module

To create a new module, we first create a new project. This project is a normal class library:

http://csharp-blog.de/wp-content/uploads/2015/09/PrismMahAppsSample_11.png

That's all and now we can implement our module.

Implementing a module

Each module has a central class that is responsible for initializing the module and integrating its functionality into the application. That class implements the IModule interface. This interface is defined as follows:

public interface IModule
{
    void Initialize();
}

As you can see the IModule interface has a single method, named Initialize, within which you can implement whatever logic is required to initialize and integrate the module's functionality into the application. Depending on the purpose of the module, it can register views into composite user interfaces, make additional services available to the application or extend the application's functionality. The project structure looks like this:

Project-Structure

Because you often want to access the DI-Container or the Region Manager during the initialisation process I have created an appropriate base class.

using Microsoft.Practices.Unity;
using Prism.Modularity;
using Prism.Regions;

namespace PrismMahAppsSample.Infrastructure.Base
{
    public abstract class PrismBaseModule : IModule
    {
        #region Ctor

        /// <summary>
        /// Ctor
        /// </summary>
        /// <param name="unityContainer">The Unity container.</param>
        /// <param name="regionManager">The region manager.</param>
        public PrismBaseModule(IUnityContainer unityContainer, IRegionManager regionManager)
        {
            UnityContainer = unityContainer;
            RegionManager = regionManager;
        }

        #endregion Ctor

        #region Interface IModule

        /// <summary>
        /// Initialize module
        /// </summary>
        public virtual void Initialize()
        {

        }

        #endregion Interface IModule

        #region Properties

        /// <summary>
        /// The Unity container
        /// </summary>
        public IUnityContainer UnityContainer { get; private set; }

        /// <summary>
        /// The region manager
        /// </summary>
        public IRegionManager RegionManager { get; private set; }

        #endregion Properties
    }
}

The following code shows the implementation of a sample module (ModuleA.cs) within the sample application:

public class ModuleA : PrismBaseModule
{
	/// <summary>
	/// Ctor
	/// </summary>
	/// <param name="unityContainer">The Unity container.</param>
	/// <param name="regionManager">The region manager.</param>
	public ModuleA(IUnityContainer unityContainer, IRegionManager regionManager) :
		base(unityContainer, regionManager)
	{
		// Titlebar
		regionManager.RegisterViewWithRegion(RegionNames.RightWindowCommandsRegion, typeof(RightTitlebarCommands));

		// Flyouts
		regionManager.RegisterViewWithRegion(RegionNames.FlyoutRegion, typeof(C1Flyout));
		regionManager.RegisterViewWithRegion(RegionNames.FlyoutRegion, typeof(C2Flyout));

		// Tiles
		regionManager.RegisterViewWithRegion(RegionNames.MainRegion, typeof(HomeTiles));
	}
}

Within this module some views are registered (the views are assigned to the created regions). Depending on the purpose of the module, it would be also possible to make additional services, styles or some other functionality available to the application.

Registering a module

Here you have different possibilities to register the modules. Modules can be registered in the following ways:

  • Directly in code - Modules can be directly registered in the module catalog in the application code. Using this approach, you can use conditional logic to determine which module should be included in your application. Modules added in code are referenced by the application instead of being loaded at run time.
  • Using configuration - Prism can register modules with the module catalog by loading a configuration file. Declaring the modules in configuration allows the modules to be loaded and initialized independent of the application.
  • Using directory inspection - a directory can be specified and inspected to load assemblies in the directory and discover modules.

Here you will find more information about this topic: https://msdn.microsoft.com/en-us/library/ff921068(v=pandp.40).aspx

In the sample application the first approach (directly in code) is used. Therefore the Bootstrapper provides the ConfigureModuleCatalog method:

/// <summary>
/// Configure the module catalog
/// </summary>
protected override void ConfigureModuleCatalog()
{
	ModuleCatalog moduleCatalog = (ModuleCatalog)this.ModuleCatalog;
	// Register ModuleA
	moduleCatalog.AddModule(typeof(ModuleA.ModuleA));
	// Register ModuleB
	moduleCatalog.AddModule(typeof(ModuleB.ModuleB));
}

So you're done with the creation of the module and the main window should be dynamically expanded by the modules (this means you should see the registered views within the MainWindow):

http://csharp-blog.de/wp-content/uploads/2015/09/PrismMahAppsSample_13.png