Showcases declarative programming and metadata-driven logic. This example demonstrates how to define custom attribute classes inheriting from 'TCustomAttribute', annotate other types with these attributes, and use 'RTTIRawAttributes' to programmatically discover and act upon this metadata at runtime for tasks like mapping classes to database tables.
<?pas
// Define custom attributes
type
TableAttribute = class(TCustomAttribute)
FName: String;
constructor Create(name: String);
begin
FName := name;
end;
end;
// Annotated entity classes
type
[TableAttribute('users')]
TUser = class
ID: Integer;
Name: String;
end;
type
[TableAttribute('orders')]
TOrder = class
OrderID: Integer;
end;
// Discover attributes at runtime
PrintLn('Entity Metadata:');
var attrs := RTTIRawAttributes;
for var i := 0 to attrs.Length - 1 do begin
// attrs[i].T is the type info target
// attrs[i].A is the attribute instance
if attrs[i].T = TypeOf(TUser) then begin
if attrs[i].A is TableAttribute then
PrintLn('TUser -> Table: ' + TableAttribute(attrs[i].A).FName);
end;
if attrs[i].T = TypeOf(TOrder) then begin
if attrs[i].A is TableAttribute then
PrintLn('TOrder -> Table: ' + TableAttribute(attrs[i].A).FName);
end;
end;
// Simple TypeOf usage
var info := TypeOf(TUser);
PrintLn('Class name from RTTI: ' + info.Name);
?>
Entity Metadata: TUser -> Table: users TOrder -> Table: orders Class name from RTTI: TUser