|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
IntroductionThis article focuses on the Provider Model design pattern and describes how it can be used to solve certain problems. To help readers to better understand or appreciate this design pattern, I've chosen view state management as an example to demonstrate the usefulness and practicality of this design pattern. So, in this article, we will first understand what the inherent problems of view state are, I will then explain why Provider Model design pattern is important and how we can leverage it to solve the aforementioned problems. BackgroundView State - a love-hate relationship with many ASP.NET developers. Developers love it because it does not require any server state resources and is simple to implement. Page and control state retains automatically across successive posts of the same page instance, which makes the magic of the Web Forms model possible. Furthermore, values in view state are hashed, compressed, and encoded for Unicode implementations, thus representing a higher state of security than hidden fields have. On the other hand, a couple of hot issues surround its use, primarily related to security and performance. For security, because view state is stored in a hidden field on the page. Although view state stores data in a hashed format, the information stored in the hidden field can be seen if the page output source is viewed directly, creating a potential security issue. For performance, because view state is stored in the page itself, storing large values can cause the page to slow down when browsers display or post it. For those new to ASP.NET, there are a number of good resources for learning more about ASP.NET view state.
Fortunately, the protected virtual void SavePageStateToPersistenceMedium (object viewState);
protected virtual object LoadPageStateFromPersistenceMedium();
By overriding both methods, you can manipulate the view state at your will. (Note that you cannot override only one method; you have to override both.) The typical solutions are:
Every proposed solution above has its pros and cons. As we all know, there is always a trade-off to choose between security and performance. The problem is how we can design our application in such a way that it can implement these solutions but selectively choose the best for a particular problem domain. For example, you might want to store the view state in a Microsoft SQL Server database for your development tasks and a different one (say Oracle database, which is requested by customer) in production. Choosing the right solution is therefore a matter of matching your needs with respect to how it can solve the problem effectively. Wouldn't it be great if you could implement these solutions on top of a repository that best suits your needs, while at the same time keep the application's architecture, design, and code independent of this choice? Introducing the Provider Model Design PatternProvider Model design pattern derives from a number of widely accepted patterns, and was officially named in the summer of 2002. A "provider" is defined as a pluggable component that extends, or fully replaces, existing system functionality. In other words, the provider model allows you to unplug the default implementation of an API (for example, view state management, session state management, personalization, and so on) and plug your own in. By writing your own provider for a specific system feature that supports the model, you can change the underlying implementation, data formats, and storage medium, without disrupting the application design (keeping the top-level interface intact). More simply put: it allows developers to publish well-documented, easy to understand APIs (Object Model), but at the same time give developers complete control over the internals of what occurs when those APIs are called. Features implementation that have providers must have a configuration section defined in the web.config (Web applications) or app.config (Windows applications) file. Its purpose is to register the available "providers" but choose one as the default provider. For example: <!-- View State Provider Configuration -->
<viewstate defaultProvider= "SqlViewStateProvider">
<add name="SqlViewStateProvider"
type="System.Web.Configuration.Providers.SqlViewStateProvider,
ViewStateProviders"
connectionString="SERVER=(local);DATABASE=(Database Name );USERID=sa;PWD=" />
<add name="CompressionViewStateProvider"
type="System.Web.Configuration.Providers.CompressionViewStateProvider,
ViewStateProviders"
connectionString="" />
</providers>
</viewstate>
Based on the configuration shown above, the following outlines a few important guidelines to be followed: defaultProviderEach feature configuration should specify the default provider, which instructs the system which of the listed providers to use. For example: <viewstate defaultProvider="SqlViewStateProvider">
Provider-friendly nameWhen defining a provider within configuration, it is required for the name attribute to be defined. Furthermore, the provider names should follow a pattern to easily distinguish who owns the providers. The suggested pattern is: [Provider Creator][Data Store][Feature]Provider. <addname="SqlViewStateProvider"
type="System.Web.Configuration.Providers.SqlViewStateProvider,
ViewStateProviders"
connectionString="SERVER=(local);DATABASE=(Database Name);USER ID=sa;PWD=" />
Table below calls out some of the common names and casing that should be used for various data stores (where name is [Name][Feature]Provider]. For example,
Provider typeWhen defining a provider within configuration, it is required for the type attribute to be defined. The type value must be a fully qualified name following the format: type="[namespace.class], [assembly name], Version=[version],
Culture=[culture], PublicKeyToken=[public token]"
The strongly typed name is desired, however, it is also legitimate to use the shorter style assembly type name. For example: type="System.Web.Configuration.Providers.SqlViewStateProvider, ViewStateProviders"
To learn more about the Provider Model design pattern, please read Provider Model Design Pattern and Specification, written by Rob Howard. ViewState Provider Object ModelThe model defines a set of classes to support the view state provider framework. The diagram shown below depicts the ViewState Provider Object Model and its interaction with Page.
SqlViewStateProvider - The implementation
Before a page renders its output, the When the page posts back, There is one problem here, each time a user visits a different page, a new record holding that page's view state will be created in the database table. Over time, this will lead to millions of records, which may seriously affect the performance of the lookup process. Some sort of automated task would be needed to periodically clean out the view state records older than a certain date. I leave this as an exercise for the reader. The diagrams below show the differences before and after using the
View State stored in hidden field (Before)
View State stored in database (After) Using the codeThis article ships with two view state providers, available from the link at the top of this article. One of the providers store view state into a SQL Server database table, which is described throughout this article, and the other has the capability of compressing the view state. As noted earlier, if the default functionality of these providers do not meet your needs, you can create your own provider and plug it into the framework. With ViewState Provider Framework in place, developing a custom view state provider is as easy as the few steps listed below:
ConclusionThe provider design pattern allows developers to have a flexible design and a rich, enterprise-level extensibility model. More importantly, you can very easily use one provider for your development tasks, and a different one for the application in production, simply by changing some configuration. Last, but not least, this is an important new design pattern in ASP.NET 2.0, which is extensively used in many common web application features like site membership, role management, personalization, etc. So, start using it in your applications today, and and you'll be ahead of the curve in understanding this design pattern in ASP.NET 2.0 tomorrow.
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||