-
Notifications
You must be signed in to change notification settings - Fork 26
hs240
Validation rules and other business related behavior is added to your business classes by adding the required code plus additional methods and properties to the class. Validation rules and side effects of changing the value of an attribute are often added to the setter method of the corresponding property. Complete validation of business objects before they are stored to the database can be added by overriding the BeforeStore method of the class. New objects can be initialized by overriding the Initialize method. For a complete list of the virtual methods of TInstantObject, please refer to the source code.
Note: BeforeStore is currently NOT called for embedded objects. Validation of embedded objects, however, can be done by using its owner's BeforeStore event.
Example 1 In InstantObjects you usually apply single-attribute business rules in the attribute's property setter method:
procedure TAddress.SetPostalCode(const Value: string);
begin
// Validation: raise exceptions to prevent value assignment.
if (Length(Value) <> 6) and (Value <> '') then
raise Exception.Create('Postal Code must be filled with 6 chars');
// Assignment: this code will usually be written by InstantObjects automatically.
_PostalCode.Value := Value;
// Post-assignment: do things as a consequence of an attribute's value change
// (see also the virtual method AttributeChanged).
if (Value <> '') and (City = '') then
GetDefaultCityByPostalCode(Value);
end;
If you need to apply business rules that involve more than one attribute, instead, you often use the BeforeStore virtual method (see Example 2).
When you code side effects, be aware that the property setters might be called more often than expected, for example when reading an object from an XML file or when you use the data-aware presentation layer. Here is an example:
procedure TShipment.SetMinShipDate(const Value: TDateTime);
begin
// Assignment: this code will usually be written by InstantObjects automatically.
_MinShipDate.Value := Value;
MaxShipDate := 0;
end;
The intent of this code is to reset MaxShipDate whenever MinShipDate changes, so that a user, in a hypothetical data-entry scenario, will have to re-enter a value for MaxShipDate. But things might not work always as expected. For example, SetMinShipDate might be called after SetMaxShipDate when streaming in an object from a XML file. The lesson here is: use the property setters and the BeforeStore method only to apply real business rules (like "MaxShipDate must be equal to or greater than MinShipDate"), and code data-entry rules (like "whenever a value for MinShipDate is entered, MaxShipDate should be reset") at the data-entry level (that is, not in the model classes).
Example 2 Business rules that involve more than one attribute are usually applied in BeforeStore, which gets called whenever the Store method is called to write an object (back) to the storage. Example:
procedure TShipment.BeforeStore;
begin
if MinShipDate > MaxShipDate then
raise Exception.Create('Date range error');
inherited;
end;
You initialize an object by overriding Initialize (if you need to apply initialization code both when a new object is created and when it is retrieved from the storage), or AfterCreate (if you need to apply initialization code for newly created objects only). There is also an AfterRetrieve method that you can override to apply initialization code only when an existing object is read from the storage and materialized in memory. Here is an example of AfterCreate:
procedure TContact.AfterCreate;
var
vCategory: TCategory;
begin
inherited;
Id := InstantGenerateId;
vCategory := TCategory.Retrieve('CAT000');
try
Category := vCategory;
finally
vCategory.Free;
end;
end;
- Home
- Glossary
- Project structure
- Installing InstantObjects
- User Guide for InstantObjects
- Creating the Business Model
- Creating the User Interface
- Programming with Persistent Objects
- Learning the Primer Demo