Modules

Retired Content

This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies.
This page may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.

By using modules, you can encapsulate particular sets of concerns and independently deploy them to your applications. The Composite Web Application Block distinguishes between two types of modules:

  • Foundational modules. A foundational module does not contain Web pages. The primary purpose of a foundational module is to provide services to the other modules in the application. For example, a foundational module can contain code that provides instrumentation, such as logging.

  • Business modules. A business module can contain any of the application classes that are required by the concerns that the module encapsulates. Figure 1 illustrates typical application objects, organized by application layers (a module can contain all, or some combination, of the listed components).

    Ff709869.a499b4a5-5b99-4ca0-97f2-2a86d5402ac1(en-us,PandP.10).png

    Figure 8

    Module composition

A module can contain three types of files. They are:

  • Module Web pages. These are the ASP.NET Web pages related to the module. (Only business modules contain Web pages.)
  • Module assembly. This is a class library that contains the module’s logic.
  • Web.config file. This is an ASP.NET configuration file. The Composite Web Application Block uses this file to identify the module assembly and the location of the Web pages. A module can either have its own Web.config file or you can add its entries to the Web site’s Web.config file.

Note

Note: This release of the Web Client Software Factory supports Web sites that use the Web Application Project model. If you create your Web site as a Web application project, you have the option to create business modules as sub-Web application projects. When you do this, the module’s deployment unit contains an additional assembly. This assembly contains the compiled code-behind for the module’s Web pages. For more information about Web application projects, see Introduction to Web Application Projects.

When your Web client application starts, the Composite Web Application Block first locates all the Web.config files in the Web site and looks for a configuration section that contains module description information. The application block uses this information to load the module assemblies.

You can create a module that does not include any Web pages. For example, you can create a module that contains only services that are used by other modules. Figure 2 illustrates different deployment examples for various modules.

Ff709869.b5886d18-82a2-4fae-96ad-7bd3d5ea26c1(en-us,PandP.10).png

Figure 9

Module deployment units

The following describes the modules illustrated in the preceding figure:

  • Module A is a foundational module and does not contain any Web pages. It is located in the bin folder. The Web site’s Web.config file contains the module information. The Web site does not contain a folder for the module because the module does not have Web pages or a Web.config file.
  • Module B is a business module. The Web pages reside in a Web site folder specific to Module B. The module folder contains a Web.config file for the module.
  • Module C is a business module and its Web pages reside in a folder specific to that module. The module folder contains a Web.config file for the module.

You can use XCopy to deploy a module on a Web site. This means you can independently deploy modules in an application. For more information about how to XCopy deploy modules to a Web client application, see How to: Deploy Modules.

Module Web Pages

Typically, business modules contain visual representations of data, such as a Web part, Web server controls, user controls, or Web pages.

Note

Note:You can use the Composite Web Application Block to easily create Web client applications that are composed of Web pages that exist in different modules. The application block does not contain explicit support for creating Web pages composed of user interface elements contained in different modules. This ability will be addressed is a future release.

Module Web pages can use either the single-file page model or the ASP.NET code-behind page model. Code-behind pages offer a clean separation of the markup (this is the layout of the user interface) and the code. With this model, it is practical to have a Web designer working on the markup while a programmer writes the code. (For information about ASP.NET page models, see ASP.NET Web Page Code Model.)

Module Assembly

A module assembly contains the logic for the functionality encapsulated by the module. This can include the logic to handle user gestures and the presentation. A module assembly can also contain classes for services. A service can be specific to a module (this means that the module adds it to the module's composition container) or global (this means it resides in the root composition container).

Note

For more information about Composition Containers, see Composition Containers.

Module Loading and the IModuleInitializer Interface

When an application starts, the Composite Web Application Block discovers all the Web.config files located in the Web site’s folder hierarchy. It uses the information in the files to identify and load module assemblies.

A module initialization class contains code that executes when the Composite Web Application Block loads the module. It must implement the IModuleInitializer interface. This interface defines the Load and Configure method. You implement these methods to perform module initialization tasks, such as registering services or adding site map nodes to the site map. The following is the IModuleInitializer interface.

public interface IModuleInitializer
{   
  void Load(CompositionContainer container);
  void Configure(IServiceCollection service, System.Configuration.Configuration moduleConfiguration);
}

When loading modules, the Composite Web Application Block service named ModuleLoaderService reflects on the module assembly to find a class that implements the IModuleInitializer interface. If the module assembly contains a class that implements this interface, the application block dynamically instantiates the class and executes its Load and Configure methods. Figure 3 illustrates the key classes and events for module loading.

Ff709869.320e71a9-4d76-4cc9-86df-da144f1eb530(en-us,PandP.10).png

Figure 10

Module loading and initialization

The following list describes the numbered elements in the Figure 10:

  1. The Global.asax file specifies WebClientApplication as the application class.
  2. ASP.NET calls the Application_Start method of the WebClientApplication class.
  3. The WebModuleEnumeratorService creates information to describe the modules in the Web site. To do this, it calls the WebConfigModuleInfoStoreService service.
  4. The WebConfigModuleInfoStoreService locates all Web.config files in the Web site directory structure.
  5. The WebConfigModuleInfoStoreService service looks for module definition information in the Web.config files.
  6. The WebClientApplication passes the module information to the ModuleLoaderService service.
  7. The ModuleLoaderService loads each module and calls the module for initialization.

When the ModuleLoaderService service loads a module, it creates a new CompositionContainer object for the module. You can use this composition container to store components that you do not want to share with other modules, such as services. Your module can access this composition container through the moduleContainer parameter of the Load method.

The Composite Web Application Block provides a base class named ModuleInitializer that implements the IModuleInitializer interface. You can use this class as the base class for your own module initialization classes. The ModuleInitializer class contains the following virtual methods that you can override:

  • Load. The default implementation of this method invokes the AddGlobalServices and AddModuleServices methods. You can override the Load method to execute custom module initialization code. For example, you can register module and global services.
  • Configure. The default implementation retrieves authorization rules from the configuration information and registers the rules with the IAuthorizationRulesService service. You can override the Configure methods to use other configuration information.

View Interfaces and Presenters

If the module contains Web pages that are deployed on the Web site as .aspx files, user controls, or a master page, and you choose to implement the Model-View-Presenter pattern, the module assembly also contains the following:

  • View interface definitions. The code-behind class of each Web page or user control implements an interface for that view.
  • Presenters. Each view is associated with a presenter. The presenter contains the user interface logic.

Note

Note: Evaluate whether the Model-View-Presenter Pattern is right for your application.
The Composite Web Application Block does not require you to use the Model-View-Presenter pattern. The Model-View-Presenter pattern requires an additional interface definition and presenter class for every view, which can be a Web page, master page, or user control. To learn about the pattern and determine whether it is right for your application, see Model-View-Presenter.

The Composite Web Application Block contains the abstract generic class Presenter<T>, where T is a view interface type. You can use this class to implement the Model-View-Presenter pattern. In this pattern, the presenter contains a reference to the view interface instead of a reference to the view implementation (the code-behind class). This means that you can use a mock implementation of the view that implements the view interface to test the presenter. To use this class, derive the presenter from the generic Presenter<T> class. The following example taken from the Model-View-Presenter with Composite Web Application Block QuickStart illustrates this.

public class ContactDetailPresenter : Presenter<IContactDetailView>
{
   // Presenter implementation
}

The Presenter class declares two virtual methods:

  • OnViewInitialized. This method is invoked by the view the first time it loads.
  • OnViewLoaded. This method is invoked by the view every time it loads.

The typical view implementation of this pattern includes code that is similar to the following example. It shows the Page_Load method of a view that has a presenter.

protected void Page_Load(object sender, EventArgs e)
{
  if (!IsPostBack)
  {
    _presenter.OnViewInitialized();
  }
  _presenter.OnViewLoaded();
}

Web.config File

When you deploy a module, you copy the module assembly to the bin folder and copy the module's Web pages and Web.config file to a folder on the Web site. You must add information to the module’s Web.config file that specifies the name of the module assembly and the location (a folder path relative to the Web site root) of the module's Web pages.

Note

Note: Alternatively, you can add the module information to the Web site’s Web.config file. When you do this, the Web site’s Web.config file acts as a centralized module information store, and you cannot use XCopy to deploy your module. Instead, you must modify the Web site’s Web.config file at deployment time.

You must place the module’s Web.config file in the folder hierarchy of the Web site. The WebModuleEnumerator service recursively searches for Web.config files in the Web site folder hierarchy. This service reads the module configuration information, and the ModuleLoaderService service uses this information to load the module assembly.

The following XML shows the content of the modules configuration section for the Shell and Navigation modules.

<modules>
  <module name="Shell" assemblyName="ModularityQuickstart.Shell" virtualPath="~/"/>
  <module name="Navigation" assemblyName="ModularityQuickstart.Navigation"/>
</modules>

Module Dependencies

You can express module dependencies in the module configuration section. For example, the Modularity QuickStart has three modules named Shell, Navigation, and Customers. The Customers module’s Web.config file contains a <dependencies> XML element. This element defines dependencies on the Shell and Navigation modules. This means that the Composite Web Application block loads the Shell and Navigation modules before it loads the Customers module.

<modules>
  <module name="Customers" assemblyName="ModularityQuickstart.Customers" virtualPath="~/Customers">
    <dependencies>
      <dependency module="Shell" />
      <dependency module="Navigation" />
    </dependencies>
  </module>
</modules>