http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnbda/html/petshop3x.asp
Microsoft .NET PET SHOP 3.x: Design Patterns and Architecture of the .NET PET SHOP
Gregory Leakemicrosoft Corporation
James Duffvertigo Software, Inc.
May 2003
Applies TO:
Microsoft® .NET Framework 1.0 and 1.1 Microsoft® Windows 2000 and Windows ServerTM 2003 Microsoft® Internet Information Services Microsoft® SQL ServerTM 2000 Oracle® 9i Database
Summary: Version 3.x of the .NET Pet Shop addresses the valuable feedback given by reviewers of the .NET Pet Shop 2.0 and was created to ensure that the application is aligned with the architecture guideline documents being produced by the Microsoft (20 printed. Pages)
Download The Pet Shop 3.0 Installer.msi Code Sample.
Contents
AbstractWhat is the Java Pet Store Microsoft .NET Pet ShopBusiness RequirementsApplication Data Model.NET Pet Shop 2.0 Architecture.NET Pet Shop 3.0 ArchitectureConclusionsAppendix A:? Changes between Versions 2 and 3
Abstract
The purpose of the original .NET Pet Shop study was to take Sun's primary J2EE blueprint application, the Sun Java Pet Store, and implement the same application functionality with Microsoft .NET. Based on the .NET implementation of Sun's J2EE best-practice sample application , customers can directly compare Microsoft's .NET technology to J2EE-based application servers across a variety of fronts while learning about the similarities and differences in the recommended design patterns for building Web-based applications. The .NET Pet Shop application is now in its third revision and is designed to show the .NET best practices for building enterprise n-tier applications which may need to support a variety of database platforms and deployment models. The .NET Pet Shop 3.0 has been re-architected based on community feedback on the. NET PET Shop 2.0 To Comply with Microsoft's Prescriptive Architecture Guidance As Published ON MSDN. The Third Revision IS Also Fully Compliant with the MiddleWare Company Application Server Benchmark Specification, and will serve as Microsoft's entry in the upcoming Middleware Application Server Benchmark this spring: a second round of testing by the Middleware Company to compare the scalability of .NET and the J2EE platforms for building and hosting enterprise Web applications. What is The Java PET Store?
The Java Pet Store is a reference implementation of a distributed application according to the J2EE blueprints maintained by Sun. The sample application was originally created to help developers and architects understand how to use and leverage J2EE technologies, and how each of the J2EE platform components fit together. The Java Pet Store demo includes documentation, full source code for the Enterprise Java Beans (EJB) architecture, Java Server Pages (JSP) technology, tag libraries, and servlets that build the application. In addition, the Java Pet Store blueprint application Demonstrates Certain Models and Design Patterns Through Specific Examples.The Full Java Pet Store Contains Three Sample Applications:
Java Pet Store: The main J2EE Blueprints application Java Pet Store Administrator:.. The administrator module for the Java Pet Store Blueprints Mailer: A mini-application that presents some of the J2EE Blueprints design guidelines in a smaller package.
The original version of the Java Pet Store was designed to work with the following databases:. Oracle, Sybase, and Cloudscape IBM has created a DB2 port of the application The application is publicly available at the Java 2 Platform Enterprise Edition Blueprints The premise.. Of The Main Application, The Java Pet Store, IS An E-Commerce Application WHEN You Start The Application You Can Browse and Search for Various Types of Pet from Dogs To Reptiles.
A Typical session Using The Java Pet Store Would Be:
Homepage-this is the main page thing loads...
Category View-There are five top-level categories: Fish, Dogs, Reptiles, Cats, and Birds Each category has several products associated to it If we select Fish as the category, we might see "Angelfish" etc.Products-If.. You now SELECT A Product The Application Will Display All Variants of The Product. Typically The Product Variant Is Either Male OREMALE.
Product Details-Each Product Variant (Represented As Items) Will Have A Detailed View That Displays The Product Description, A Product Image, Price, and The Quantity In Stock.
Shopping Cart-this Allows The User to Manipulate The Shopping Cart (Add, Remove, and Update Line Items).
Checkout-the checkout page displays The shopping Cart in a Read-Only View.
.
Verify Sign In -After Being Auto The Site, The User is The Redirected To The Credit Card and Billing Address Form.
Confirm Order-The Billing and The Shipping Addresses Are Displayed.
COURT ORDER-this Is The final step in the order-processing pipeline. The order is now committed to the database at this point.
Figure 1. Java Pet Store
Microsoft .NET PET SHOP
The goal of the .NET Pet Shop was to focus solely on the Java Pet Store (the administration and mailer component were not implemented in .NET) In addition to reproducing the functionality of the Java Pet Store application, two additional objectives were added.:
Compare and contrast the code and code size of a real world, best-practice application between .NET and J2EE. Provide data on how many users a typical, well-designed application can support when implemented in .NET and in J2EE.
Figure 2. .NET Pet ShopThe overall logical architecture of the .NET Pet Shop is given in Figure 3. The main focus of the design was to use ASP.NET Web Forms for the presentation tier which communicate to C # business components in a logical middle tier. In turn the business components access a back end database through ADO.NET and a SQL Server helper class known as the Data Access Application Block (DAAB) for more information on the DAAB and to download the full DAAB source code. Data Access is fully abstracted into a Data Access Layer (DAL), separate from the business logic layer (BLL). New with the .NET Pet Shop 3.0, we have introduced a DAL layer for both Oracle 9i and SQL Server 2000 databases. Class loading of the appropriate DAL layer occurs dynamically at runtime based on an application configuration setting in Web.Config. Note that .NET Pet Shop 3.0 uses two backend databases, and the order process involves a distributed transaction across these two databases. Using simple Web.C onfig application settings, users can deploy the .Net Pet Shop to work with single or multiple backend databases, and can freely mix SQL Server and Oracle backend databases with the distributed transaction handled by .NET Serviced Components using COM Enterprise Services.
Figure 3. .NET PET SHOP High-Level Logical Architecture
Figure 4 shows how the Microsoft .NET Pet Shop might be physically deployed. In this case inbound network traffic is split between the two application servers using Network Load Balancing, NLB, or perhaps hardware load balancing. Once a network request has reached one of the machines in the cluster, then all the work for that request will be performed on that particular machine. The business logic and data access components will be installed as assemblies on both servers, which in essence will be identical clones of one another. If the load -balancing software is configured to use "sticky Ips," then each server can have its own session-state store, because a second request will be guaranteed to return to the server where the first request was fulfilled. For a more fault-tolerant solution , The Two Application Servers Can Share A Common Session-Store Such As SQL Server OR A Dedicated Session Server (Not Shown On Diagram). The Type and Location of The Session-Store IS Determine D by the value in the 'sessionstate' child node of the 'system.web' element in the 'Web.config' File for Each Web Site.figure 4. .Net Pet Shop Physical Deployment Diagram
Business Requirements
As part of the architecture documentation for Pet Shop 3 we have laid out what we considered to be the business requirements for the .NET Pet Shop, so that developers and customers could understand some of the trade-offs we made when we made some of our Design Decisions for the application.
What Are The Functional Requirements of the PET SHOP Application?
The application should enable customers to browse the company catalog by category and through key word searches. The application should provide customers with a mechanism to purchase multiple items through a shopping cart model. The application should provide a simple security model so that a customer is required to sign in before they are allowed to purchase the contents of the cart The application is intended to support a high-volume enterprise-class e-commerce solution; hence the application should demonstrate the following:. High performance, measured in terms of supported users , and the user response time. The ability to scale up by adding more processors The ability to scale out by adding more machines to form a cluster With large Enterprise System it is likely that the application will be required to access multiple data repositories, hence the Application Should Support Distributed Transactions. The Application Should Allow for a flexible Deployment Strategy. by Default The App lication is designed to be deployed to two physical machines, one application server and one database server but should be extensible to work in other deployment models. The application should support multiple database vendors. In this case we have chosen Microsoft SQL Server, and Oracle. The Application Should Be Easy To Maintain, Which Will Be Measured by The Lines of Code In The Application.
Application Data Model
Database
The database schema used in the .NET Pet Shop is ported directly from the Java Pet Store. The Java Pet Store supports several database vendor formats and so we took the schema for the Sybase application and created it in a Microsoft SQL Server 2000 instance. This . required no changes to the Sybase version of the schema With the creation of an Oracle version of the .NET Pet Shop, we took the original Oracle implementation of the Java Pet Store database.The database has the following overall structure of tables; see Table 1:
Table 1. Database Table In Pet Shop
Table NamePurposeAccountRepresents basic customer informationBannerDataStores the ad banner informationCategoryThe catalog categories (Fish, Dogs, Cats, etc) InventoryProduct inventory statusItemIndividual product detailsLineItemOrder detailsOrdersThe orders placed by the customer. An order contains one or more line itemsOrderStatusOrder statusProductCatalog products, each product may have one or more Variants (items). a Typical Variant Might Be Male OR Female.profilecustomer User ProfilesignonLogin Table for CustomerssupplierInformation Concerning Fulfillment Supplier
With version 2 of the .NET Pet Shop, the application was modified to create a scenario where a distributed transaction would be required to complete the order process. For the distributed transaction scenario, the Orders, OrderStatus, and LineItem tables have been split off into A Separate Database Instance That Could Be Installed On a Separate Machine. We Have Kept this Distributed Design Pattern in The Third Version of The .NET PET SHOP.
Figure 5. .NET PET SHOP Orders Database Schema
Figure 6. .NET PET SHOP Accounts and Products Database Schema
? What Changes Could Be Made to the Pet Shop Table Design There are some changes that could be made to the schema used in the application; however, we have not made these changes in order to keep in line with the schema provided by the Java Pet Store Reference Implementation. There Changes Are Listed in Table 2:
Table 2. Possible Improvements to the Pet Shop Schema
ChangeReasonNot store HTML in tablesYou may want to use different client application types, hence by storing only an image file name, rather than an image tag, in the database you can be more flexible with the client type you can deployUse a one-way encryption algorithm for customer passwordsHelps make the application more secure, because if any part of the system is compromised it will still be difficult to read the password. Would require the facility to reset the password to a new value.Encrypt credit card informationPrevent access to the credit card . information should the system to compromised Additional changes would be to make the table only accessible with write permissions via a stored procedure; hence a hacker would need to access the database via an alternative set of credentials to read the data.
.NET PET SHOP 2.0 Architecture
Figure 7. .NET PET SHOP 2 Application Architecture
.NET Pet Shop 2.0 was designed to be deployed in a physical two-tier deployment and took advantage of this fact in the implementation of certain parts of the application. The application consisted of a Web tier built with ASP.NET Web Forms which used " code-behind "to separate the application HTML from the user interface code. The middle tier contained business components to control the application logic which talked to a SQL Server database through a customized version of the Microsoft Database Access Application Block (DAAB). to support distributed transactions, some of the middle tier business components were implemented using Enterprise Services. With Microsoft .NET this is the recommended way to support distributed transactions. However, not all classes extended the ServicedComponent class, as there is a performance overhead of implementing all classes As Enterprise Serviced Components. When Publishing The .NET PET SHOP 2.0, Which Was Used In The First MiddleWare Application Server Benchmark, We Received Muchbeck ON Optimizations That Should Be Made to the Architecture To Make It More Relevant To Large-Scale Enterprises. The Major Areas of Feedback Included:
Creating a completely abstracted data tier with no imports of data-specific classes in the middle tier. Implementing a data access layer for Oracle that works transparently with the same business and UI layers as the SQL Server version. Completely abstracting Web session state from the business logic and data layers such that the backend components of the application can be physically distributed onto separate computers from the Web server, or reused from other types of clients such as Windows-based clients vs. Web-based clients. Fully partitioning application modules into separate Namespaces and Physical Assemblies. Additional feedback Across a variety of fronts..NET PET Shop 3.0 Architecture
Figure 8. .NET PET SHOP 3.0 Application Architecture
Application AREAS
Table 3. Application Areas in The Pet Shop Solution
AreaPurpose.NET ImplementationUser Interface ComponentsCapture data input from the user and display data returned by the backend system. They also handle simple navigation. Refer to User Interface Components. ASP.NET Web Forms, user controls, and server controls. These constructs allow for clean separation between designer HTML and UI code such as event handlers for buttonsUser Interface ProcessingControls user navigation and process flows with backend business objects. Also handles management of user session data. Refers to User Process Components.These are implemented as C # classes. The session state management is handled by ASP.NET.Business ComponentsComponents that implement the business logic for an applicationThese are implemented as C # classesBusiness EntitiesThin data classes for passing data between tiers of the application. Refer to business entity components. These are implemented as C # classes with each field exposed As a proty. Each class is marked as "serializable" to enable inter-process transfer.Data Access Layer ComponentsHandle the interaction with back end data stores, including databases, messaging systems, etc.These handle the interaction with backend data stores, including databases, messaging systems, etc. Implemented as four C # projects: A set of interface classes for each data access method we want to expose. An implementation of the interfaces for SQL Server. An implementation of the interfaces for Oracle 9i. A set of factory classes to load the correct implementation, either SQL Server or Oracle.
Microsoft Visual Studio .NET SOLUTION
Figure 9 shows the Microsoft Visual Studio .NET solution layout for the .NET Pet Shop application. Each element or tier of the application was given its own project to make the solution manage and clearly define where new classes used in the application should be placed or Old Ons Can Be Found.figure 9. Visual Studio .NET Application Solution
The Purpose of Each Project is listed in Table 4:
Table 4. Visual Studio Projects in the PET Shop SOLUTION
ProjectPurposeBLLHome for business logic componentsConfigToolAdministration application used to encrypt connection strings and create event log sourceDALFactoryClasses used to determine which database access assembly to loadIDALSet of interfaces which need to be implemented by each DAL implementationModelThin data classes or business entitiesOracleDALOracle specific implementation of the Pet Shop DAL which uses the IDAL interfacesPost-BuildProject to run post compile actions such as adding assemblies to the GAC or COM Pre-BuildProject to remove assemblies from the GAC or unregister assemblies from COM SQLServerDALMicrosoft SQL Server specific implementation of the Pet Shop DAL which uses the IDAL interfacesUtilitySet of helper classes including a wrapper for the DPAPIWebWeb pages and controlsSolution ItemsMiscellaneous items used to build the application such as Pet Shop.snk key file used to sign application assemblies
Database Portability
One of the key requirements for this version of the Microsoft .NET Pet Shop was to provide an implementation of the application that supported both Oracle and SQL Server databases. When designing the database access mechanism for the application, we had a choice as to which database providers we should use; we could either use the generic OLE-DB managed provider or the database-specific, performance-optimized .NET managed providers, such as the SQL Server and Oracle managed providers provided with the .NET Framework 1.1 One of the. key requirements for the application was to create a high-performance solution, so we chose to build the application using the database-native .NET managed providers. for an analysis of the difference in performance between the managed providers and the generic OLE-DB providers , Readers SHOULD REFER TO USING .NET Framework Data Provider for Oracle To Improve .NET Application Performance, Which Shows That The Vendor-Specific Province Can Perform Two to Three times better than the equivalent OLE-DB provider. The tradeoff that we made when choosing to go with a database-specific access class was that we would need to write a separate data access layer for each database platform we wanted to support and hence the application Would Contain More Code. While The Two Data Access Layers Share Much Common Code, Each Is Clearly Targeted for Use with a specific Database (Oracle or SQL Server 2000).
In order to simplify the use of the database access classe, s we elected to use the Factory Design Pattern as outlined by the GoF, with reflection being used to dynamically load the correct data access objects at runtime The factory is implemented as follows:. A C # interface is created with a method declared for each method that must be exposed by the database access classes. for each database that we want to support, we create a concrete class that implements the database specific code to perform each of the operations in the interface or "contract." to support the runtime determination of which concrete class to load, we create a third class which is the factory itself and reads a value from configuration file to determine which assembly to load using reflection. With the reflection namespace in .NET YOU LOAD A SPECIFIC Assembly and create an instance of an Object use what assembly. to make the application more security and provide ket support for versioning, we can add "EVI dence "about the assembly file to load in the application configuration file, in this case, web.config. This means that the .NET Framework will only load the assembly that we have signed during compilation and has the correct version number. Figure 10 shows how the business logic, factory, and databases access classes interact with each other. The key advantage of the solution built is that the database access class can be compiled after the business logic classes as long as the data access class implements the IDAL interfaces. This Means That Should We Want To Create A DB2 Version of The Application, We do Not Need To Change The Business Logic Tier (OR UI Tier). The Steps to Create A DB2 Compatible Version Are:
Create the database access classes for DB2 which implement the IDAL interfaces. Compile the DB2 access classes into an assembly. Test and deploy the new data assembly to a running server. Change the configuration file to point to the new database access classes.No changes or Recompiles Need to Be Performed on The Business Logic Components.
Figure 10. Dal Factory Implementation In .NET PET SHOP
Stored Procedures
Normally We 10 Recommend TO CUSTOMERS That The Use Stored Procedures To Access Tables in The Database. There said SEVERAL REASONS for this:
Stored procedures provide a clean mechanism to encapsulate queries. Changing a query can be done without changing the data access code. A DBA can easily see what SQL statements are being executed. Stored procedures are typically more secure, and it is easier to control database access . by using stored procedures you can avoid round trips to the client by issuing more than one request in the stored procedure. Stored procedures usually offer the best performance compared to middle-tier-generated SQL. Stored procedures offer an excellent way to encapsulate XML queries And XML INPUT Parameters.
.............. ..
However, to make the best use of the financial investment that you have made in your database software and hardware, developers will tend to optimize the SQL used in their applications for their specific database engine regardless of whether the SQL is in a stored procedure or generated in the middle tier. A good example of this is generating unique numbers or identity numbers, as all databases support their own particular mechanisms for doing this, and so the SQL used to generate the unique number tends to be specific to the database being used. There are always alternatives, but they do not perform as fast as the proprietary solutions.With the .NET Pet Shop we took the conscious decision not to use stored procedures in the application as this might be seen to be an unfair advantage for the .NET Solution in Reality The Difference In Performance Is Small Because The Application IS Relative SIMPLE AND MOST OF THE SQL Statement Execution Plans Are Cached in .
Caching
One of most effective ways to improve the performance of a database-driven applications is to eliminate accessing the database for every request. ASP.NET offers a variety of caching mechanisms that boost performance in most applications. The two main ways to use caching in ASP .NET Are Output Caching and Data Caching.
.NET CACHING OPTIONS
Page-level output caching takes the response from an ASP.NET Web page and stores the full page in a cache. The page cache is designed to work between the Web tier and the middle tier and caches the results / data of middle-tier methods , or the results of database calls in the case of two-tier apps. The first .NET Pet Shop distribution was offered in a page-level output-cached version and a noncached version. Version 3 only supports data caching but can easily be modified to support output caching. with Windows Server 2003 and IIS 6.0, certain output cached pages (those with VaryByParm = "none" and the directive to Cache 'Anywhere') can also be kernel-level cached, with even faster access from Internet clients. Regardless, any output-cached page (kernel or nonkernel cached) is served extremely quickly by the Windows application server with much less resource (CPU) consumption, since no processing is actually occurring to recreate the page.ASP.NET Output Caching
The original .NET Pet Shop application, version 1.5, also used a variation on page-level output caching, partial page caching or fragment caching to cache different regions of page. For instance, the header information that appears on the top of every page is cached. However, the header information is dependent on the user signing in (so two different versions of the page have to be cached). ASP.NET easily allows this by using the VaryByCustom attribute on the 'OutputCache' directive. Using VaryByCustom requires overriding The getvarybycustomstring method to get a custom cache for the header.
ASP.NET DATA AND OBJECT CACHING
The object cache (Cache API) allows you to store the results of a method call or database query in the internal caching engine with the .NET Framework. Since you have gone further through more of the application pipeline, the data cache may not offer the same performance boost that output caching yields, since HTML pages still must be dynamically constructed on each request. However, it does offer a good compromise between fully dynamic pages and reducing the load on the database by storing nonvolatile data in the middle tier. For example You May Want to Display The Same Piece of Data Differently in Two Web Pages, or Use The Cached Objects OR Data Differently In Various Pages of the Application.asp.Net Cache Monitoring
There are several ways to monitor what is happening in the ASP.NET caching system. The foremost method is to use Perfmon but you can also use a SQL Server trace to check when database access is occurring or not occurring as the case may be. To monitor the cache in Perfmon, select the Output Cache Entries and Cache API Entries counters under the ASP.NET Application performance object and add them to the Perform graph. It is also possible to monitor the turnover rate and the hit rate within Perfmon to detect whether The item is being used in the cache.
Table 5. Summary of Caching Options IN .NET
Type of CachingBenefitsLimitationsOutput CachingOffers best performance Entire page output is cachedFragment Caching (Cache user controls) Simple to implement. Entire page output is cached Limited to time invalidationCache APIDifferent user controls on a page can have different cache timeouts Cached controls can be shared across pages. Need To Cache Each User Control Individally
Pet Shop Middleware Benchmark Caching RulesThe Middleware Company has defined strict rules for the benchmark application as to what can be cached and how it can be cached. Basically, page-level output caching is disallowed, but middle-tier data caching is allowed in certain places . in the application The following data was allowed to be cached; it does not need to be refreshed from the database on each request: category information, product information, item information (excluding inventory data), and some account information in terms of inventory. data, the current quantity in stock should reflect an up-to-date value whenever an item is added to the cart or a user navigates to the 'ItemDetails' page. For the account information the username and password has to be validated on every single Login Attempt, and the address sale for billing information shop the date during a checkout process. The implication of this is what Results for MOSTOTS Searches and Browse Operations Can Be Cached in The Middle Tier Using A Data / Object Cache Set To Expire ON A Given Interval.
The second rule for the benchmark is that page level output caching should not be allowed;. The web server should always be required to recreate the rendered HTML for a page The reason for this is to test the ability of the application servers to generate dynamic pages NOTHOW FAST The Server Could Pull HTML from a cache.
PET SHOP 3.0 CACHING IMPLEMENTATION
For this version of the application, we used data caching in the code behind of the ASPX pages to cache the results of middle tier (business logic tier) requests. The following sample code shows how one would access the ASP.NET cache API to retrieve information from the cache. The example is based on the category query, category.aspx.cs, in the Pet Shop application. in the Pet Shop a user can select one of the five predefined categories of pet and view a list of animals in that category. The first thing the code does is to check to see if the data has already been cached by using the category id as a key to look up an element in the data cache. If this element does not exist, either because the data has not yet been cached, or the current cache has expired, it will return null. If the element exists, the data from the cache is pulled and cast to the appropriate type. If the data is not in the cache, the middle tier is invoked To query for the data. The results from the middle tier quer y are then added to the cache with an expiry time of 12 hours from now. Alternatively, we could expire the cached based on a fixed time of day, a dependency on another cache item, or by supplying a callback function which could be used to Clear the cache.// get the category from the query string
String categoryKey =
WebComponents.cleanstring.inputText (Request ["CategoryID"], 50);
// Check to see if the contents are in the data cache
IF (cache [categoryKey]! = null) {
// if the data is already cached, then used the cached copy
Products.DataSource = (ilist) cache [categoryKey];
} else {
// if the data is not cached,
// Ten Create a New Products Object and Request the Data
Product product = new product ();
IList productsBycategory = product.getProductSBycategory (categoryKey); // store the results of the call in the cache
// and set the time out to 12 Hours
Cache.add (CategoryKey, ProductsBycategory, NULL,
Datetime.now.addhours (12), cache.noslidingExpiration,
CacheItemPriority.high, NULL);
Products.DataSource = ProductsBycategory;
}
// bind the data to the control of THE CONTROL
Products.DATABIND ();
Conclusions
The architecture of the .NET Pet Shop has been enhanced to provide a more flexible solution in terms of deployment options and the application is more readily customizable and adaptable to the changes in business models. Despite all these changes, the performance of the Pet Shop has remained roughly the same as the 2.0 implementation, and shows that the Microsoft .NET framework offers a viable alternative to J2EE for Enterprise solutions. Using the .NET Pet Shop and J2EE Pet Store, architects and developers can compare .NET and J2EE side by side using functionally identical reference applications that illustrate best coding practices for each platform. The upcoming Middleware Benchmark will test the new .NET Pet Shop 3.0 implementation to compare its performance to two new J2EE implementations-one based on CMP 2.0 and one based on a pure JSP / Servlet architecture with no ejbs. The testing will be concected by the Middleware Company and Published on the serverside with a variety of j2ee application servers. A panel of J2EE experts has been established and is overseeing this benchmark to ensure fairness across tested products and adherence to specification / best practice for all implementations. In addition, the major J2EE application server vendors have been invited, along with Microsoft, to participate by commenting on the specification, providing implementations to be tested, and being on site for tuning / optimizations and the testing process Microsoft has opted to fully participate in this second round of testing.Appendix A:. Changes Between Versions 2 and 3
ItemDescriptionReason1Created a database access layer (DAL) .Allows clean separation of business logic from database access code, hence we can change database vendor without changing the business logic code.2Created a common project for all thin data classes (models) .The model project only contains thin classes for holding data and would be used in each tier of the application as a container to transport data in. All the model classes support serialization through the [Serializable] tag to add improved support for clustering and any future changes we want to make to physical deployment.3Removed references to System.Web in Components project.Good design practice as it allows middle-tier components to be used with different types of UI.4Changed some of the custom server controls to Web user controls;
however the Pager control was left as a custom server control.The header and banner controls contain a lot of HTML / UI content hence they are easier to maintain if they are implemented as web user controls. The Pager control deals with the manipulation of the query string and using data in viewstate, and so it is better suited being a custom server control.5Created an implementation of the DAL for Oracle.To support an Oracle database we created a specific Oracle DAL that would take advantage of an Oracle specific driver6The DAL layer now implements a factory [GoF] to load the appropriate vendor specific DAL.To hide which database we are using on the back end, we use a Factory method to return an interface to the DAL layer we want to use.7All public fields in the model class were converted to properties.This allows the field storage mechanism to be hidden and provides a good place to add break points in code if you want to see what functions modify certain data.8Created a database access layer (DAL) .Allowed clean separation of business logic from database access code, hence we can change database vendor without changing the business logic code.9Changed all static methods to instance methods.Response to review feedback10Fixed the version number in assemblyinfo.cs to a specific version to match deployment.Allows for specifying evidence when loading an assembly in the DALFactory objects.11Added pre- and post-build steps to the Visual Studio .NET solutions.This enables for running gacutil and regsvcs utilities on certain assemblies once the project has .