The West Wind Web Store uses a business object architecture that is designed for ease of use, simplicity in design and still provide only a thin layer on top of the ADO.Net architecture of .NET with the ability to fall back to ADO.NET at any point.
The key features of the business object are:
- Easy to use
The wwBusiness class interface is very simple - just a handful of methods and properties that you'll reuse over and over. No complex framework or interdependencies to learn - just a single level class that you subclass from for your business objects. Using the business object is as easy as creating a new class and optionally tying it to a primary database table that it maps to (not required but usually done). - Simplifies data manipulation
High level methods like C.R.U.D. methods like Load(), Save(), New() and Delete() etc. deal with all of the logistics of retrieving, changing and saving data. You simply manipulate an Entity object (and/or a DataRow) and let the business object deal with writing the data back to the database. In the Web Store 80%+ of the data access is handled through these high level CRUD data methods. - Data member provides easy cached access to data
wwBusiness provides Entity and DataRow members that expose the underlying database fields of the current loaded record from operations like New(), Load() and GetBlankRecord(). The Entity provides a strongly typed object from data row values which is much easier to use in code and provides compile time safety. A EntityGenerator tool is provided that can generate entities from your database schema. These entities are much more light weight than typed datasets and are plain .NET objects that support full serialization/deserialization for Web Services, Remoting, and WCF. - Abstracts Data Access
wwBusiness abstracts the backend database used so you can switch backends supported dynamically. Business object methods like Execute(), ExecuteNonQuery(), ExecuteScalar etc. have easy to use signatures for common scenarios of returning DataSets/DataTables/Readers without writing lower level ADO.NET code. Most commands are single line and handle connection setup/closing, error handling and returning high level results. wwBusiness provides access to the raw ADO.NET objects (like Command, DataAdapter, DataSet etc.) so if at any point you want full low level control you can get it from within the context of the wwBusiness/wwData object. - Separate Data Layer Objects
All data access is routed through a Data Object (wwData and its subclasses like wwDataSql, wwDataOdbc). The business object determines which backend to go to at startup and then uses the appropriate data access object to perform the actual database interaction. Since the interfaces are identical and use generic interface references, swapping a back end provider is as easy as setting a property. Supported backends include Sql Server, VistaDb, FoxPro, and generic OleDb. Base implementations for MySql and Oracle are also provided but haven't been tested extensively. - Light Weight
The data wrappers provided by wwBusiness and wwData/Sql are very lightweight and add very little overhead to the SQL access code. The underlying code goes directly to ADO.Net code and returns standard ADO.Net data structures like DataSets and DataRows that can be used with or without the West Wind Databinding controls. - Validation Support
The business object includes a ValidationErrors Collection that can be used to validate business logic. The Validate() method of the business object is a great place to validate business rules before saving. Here you can run any business rules that might require data access against the backend and if failures occur handle them in this central method by assigning them to the ValidationErrors collection. - Integration with Databinding Controls
We provide a wwDataBinder control that can easily bind control properties with data from these business objects (or any other objects for that matter). In addition the wwDataBinder can also consume ValidationErrors directly and display them as part of the error handling provided through the databinder.
See also: