An adapter defines a set of characteristics for a particular requesting device. Suppose you are designing a new device based on a Palm Pilot, and you want to make hardware modifications and enhancements. To develop ASP.NET mobile Web pages for your new device, you require a customized device adapter to make full use of the enhanced hardware feature set.
Inside the Web.config file, you map each of your mobile controls to the customized adapter that you created for it. Not only can you specify individual device adapter sets for device-specific customization, but you can customize further by inheriting one device adapter set from another, thus customizing behavior for specific device/control combinations.
To map mobile controls and device adapters, declaratively configure them in the <mobileControls> section of the <system.web> element. You can do so in the Web.config file for changes to be isolated to the given application. Server-wide settings are located in the Machine.config file for the .NET Framework installation under your Microsoft Windows directory. In the configuration files you can specify the individual adapter sets that are chosen at run time.
If a <mobileControls> section does not currently exist in your Web.config file, you can add one anywhere as a child of the <system.web> element.
Declaring an Adapter Set
A device adapter set is the mapping mechanism within the Web.config file. For each control that uses a customized device adapter, you must include the following information within the device adapter set:
a predicate class
a predicate method
a page adapter
the control's name and associated device adapter
To add a device adapter set to the Web.config file of your application, you must declare a device adapter set using a <device> element in the <mobileControls> section of the Web.config file, as shown in the following code example.
<?xml version="1.0" encoding="utf-8"?> <configuration> <system.web> <!-- Other settings previously specified reside here. --> <mobileControls> <device name="myDeviceAdapter" predicateClass="fullyQualifiedAdapterClass" predicateMethod="specificMethodToInvoke" pageAdapter="fullyQualifiedPageAdapter"> <control name="fullyQualifiedControl" adapter="fullyQualifiedPageAdapter"/> <!-- Add additional control names here. --> </device> </mobileControls> </system.web> </configuration>
Defining Device Attributes
As shown in the previous code example, you must include in each adapter set the attributes that are defined in the following table.
Uniquely identifies the device adapter set.
(Optional) Indicates that the current device adapter set inherits from another set, which is identified by name. The parent device adapter set can reside anywhere in the same <mobileControls> section of the same Web.config file or it can reside in a parent Web.config file.
Point to a static method that is called to evaluate whether the adapter set is appropriate for the current device. The method takes a single parameter of type HttpContext and returns a Boolean value indicating whether the adapter set applies. The method can examine capabilities of the target device using the Browser property of the provided HttpContext object, which returns a MobileCapabilities object.
Identifies the page adapter class for the device set, a type that implements the IPageAdapter interface.
If a <device> section includes the InheritsFrom attribute, you do not need to declare the PredicateClass, PredicateMethod, or PageAdapter attributes. Instead, your device adapter set can inherit these from the parent device adapter set definition.
Although these attributes are not required, you can define them if it is appropriate for your application.
You can place any number of <control> elements within an adapter set. Each provides a specific control adapter mapping (a class that implements IControlAdapter). A <control> element has two attributes: a name attribute that specifies the class of the control to be mapped, and an adapter attribute that specifies the class of the control adapter.
Although there is a one-to-one mapping between control and adapter, it is not necessary to write a separate control adapter class for every control/device combination. In general, if a new mobile control uses inheritance or simple composition and does not require customized output, it does not require a control adapter. Consider the following alternatives:
An adapter or set of adapters might apply to a general type of device. For example, all HTML 3.2 devices might have the same set of device adapters. However, for some controls, there might be more specialized device adapters for more specific devices. For example, you might want to write a Calendar control device adapter that is specialized for the Pocket PC.
A control adapter might be associated with a control base class, rather than with individual controls. For example, a single adapter might be sufficient to render all validator controls inheriting from the BaseValidator class.
It is possible to write fully functional mobile controls that do not use device adapters. However, it is strongly recommended that developers write device adapters where appropriate, because much of the flexibility of the architecture is lost if any single control on the page does not use device adapters.
New controls created by extending existing controls — user controls, composite controls, and controls that are created through inheritance and that contain existing controls — do not need device adapters because the adapters of the contained controls are used.
Understanding the Device Adapter Selection Process
The following process describes how a device adapter set for a page is selected:
ASP.NET iterates through the collection of device adapter sets, as defined by <device> sections in the Web.config file. The Web.config file closest to the requested page is examined first, then each successive Web.config file located higher in the configuration hierarchy. The Machine.config file is examined last.
The associated predicate for each device adapter set is evaluated using the predicateClass and predicateMethod attributes.
Each predicate uses the provided HttpContext object to examine the device capabilities of the target device, and returns true or false, indicating whether the device adapter sets are applicable.
As soon as any predicate returns true, that device adapter set is considered selected. At this point, the system uses the pageAdapter attribute of the <device> element to determine which class to create an instance of to create the adapter.
If none of the predicates in the Web.config file return true, the process is repeated for the device adapter sets in the parent directory's Web.config file.
For each control, the page is called to provide a device adapter for the specified control type. ASP.NET uses the following steps to choose the appropriate control adapter:
The device adapter set used is the same one chosen for the page's device adapter.
If the device adapter set contains a <control> element that directly maps the control class to a device adapter class, an instance of the specified adapter class is created.
If the device adapter set cannot be directly mapped, a new instance of the base class for the control is created.
This process is repeated until the base class Control is reached. If at any time a direct mapping is found, a new instance of the specified device adapter class is created.
If a mapping has still not been found, and the device adapter set inherits from another adapter set, the steps for adapter selection are repeated for the parent adapter set. This continues up the hierarchy of adapter sets until a mapping is found.
The results of the lookup are cached, so the specified lookup needs to be performed only for the first relevant control once. The behavior described above is preserved.