Using your Business Objects

In this topic I'll take a quick overview and a short tour of the code features of the wwBusiness framework.

The wwBusiness object provides the core business object class. This class is a single level business object class that implements the business tier and a separate data tier that is never accessed directly from your front end code. The Data Tier is abstracted and handles different types of backends - Sql Server, OleDb etc. The framework provides error handling for your data access code and makes it very easy to retrieve and save data without having to repetitively write the same data acess code over and over again. The error handling captures errors and allows your code to check for them easily through properties and return values.

The base object provides core data access functionality (Load, Save, Query, New etc.) through its base class methods. The base class also provides a direct query interface through the Execute() method although use of it is not recommended - you should use this method in sublcassed methods to access data and then return the data from there.

For typical front end code the business object layer can handle 70% or more of the Data Access code simply by using the record based methods. And the remainder typically uses the Execute() method to perform queries that return data. In addition to providing this consistency, it also allows for clean abstraction of the data access code from the backend. wwData is a very thin layer ontop of ADO.Net. This provides flexibility to switch backends and use alternate datasources and protection against future changes if Microsoft should decide to change data access methodologies again.

Each business object stores data internally in a DataSet that is publicly exposed. A DataRow is also exposed and provides a 'current' instance record of the currently selected it. For example, when you call the Load() method of the business object the DataSet is loaded with a table by the same name as the underlying default table. The first row of this table is exposed in a DataRow object which provides easier access to the data. You can use the DataRow member to read data and update it. When you've made changes to it you can simply call Save() to write the data back to the business object. A simple example demonstrates:

Customer = new busCustomer();
busCustomer Customer = new busCustomer();

if ( !Customer.Load(1000) )// *** Load by Pk
{
	this.lblError.Text = Customer.ErrorMessage;
	return false;
}

this.lblLastName.Text = (string) Customer.DataRow["LastName"];
...
Customer.DataRow["LastName"] = this.lblLastName.Text;

Customer.Save();

You can also add a new Customer in the same fashion. For fun I'm adding some validation checks here as well:

busCustomer Customer = new busCustomer();

if ( !Customer.New() )// *** Load by Pk
{
	this.lblError.Text = Customer.ErrorMessage;
	return;
}

Customer.DataRow["LastName"] = "Strahl";
Customer.DataRow["FirstName"] = "Rick";
...

If (!Customer.Validate() ) 
{
   this.lblErrorMessage.Text = Customer.ValidationErrors.ToHtml();
   return;
}

if (!Customer.Save() )
{
   this.lblErrorMessage.Text = Customer.ErrorMessage;
   return;
}

As you can see the idea here is that you work with record level objects a lot of time when your dealing with the user interface and having access to the DataRow is really nice since you have a single place to make changes and then simply call Save() to update the changes.

Note:
You can also used Typed DataSets instead of the untyped Data used in the examples above. See the Using Typed DataSets topic for more detail.

Behind the scenes wwBusiness uses the wwData member to perform the data updates which use standard ADO.Net code to update the changes you've made to the Data using a DataAdapter.

The high level C.R.U.D. methods can handle a large chunk of front end code easily. You can combine multiple business objects together into an object hierarchy. For example an invoice object could contain a Customer object and a lineItem object. Rather than deal with relationships at the data level the approach usually taken is to handle the relationships at the object level. Although this is the recommended way to do this, you can of course still use relations at the ADO.Net level, but you will be responsible for managing these yourself with standard ADO.Net code. Object relationships too are managed through code, but the logistics for this are generally very simple.

Implementation wise you will be creating custom methods to handle business logic. Query methods generally will use the Execute method to run custom queries or call Stored procedures using a Command object. These methods then should return data in a common way (for example query methods should return a record count or -1 for failure, Load() type methods should return true or false etc.) These are just guidelines for consistency but they are not required. For an idea of how this works in a real scenario take a look at the custom business classes provided in the Web Store application. busItem is a good example of a simple object with a gamut of custom implentation methods, while busInvoice is a good one for a complex object that includes multiple related objects (Customer and LineItems).

Beause the framework consists only of a minimal set of methods on this object it's easy to get started with it. The framework is also very efficient as it only builds a thin layer around ADO.Net.



© West Wind Technologies, 1996-2018 • Updated: 01/13/05
Comment or report problem with topic