Skip to main content

Bootstrapper for Prism Application

Introduction

This article explains to create a bootstrapper for your prism application using WPF, it contains a little explanation about bootstrapper such as definition, how it works, etc. before going forward lets understanding about bootstrapper definition, how it works and relation with prism.

What is Bootstrapper

A bootstrapper is a class that is responsible for the initialization of an application built using the Prism Library. By using a bootstrapper, you have more control over how the Prism Library components are wired up to your application.

The Prism Library includes a default abstract Bootstrapper base class that can be specialized for use with any container. Many of the methods on the bootstrapper classes are virtual methods. You can override these methods as appropriate in your own custom bootstrapper implementation.

Getting Started

Creating bootstrapper for prism application easy very easy, just need to follow some steps to create and use bootstrapper. Here I have divided the bootstrapper creation process into 8 steps listed below.

  1. Create and Configure a module catalog
  2. Create and Configure the container
  3. Configure default region adapter mappings
  4. Configure default region behaviors.
  5. Register framework exception types.
  6. Create the Shells.
  7. Initialize the shell
  8. Initialize the module

Step-1: Creating and Configuring the Module Catalog

If you are building a module application, you will need to create and configure a module catalog. Prism uses a concrete IModuleCatalog instance to keep track of what modules are available to the application, which modules may need to be downloaded, and where the modules reside.

The Bootstrapper provides a protected ModuleCatalog property to reference the catalog as well as a base implementation of the virtual CreateModuleCatalog method. The base implementation returns a new ModuleCatalog; however, this method can be overridden to provide a different IModuleCatalog instance instead, as shown in the following code from the QuickStartBootstrapper in the Modularity with MEF for Silverlight QuickStart.

 protected override IModuleCatalog CreateModuleCatalog()  
 {  
   // When using MEF, the existing Prism ModuleCatalog is still  
   // the place to configure modules via configuration files.  
   return ModuleCatalog.CreateFromXaml(new Uri(  
                   "/ModularityWithMef.Silverlight;component/ModulesCatalog.xaml",  
                   UriKind.Relative));  
 }  

In both the UnityBootstrapper and MefBootstrapper classes, the Run method calls the CreateModuleCatalog method and then sets the class's ModuleCatalog property using the returned value. If you override this method, it is not necessary to call the base class's implementation because you will replace the provided functionality.

Step-2: Creating and Configuring the Container

Containers play a key role in an application created with the Prism Library. Both the Prism Library and the applications built on top of it depend on a container for injecting required dependencies and services. During the container configuration phase, several core services are registered. In addition to these core services, you may have application-specific services that provide additional functionality as it relates to composition.

  1. Core Services

    The following details lists the core non-application specific services in the Prism Library.

    • IModuleManager: Defines the interface for the service that will retrieve and initialize the application's modules.
    • IModuleCatalog: Contains the metadata about the modules in the application. The Prism Library provides several different catalogs.
    • IModuleInitializer Initializes the modules.
    • IRegionManager: Registers and retrieves regions, which are visual containers for layout.
    • IEventAggregator: A collection of events that is loosely coupled between the publisher and the subscriber.
    • ILoggerFacade:

      A wrapper for a logging mechanism, so you can choose your own logging mechanism. The Stock Trader Reference Implementation (Stock Trader RI) uses the Enterprise Library Logging Application Block, via the EnterpriseLibraryLoggerAdapter class, as an example of how you can use your own logger. The logging service is registered with the container by the bootstrapper's Run method, using the value returned by the CreateLogger method. Registering another logger with the container will not work; instead override the CreateLogger method on the bootstrapper.

    • IServiceLocator: Allows the Prism Library to access the container. If you want to customize or extend the library, this may be useful.

  2. Application-Specific Services

    The following details lists the application-specific services used in the Stock Trader RI. This can be used as an example to understand the types of services your application may provide.

    • IMarketFeedService: Provides real-time (mocked) market data. The PositionSummaryPresentationModel updates the position screen based on notifications it receives from this service.
    • IMarketHistoryService: Provides historical market data used for displaying the trend line for the selected fund.
    • IAccountPositionService: Provides the list of funds in the portfolio.
    • IOrdersService: Persists submitted buy/sell orders.
    • INewsFeedService: Provides a list of news items for the selected fund.
    • IWatchListService: Handles when new watch items are added to the watch list.

Step-3: Creating and Configuring the Container in the UnityBootstrapper

The UnityBootstrapper class's CreateContainer method simply creates and returns a new instance of a UnityContainer. In most cases, you will not need to change this functionality; however, the method is virtual, thereby allowing that flexibility.

After the container is created, it probably needs to be configured for your application. The ConfigureContainer implementation in the UnityBootstrapper registers a number of core Prism services by default, as shown here.

An example of this is when a module registers module-level services in its 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 bootstrapper's RegisterTypeIfMissing method determines whether a service has already been registered—it will not register it twice. This allows you to override the default registration through configuration. You can also turn off registering any services by default; to do this, use the overloaded Bootstrapper.Run method passing in false. You can also override the ConfigureContainer method and disable services that you do not want to use, such as the event aggregator.

If you turn off the default registration, you will need to manually register required services. To extend the default behavior of ConfigureContainer, simply add an override to your application's bootstrapper and optionally call the base implementation, as shown in the following code from the QuickStartBootstrapper from the Modularity for WPF (with Unity) QuickStart. This implementation calls the base class's implementation, registers the ModuleTracker type as the concrete implementation of IModuleTracker, and registers the callbackLogger as a singleton instance of CallbackLogger with Unity.

 protected override void ConfigureContainer()  
 {  
   base.ConfigureContainer();  
    this.RegisterTypeIfMissing(typeof(IModuleTracker), typeof(ModuleTracker), true);  
   this.Container.RegisterInstance<CallbackLogger>(this.callbackLogger);  
 }  

Step-4: Creating and Configuring the Container in the MefBootstrapper

The MefBootstrapper class's CreateContainer method does several things. First, it creates an AssemblyCatalog and a CatalogExportProvider. The CatalogExportProvider allows the MefExtensions assembly to provide default exports for a number of Prism types and still allows you to override the default type registration. Then CreateContainer creates and returns a new instance of a CompositionContainer using the CatalogExportProvider. In most cases, you will not need to change this functionality; however, the method is virtual, thereby allowing that flexibility.

After the container is created, it needs to be configured for your application. The ConfigureContainer implementation in the MefBootstrapper registers a number of core Prism services by default, as shown in the following code example. If you override this method, consider carefully whether you should invoke the base class's implementation to register the core Prism services, or if you will provide these services 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);  
 }  

In the MefBootstrapper, the core services of Prism are added to the container as singletons so they can be located through the container throughout the application. In addition to providing the CreateContainer and ConfigureContainer methods, the MefBootstrapper also provides two methods to create and configure the AggregateCatalog used by MEF. The CreateAggregateCatalog method simply creates and returns an AggregateCatalog object. Like the other methods in the MefBootstrapper, CreateAggregateCatalog is virtual and can be overridden if necessary.

The ConfigureAggregateCatalog method allows you to add type registrations to the AggregateCatalog imperatively. For example, the QuickStartBootstrapper from the Modularity with MEF for Silverlight QuickStart explicitly adds ModuleA and ModuleC to the AggregateCatalog, as shown here.

 protected override void ConfigureAggregateCatalog()  
 {  
   base.ConfigureAggregateCatalog();  
   // Add this assembly to export ModuleTracker  
   this.AggregateCatalog.Catalogs.Add(  
          new AssemblyCatalog(typeof(QuickStartBootstrapper).Assembly));  
   // Module A is referenced in in the project and directly in code.  
   this.AggregateCatalog.Catalogs.Add(  
          new AssemblyCatalog(typeof(ModuleA.ModuleA).Assembly));  
   // Module C is referenced in in the project and directly in code.  
   this.AggregateCatalog.Catalogs.Add(  
          new AssemblyCatalog(typeof(ModuleC.ModuleC).Assembly));  
 }  

Step-5: Creating the Shell

In a traditional Windows Presentation Foundation (WPF) application, a startup Uniform Resource Identifier (URI) is specified in the App.xaml file that launches the main window. In an application created with the Prism Library, it is the bootstrapper's responsibility to create the shell or the main window. This is because the shell relies on services, such as the Region Manager, that need to be registered before the shell can be displayed.

The CreateShell method allows a developer to specify the top-level window for a Prism application. The shell is usually the MainWindow or MainPage. Implement this method by returning an instance of your application's shell class. In a Prism application, you can create the shell object, or resolve it from the container, depending on your application's requirements.

An example of using the ServiceLocator to resolve the shell object is shown in the following code example.

 protected override DependencyObject CreateShell()  
 {  
   return ServiceLocator.Current.GetInstance<Shell>();  
 }  

You will often see the ServiceLocator being used to resolve instances of types instead of the specific dependency injection container. The ServiceLocator is implemented by calling the container, so it makes a good choice for container agnostic code. You can also directly reference and use the container instead of the ServiceLocator.

Step-6: InitializeShell Method

After you create a shell, you may need to run initialization steps to ensure that the shell is ready to be displayed. Depending on whether you are writing a WPF or Silverlight application, the InitializeShell method implementations will vary. For Silverlight applications, you will set the shell as the application's visual root, as shown here.

 protected override void InitializeShell()  
 {  
   Application.Current.RootVisual = Shell;  
 }  

For WPF applications, you will create the shell application object and set it as the application's main window, as shown here (from the Modularity QuickStarts for WPF).

 protected override void InitializeShell()  
 {  
   Application.Current.MainWindow = Shell;  
   Application.Current.MainWindow.Show();  
 }  

The base implementation of InitializeShell does nothing. It is safe to not call the base class implementation.

Related Articles

  1. Creating Application in Prism

Summary

In the above discussion, we see how to create Bootstrapper in WPF Prism Application using c# language. Hope you have understood the discussion if any query please have a comment in this article

Thanks

Comments

Popular posts from this blog

Generate QR Code in WPF

Introduction In my previous two blogs, we have discussed how to display generate and display various barcodes on the web page. In this blog, we are going to demonstrate how to Generate QR Code in the WPF application. Getting Started Here in the demonstration Generate QR Code in WPF , will generate QR code using third party library as there is not inbuilt library provided by Microsoft to generate QR code and will display in WPF image control, In the below, we will see the steps to display QR Code. As I mentioned in the above paragraph that there is no inbuild library provided by Microsoft to generate QR code, I have taken the help of the ZXing library which is a third party free library and available Nuget. This library provides various options to generate barcodes and QR Code from the user-friendly text. Generate QR Code in WPF Here are the steps to generate QR code and let's follow the steps to complete demonstrations. Demonstration:- Generate QR Code Open visual stud

Creating Application in Prism

Introduction This article explains an illustration of creating a windows application in Prism Library(WPF Prism). The solution includes recommended practices and techniques and is the basis for the procedures in Prism. This illustration created in the Visual Studio 2012, It can also developed in the visual studio 2008 and 2010, because wpf supports from .net framework 3.5 to latest version. Microsoft.Practices.Prism.dll. This assembly contains the implementation of the Prism Library core components such as modularity, logging services, communication services, and definitions for several core interfaces. It also contains the implementation of Prism Library components that target WPF applications, including commands, regions, and events. Microsoft.Practices.Prism.UnityExtensions.dll. This assembly contains base and utility classes you can reuse in applications built with the Prism Library that consume the Unity Application Block. For example, it contains a bootstrapper base class

WPF Binding

Introduction This blog describes WPF Binding and the measure elements exist with binding with XAML example in XAML and code-behind. Getting Started Binding helps in WPF to flow data from one object to another object, the object which fetches data is called source and the object which receives the data is called target. The Object a be a UI control or object of a class that means in binding you can bind a property of a class and property of another control to WPF UI controls as well. XAML Example <TextBox x:Name="sourceText" Grid.Row="0" /> <Button Grid.Row="1" Content="{Binding ElementName=sourceText, Path=Text}"/> Code Example Button btn=new Button(); Binding binding = new Binding("Text"); binding.Source = sourceText; btn.SetBinding(Button.ContentProperty, binding); In WPF binding has some measure properties or elements that we are using while developing application or projects, here we are going to d