The ASP.NET 2.0 Provider Model

Most applications need to save and retrieve data to and from persistent media. In ASP.NET, a good example of this kind of persistent data is the session state. Developers write applications that use the session state, but neither end-users nor developers really know where or how the session state is held. ASP.NET developers can control the location of the data to some extent, however, by instructing the ASP.NET runtime to save and retrieve the state from local memory, memory of an external process, or even a SQL Server table.

In spite of the various storage options, the programming interface to the session state remains the same (the web.config file). For example, to move the session state from the local memory (the ASP.NET cache) to a SQL Server table, all you do is modify an attribute in the web.config file. You don't need to recompile or even touch the code. This article reveals the magic behind this behavior, which the ASP.NET 2.0 provider model provides.

ASP.NET 1.x Session State Module

When the session state HTTP module needs to retrieve the session state for an ongoing request, it reads the information in the web.config file and figures out which state manager component is in charge of providing the session state. A state manager is an ASP.NET internal component that knows how to retrieve the collection of session state items for a particular request. State managers differentiate themselves by the storage media they use to persist data, yet these .NET classes all implement the same interface, IStateClientManager.

The session state module figures out the name of a state manager class based on the session mode attribute in the web.config file. Next, it uses a switch statement to instantiate the right component, as in the following pseudo-code:

All three state client manager classes implement the same interface, thus providing the same functionality to the HTTP module.

Although this model is effective and fully functional, it hardly is extensible. What if you want to store your session state in, say, an Oracle database?

Moving to ASP.NET 2.0

ASP.NET 2.0 has generalized and transformed the session state module discussed so far into the so-called "ASP.NET provider model," which makes it far more customizable than its predecessor. In particular, several ASP.NET 2.0 features offer rich customization capabilities, including personalization, membership, role management, site map, and of course, session state.

As mentioned, the ASP.NET provider model is an evolution of the ASP.NET 1.x session state managers inspired by the Adapter design pattern. Two key aspects differentiate the ASP.NET 1.x session state model from the ASP.NET 2.0 provider model:

First and foremost, the ASP.NET 2.0 model is based on a richer and more flexible extensibility mechanism.

Secondly, it makes use of base classes instead of interfaces.

The ASP.NET 1.x session state model is based on the mode attribute, which is a closed enumerated type—the SessionStateMode enum. To support a new mode (for example, the Oracle table), you need to extend the enum type and modify the code of the session state module. These changes must be repeated each time you need a new extension.

ASP.NET 2.0's Adapter design pattern offers a better and more flexible code design. An Adapter class implements an interface known to its clients and provides access to an instance of a class not known to its clients. An Adapter object provides an interface's functionality without having to assume which class is being used to implement that interface. The only variation to the Adapter pattern is that a base class is used instead of an interface.

In ASP.NET 2.0, you use the provider model to achieve several tasks, the most important of which are:

The implementation of a read/write mechanism to persist the user profile

The creation of a user-defined repository of user credentials that supports most common operations, such as verifying the existence of a user, adding and deleting users, and so forth

The creation of a user-defined repository for user roles

The definition of the site map

The introduction of newer types of data storage for the session state

Provider Model Implementation

The implementation of the provider model consists of two distinct elements: the configuration layer and the storage layer. The configuration layer provides information for identifying and instantiating the physical provider object that manages the stored data. The storage layer is the physical entity that stores and manages the data. Depending on the feature, it can be Active Directory, an Oracle or SQL Server table, or an XML file.

Let's briefly review the characteristics of the provider model implementation in a common scenario: managing the user's profile, the set of personal information that each user keeps private.

The configuration layer provides a strongly typed model to get and set property values for the user profile object. The user profile object is represented with a collection of typed properties expressed in the web.config file as follows:

The class is compiled on the fly and added to the application's AppDomain. An instance of the class is also exposed through the Profile property on the HttpContext class. The user profile object is filled with stored data when the request starts, and any modified values are restored upon exit. Reading and writing are operations the user profile providers perform.

ASP.NET 2.0 comes with two user profile providers. Each uses a different data engine. The default provider uses an Access database; the other provider is for SQL Server. You also can write custom providers. The provider writes data into the database of choice and is responsible for the final schema of the data. A user profile provider must be able to either serialize the type (by using XML serialization and binary object serialization, for example) or know how to extract significant information from it.

Provider Model in ASP.NET 2.0

At its core, the ASP.NET 2.0 provider infrastructure allows customers to extend some of the out-of-the-box system functionality and change the underlying implementation while keeping the top-level interface intact. Providers are relatively simple components with as few methods and properties as possible.

Other providers (for example, the membership provider) perform different tasks, such as creating a new user, deleting existing users, or validating a given user. However, no matter the operations performed, the provider supplies a common and immutable programming interface for tasks that helper classes perform—tasks that the client doesn't know in advance and that can work with any sort of storage medium.

As a result, the provider model in ASP.NET 2.0 has two key benefits:

It makes the whole infrastructure much more resilient and flexible.

It enables developers to port ASP.NET 2.0 into portions of their existing infrastructures that were developed for version 1.x easily. In this sense, it promotes reusability and smoothes migration.

About the Author

Dino Esposito is Wintellect's ADO.NET expert and a trainer and consultant based in Rome, Italy. He runs the Cutting Edge column for MSDN Magazine and is a regular contributor to MSDN News, Visual C++ Developers Journal, and SQL Server Magazine.