Composition Containers | Services


You can use modules to encapsulate a set of concerns of your application 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 required by the concerns that the module encapsulates. Figure 1 illustrates typical objects organized by application layer (a module can contain all, or some combination, of the listed components).
Figure 1
Module composition

There are three types of files that comprise a module's deployment unit:
  • Module Web pages. These are the ASP.NET Web pages displayed for your module. (Only business modules contain Web pages.)
  • Module assembly. This is a class library that contains the logic for your module.
  • Web.config file. This is an ASP.NET configuration file. The application block uses this file to identify the module assembly and the location of the Web pages. A module can have a separate Web.config file, or you can add the entries required for a module to the Web site Web.config file.
When your Web client application starts, the Composite Web Application Block locates the Web.config files in the Web site and looks for a configuration section that contains module information. The application block uses this information to load module assemblies. You can specify module information in the Web.config file for the Web site, or you can create a module-specific Web.config file in the module's Web site folder.
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.
Figure 2
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. The Web site Web.config file contains the module information. The Web site does not contain a folder for the module (it does not require one 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 XCopy deploy a module to a Web site. This means you can independently deploy modules in an application.

Module Web Pages

Typically, business modules contain visual representations of data, such as a Web part, Web server control, user control, or Web pages. (A module that does not contain any visual components; instead, it contains services that are used by other modules is known as a foundational module.)

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 within different modules. Composability within a Web page is a technical challenge that is to 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 (user interface) and code. With this model, it is practical to have a designer working on the markup while a programmer writes code. (For information about ASP.NET page models, see ASP.NET Web Page Code Model).

Module Assembly

A module assembly includes the logic for the application concerns encapsulated by the module. This can include the logic for handling user interaction events and presentation. A module assembly can contain classes for services. A service can be specific to the module (the module adds it to the module's composition container) or global to all modules (the module adds it to the root composition container).

Module Loading and the IModuleInitializer Interface

During application startup, the application block discovers all Web.config files located in the Web site folder hierarchy. It uses the information in the files to identify and load module assemblies.
A module initialization class is a class that implements the IModuleInitializer interface. This class contains initialization code that runs when the Composite Web Application Block loads the module. This interface defines two methods, Load and Configure. You implement these methods to perform module initialization tasks, such as registering services or adding site map nodes to the site map.

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

When loading modules, a Composite Web Application Block service (ModuleLoaderService) reflects on the module assembly and looks for a class that implements the IModuleInitializer interface. When 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 key classes and events for module loading.
Figure 3
Module loading and initialization

The following list describes the numbered elements in the preceding figure:
  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 for 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 (for example, services) that you do not want to share with other modules of the application. Your module can access this composition container through the moduleContainer parameter of the Load method.
The Composite Web Application Block provides a base class (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 implementation of this method invokes the AddGlobalServices and AddModuleServices methods. You can override this method to execute custom module initialization code.
  • Configure. The implementation retrieves authorization rules from the configuration information and registers the rules with the IAuthorizationRulesService service. Override this service to use additional configuration information.

View Interfaces and Presenters

If the module contains Web pages (deployed as .aspx files in the Web site), user controls, or a master page, and you choose to implement the View-Presenter pattern, the module assembly will also contain 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.
Is the View-Presenter pattern right for your application?
The application block does not require you to use the View-Presenter pattern. The View-Presenter pattern requires an additional interface definition and presenter class for every view (Web page, master page, or user control).

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 View-Presenter pattern. In this pattern, the presenter contains a reference to the view interface; it does not include a reference to the view implementation (the code-behind class). This means you can use a mock implementation of the view (one that implements the view interface) to test the presenter. To use this class, you derive your presenter from the generic Presenter<T> class, as illustrated in the following code (taken from the Modularity QuickStart).

public class SummaryViewPresenter : Presenter<ISummaryView>
   // 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 common view implementation of this pattern includes code similar to the following in the Page_Load method of a view that has a presenter.

protected void Page_Load(object sender, EventArgs e)
  if (!IsPostBack)

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 in 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.

Alternatively, you can add the module information to the Web site Web.config file. When you do this, the Web site Web.config file acts a centralized module information store, and you cannot XCopy deploy your module (deployment with a centralized module information file requires you to modify the Web site Web.config file at deployment time).

You must place the module information 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.

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

Module Dependencies

You can express module dependencies in the module configuration section. For example, the Modularity QuickStart has three modules, Shell, Navigation and Customers. The Customers module information file contains a Dependencies XML element. This element defines a dependency on the Shell and Navigation modules. This means that the application block will load the Infrastructure module before it loads the Customers module.

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

Composition Containers | Services

Last edited Jan 17, 2008 at 3:08 PM by siacomuzzi, version 3


No comments yet.