Delphi Cookbook
上QQ阅读APP看书,第一时间看更新

How it works...

On startup, the application is as shown in the following screenshot:

Figure 2.4: Validation using RTTI attributes application on startup

When the Register button is clicked, the validation mechanism is triggered through the following steps:

  1. Retrieving a TCustomer instance based on the form data.
  2. Using the Validate class method of the TValidator class validates the instance just retrieved.
  3. If the validation is successful, a success message is shown; otherwise, errors are shown:
procedure TMainForm.btnRegisterClick(Sender: TObject);
var
LCustomer: TCustomer;
LErrors: TArray<string>;
begin
LCustomer := GetCustomer;
try
LErrors := [];
if TValidator.Validate(LCustomer, LErrors) then
ShowMessage('Well done! You''re now registered...')
else
ShowErrors(LErrors);
finally
LCustomer.Free;
end;
end;

The concepts of querying, consideration, and application are contained in this code snippet:

// iterate over object properties
for p in rt.GetProperties do
// iterate over attributes of this property
for a in p.GetAttributes do
begin
// ensure that is a ValidationAttribute
if not(a is ValidationAttribute) then
continue;
// reference to Validate method
m := FContext.GetType(a.ClassType).GetMethod('Validate');
if m = nil then
continue;
// invoke method
LResult := m.Invoke(a, [p.GetValue(AObject).AsString])
.AsType<TValidationResult>;
// eventually add error to errors array
if not LResult.Validation then
AErrors := AErrors + [LResult.ErrorMessage];
end;

Specifically, in the validated method of TValidator, the properties of the BOs are iterated to understand whether the validation attributes have been applied. If yes, the Validate method of the specific attribute is applied to the current value of the object property. If the property value does not pass validation, the error message specified in the attribute declaration phase is added to the errors array.

In the following screenshot, you can see the mechanism in place:

Figure 2.5: Validation in action