Table of contents
- Introduction
- Initializing Prism Applications
- Manage dependencies between components
- Modular Application Development
- Implementation of the MVVM pattern
- Advanced MVVM scripts
- Creating user interface
- User Interface Design Recommendations
- Navigation
- View-Based Navigation (View-Based Navigation)
- The interaction between loosely coupled components
This chapter explains what you need to do to download the Prism application. The Prism application requires registering and configuring components at launch time — this process is known as bootstrapping.
What is a bootloader (Bootstrapper)
The loader is the class responsible for initializing an application created using the Prism library. When using the loader, you get more control over how the components of the Prism library are created and connected when you start your application. The Prism library includes an abstract base loader class that can be specialized for use with any container. Many of the methods in the boot loader classes are virtual. You can override these methods to provide your own implementation.

The Prism library provides some additional base classes inherited from the
Bootstrapper class, with default implementations that are suitable for most applications. It remains only to add the implementation implementation creation and initialization of the shell.
')
Dependency injection
Applications built using the Prism library rely on the dependency injection mechanism provided by the container. The library provides assemblies that work with the Unity Application Block (Unity) or Managed Extensibility Framework (MEF), and allows the use of other DI containers. Part of the bootstrap process is configuring the container and registering the necessary types in it.
The Prism library includes the
UnityBootstrapper and
MefBootstrapper classes , which implement most of the functionality required for using both Unity and MEF as a DI container. In addition to the steps shown in the previous illustration, each loader adds some steps specific to the container used.
Shell creation
In a traditional WPF application, the starting URI is defined in the App.xaml file, which determines when the application loads which window is the root. In the Silverlight application, the RootVisual property of the application is set in the code behind the App.xaml file. In an application created using the Prism library, the loader must create a shell or main window itself. This is due to the fact that the shell relies on services, such as the region manager, which must be registered before the shell is created and displayed.
Key decisions
After you decide to use the Prism library in your application, you will need to consider the following:
- You will have to decide whether you will use a MEF, Unity, or other DI container in your application. This will determine which loader class you should use, or whether you will need to create your own loader for the selected container.
- You should think about the specialized services that you will use in your application. They must also be registered in the container.
- Determine whether the built-in journaling service meets your needs, or whether you will need to create and register another service.
- Determine how the modules will be detected by the application: through explicit declarations in the code, through attributes on the modules detected after scanning the file system directory, through the configuration file, or through XAML.
Next, we consider these points in detail.
Basic scripts
Creating a boot sequence is an important part of creating your Prism application. This section describes how to create a boot loader and configure it to create a shell, configure a DI container and application-level services, and how to load and initialize modules.
Creating a loader for your application
If you choose Unity or MEF, then creating a bootloader will be relatively easy. You must create a class inherited from
MefBootstrapper or
UnityBootstrapper and implement the
CreateShell method. Additionally, you can override the
InitializeShell method to specifically initialize the shell class.
Implementing the CreateShell Method
The
CreateShell method allows the developer to define a high-level window for the Prism application. The shell is usually
MainWindow or
MainPage , in the case of Silverlight. Implement this method by returning an instance of the shell class of your application. In the Prism application, you can either create a shell object or obtain it from a container, depending on the requirements of your application.
An example of using a
ServiceLocator to get a shell object is given in the following code example.
protected override DependencyObject CreateShell() { return ServiceLocator.Current.GetInstance<Shell>(); }
The note
You will often see that ServiceLocator is used instead of a specific dependency injection container to get type instances. ServiceLocator is implemented in such a way that it redirects calls to a container, so its use is a good choice for writing code that does not depend on the selected container. You can also reference and use the container directly, and not the ServiceLocator .
Implementing the InitializeShell Method
After you have created a shell, you may need to perform initialization steps to ensure that the shell is ready for display. Depending on whether you are writing a WPF or Silverlight application, the implementation of the
InitializeShell method may vary. For Silverlight applications, you must install the shell as the visual root of the application, as shown below.
protected override void InitializeShell() { Application.Current.RootVisual = Shell; }
For WPF applications, you need to create an application shell object and set it as the main application window (taken from Modularity QuickStarts for WPF).
protected override void InitializeShell() { Application.Current.MainWindow = Shell; Application.Current.MainWindow.Show(); }
The base implementation
InitializeShell does nothing. It is safe not to call the base class implementation.
Creating and configuring a module directory
If you are creating a modular application, then you will need to create and configure a directory of modules. Prism uses a specific instance of
IModuleCatalog to track which modules are available to an application, which modules may need to be loaded and where the modules are located.
The
Bootstrapper class provides a protected property,
ModuleCatalog, for referencing a directory, as well as the basic implementation of the
CreateModuleCatalog virtual method. The base implementation returns a new
ModuleCatalog instance. However, this method can be overridden to provide another instance of the module directory, as shown in the following code example from the
QuickStartBootstrapper in Modularity with MEF for Silverlight QuickStart.
protected override IModuleCatalog CreateModuleCatalog() {
In both the
UnityBootstrapper and
MefBootstrapper classes, the
Run method calls the
CreateModuleCatalog method and then sets the
ModuleCatalog property of the class using the returned value. If you override this method, you do not need to call the base class implementation because you are replacing the provided functionality. For more information about modularity, see Chapter 4, “Modular Application Development.”
Creating and configuring a DI container
Containers play a key role in an application created using the Prism library. Both the Prism library and the applications created using it depend on the DI container needed to implement the required dependencies and services. During the container configuration phase, some basic services are registered there. In addition to these services, you may have your own specialized services that provide additional functionality that affects the composition process.
Basic Services
The following table shows the basic non-specialized services of the Prism library.
Interface. | Description. |
---|
IModuleManager , module manager | Defines an interface for a service that receives and initializes application modules. |
IModuleCatalog , module catalog | Contains metadata about the modules in the application. The Prism library provides several different directories. |
IModuleInitializer , module initializer | Initializes the modules. |
IRegionManager , Regional Manager | Registers and receives regions that are visual markup containers. |
IEventAggregator , event aggregator | A collection of events loosely coupled between the publisher and the subscriber. |
Iloggerfacade | A wrapper for the journaling mechanism. Thus, you can choose your own journaling mechanism. The Stock Trader Reference Implementation (Stock Trader RI) uses the Enterprise Library Logging Application Block, through the EnterpriseLibraryLoggerAdapter class, as an example of how you can use your own logger. The logging service is registered in the container in the Run method of the loader using the value returned by the CreateLogger method. Registering another logger in the container will not work; instead, override the CreateLogger method in the loader. |
IServiceLocator | Allows the Prism library to access the container. It may be useful if you want to customize or expand the library. |
Specialized Services
The following table lists the specialized services used in Stock Trader RI. They can be used as an example to understand what services can be in your application.
Service in Stock Trader RI. | Description. |
---|
IMarketFeedService | Provides (fake) real-time market data. PositionSummaryPresentationModel updates the position screen based on notifications received from this service. |
IMarketHistoryService | Provides a history of market data used to display trend lines for a selected stock. |
IAccountPositionService | Provides a list of funds in a portfolio. |
IOrdersService | Contains sent purchase / sale orders. |
INewsFeedService | Provides a list of news items for the selected fund. |
IWatchListService | Determines when a new item is added to the list of monitored items. |
There are two boots of derivatives derived from the Bootstrapper class, available in Prism, UnityBootstrapper and MefBootstrapper. Creating and configuring other containers involves similar steps, implemented a little differently.
Creating and configuring a container in UnityBootstrapper
The
UnityBootstrapper class's
CreateContainer method simply creates and returns a new instance of
UnityContainer . In most cases, this functionality does not need to be changed. However, the method is virtual, providing the necessary flexibility. After the container is created, it should probably be configured accordingly. The implementation of the
ConfigureContainer in
UnityBootstrapper registers the underlying services of Prism by default, as shown below.
The note
Similarly, the module registers its services in the Initialize method.
protected virtual void ConfigureContainer() { ... if (useDefaultConfiguration) { RegisterTypeIfMissing(typeof(IServiceLocator), typeof(UnityServiceLocatorAdapter), true); RegisterTypeIfMissing(typeof(IModuleInitializer), typeof(ModuleInitializer), true); RegisterTypeIfMissing(typeof(IModuleManager), typeof(ModuleManager), true); RegisterTypeIfMissing(typeof(RegionAdapterMappings), typeof(RegionAdapterMappings), true); RegisterTypeIfMissing(typeof(IRegionManager), typeof(RegionManager), true); RegisterTypeIfMissing(typeof(IEventAggregator), typeof(EventAggregator), true); RegisterTypeIfMissing(typeof(IRegionViewRegistry), typeof(RegionViewRegistry), true); RegisterTypeIfMissing(typeof(IRegionBehaviorFactory), typeof(RegionBehaviorFactory), true); } }
The
RegisterTypeIfMissing method of the loader determines whether the service has already been registered, which prevents them from re-registering. This allows you to override the default registration via configuration. You can also turn off the registration of any services by default, to do this, use the overloaded method
Bootstrapper.Run , passing it
false . You can also override the
ConfigureContainer method and disable services that you do not want to use, such as an event aggregator.
The note
If you disable the default registration, you will need to manually register the necessary services.
To extend the default
ConfigureContainer behavior, simply add an override to your application's loader and additionally call the base implementation, as shown in the following code from the
QuickStartBootstrapper from Modularity for WPF (with Unity) QuickStart. This implementation calls the base class implementation, registers the
ModuleTracker type as a specific
IModuleTracker implementation, and registers the
callbackLogger as a singleton to the
CallbackLogger instance that comes with Unity.
protected override void ConfigureContainer() { base.ConfigureContainer(); this.RegisterTypeIfMissing(typeof(IModuleTracker), typeof(ModuleTracker), true); this.Container.RegisterInstance<CallbackLogger>(this.callbackLogger); }
Creating and configuring containers in MefBootstrapper
The
CreateContainer method of the
MefBootstrapper class does several things. First, it creates
AssemblyCatalog and
CatalogExportProvider .
CatalogExportProvider allows the
MefExtensions assembly
to provide a default export for Prism types and also allows you to override the default type registration.
CreateContainer then creates and returns a new
CompositionContainer instance using the
CatalogExportProvider . In most cases, you will not need to change this functionality. However, the method is virtual, providing the necessary flexibility.
The note
In Silverlight, due to security restrictions, you cannot get an assembly using the type. Instead, Prism uses another method that uses the Assembly.GetCallingAssembly method.
After the container is created, it must be configured for your application. The implementation of the
ConfigureContainer in
MefBootstrapper registers many basic Prism services by default, as shown in the following code example. If you override this method, consider whether you should call the base class implementation to register the Prism base services, or you will provide them in your implementation.
protected virtual void ConfigureContainer() { this.RegisterBootstrapperProvidedTypes(); } protected virtual void RegisterBootstrapperProvidedTypes() { this.Container.ComposeExportedValue<ILoggerFacade>(this.Logger); this.Container.ComposeExportedValue<IModuleCatalog>(this.ModuleCatalog); this.Container.ComposeExportedValue<IServiceLocator>(new MefServiceLocatorAdapter(this.Container)); this.Container.ComposeExportedValue<AggregateCatalog>(this.AggregateCatalog); }
The note
In MefBootstrapper, basic Prism services are added to the container as singletones, so they can be obtained through the container throughout the application.
In addition to providing the
CreateContainer and
ConfigureContainer methods,
MefBootstrapper also provides two methods for creating and configuring
AggregateCatalog used by MEF. The
CreateAggregateCatalog method simply creates and returns an
AggregateCatalog object. Like other methods in
MefBootstrapper ,
CreateAggregateCatalog is virtual and can be overridden if necessary. The
ConfigureAggregateCatalog method allows you to add type registrations to
AggregateCatalog forcibly. For example,
QuickStartBootstrapper from the Modularity with MEF for Silverlight QuickStart explicitly adds
ModuleA and
ModuleC to
AggregateCatalog , as shown below.
protected override void ConfigureAggregateCatalog() { base.ConfigureAggregateCatalog();
Additional Information
For more information about MEF,
AggregateCatalog , and
AssemblyCatalog , see "Managed Extensibility Framework Overview" on MSDN:
http://msdn.microsoft.com/en-us/library/dd460648.aspx .