ATTRIBUTES AND RTTI CODE FASTER ATTRIBUTES Attributes are
ATTRIBUTES AND RTTI CODE FASTER!
ATTRIBUTES “Attributes are a language feature in Delphi that allows annotating types and type members with special objects that carry additional information. This information can be queried at run time. Attributes extend the normal Object-Oriented model with Aspect. Oriented elements. ” - Delphi documentation
ATTRIBUTES Code annotation Programmer annotates the code Run time querying Program reads those annotations and reacts accordingly
EXAMPLE type TMy. Class = class [My. Attribute] FField: string; end;
IMPLEMENTATION Attribute = class Descending from TCustom. Attribute Traditionally not starting with a T and ending in an Attribute type My. Attribute = class(TCustom. Attribute) end;
SIMPLIFICATION Attribute part of the name can be removed in the annotation Standard practice type TMy. Class = class [My. Attribute] FField 1: string; [My] FField 2: integer; end;
RTTI ctx : = TRtti. Context. Create; try t : = ctx. Get. Type(a. Class); for f in t. Get. Fields do for a in f. Get. Attributes do … finally ctx. Free; end; Attributes exist only when observed!
USEFUL HELPERS RTTIUtils Robert Love DSharp. Core. Reflection Stefan Glienke
PARAMETERS Attributes can accept parameters type TMy. Class = class [Store. As('External. Field')] FField: string; end;
CONSTRUCTOR Parameters are passed to an appropriate constructor type Store. As. Attribute = class(TCustom. Attribute) public constructor Create(external. Name: string); end;
OVERLOADED ATTRIBUTES Attribute can accept different parameter types or variable number of parameters type TMy. Class = class [Store. As('External. Field 1')] FField 1: string; [Store. As('External. Field 2', true)] FField 2: string; end;
OVERLOADED CONSTRUCTORS type Store. As. Attribute = class(TCustom. Attribute) public constructor Create( external. Name: string); overload; constructor Create(external. Name: string; store. As. Attribute: boolean); overload; end;
DEFAULT VALUES type Store. As. Attribute = class(TCustom. Attribute) public constructor Create(external. Name: string; store. As. Attribute: boolean = false); end;
ADVANCED ATTRIBUTES Multiple attributes are allowed on one element [Serialize] [Root. Node('Options')] Tew. Options = class [Serialize] [Root. Node('Optons')] Tew. Options = class [Serialize, Root. Node('Options')] Tew. Options = class
ATTRIBUTABLE ENTITIES Attributes can be applied to classes, records fields, properties methods, method parameters non-local enumeration declaration, variable declarations Even to entities that are not accessible with RTTI!
PROBLEMS Not working on generic classes W 1025 Unsupported language feature: 'custom attribute‘ Meaning can be unclear [Gp. Managed(true)] FList: TObject. List;
PRACTICAL EXAMPLES
AUTOMATICALLY CREATED FIELDS type Tew. Options = class(TGp. Managed) strict private FActive. Language: string; [Gp. Managed] FEditor : Tew. Opt_Editor; [Gp. Managed] FHotkeys: Tew. Opt_Hotkeys; public property Active. Language: string read FActive. Language write FActive. Language; property Editor: Tew. Opt_Editor read FEditor; property Hotkeys: Tew. Opt_Hotkeys read FHotkeys; end;
OBJECT SERIALIZATION - XML type [Xml. Root('Person')] TPerson = class(TObject) … public [Xml. Attribute('First_Name')] property First. Name: String read FFirst. Name write FFirst. Name; [Xml. Element('LAST_NAME')] property Last. Name: String read FLast. Name write FLast. Name; [Xml. Ignore] property Middle. Name: String read FMiddle. Name write FMiddle. Name; end;
OBJECT SERIALIZATION - INI type TConfig. Settings = class(TObject) … public [Ini. Value('Database', 'Connect. String', '')] property Connect. String: String read FConn. String write FConn. String; [Ini. Value('Logging', 'Level', '0')] property Log. Level: Integer read FLog. Level write FLog. Level; [Ini. Value('Logging', 'Directory', '')] property Log. Directory: String read FLog. Dir write FLog. Dir; end;
UNIT TESTING - DUNITX type TMy. Example. Tests = class public [Test] [Test. Case('Case 1', '1, 2')] [Test. Case('Case 2', '3, 4')] [Test. Case('Case 3', '5, 6')] procedure Test. One(param 1: integer; param 2: integer); [Test] procedure Test. Two;
ORM MAPPING type [TAttr. DBTable('NONE')] TReport. Item = class(TObject) protected [TAttr. DBField(PP_VEHICLE_FIELD)] FVeiculo. Id: integer; [TAttr. DBField(PP_DRIVER_FIELD)] FMotorista. Id: integer; end;
DATA VALIDATION type TMy. Config = class [Must. Not. Empty. String] [Folder. Must. Exists] property Working. Dir: string; [Min. Value(1)] [Max. Value(7)] property Default. Day: Integer; [Must. Not. Empty. String][Limit. To. These. Chars('xyz')] property Default. City: string; end;
COMMAND-LINE PARSING type TCommand. Line = class public [CLPDescription('Set precision'), CLPDefault('3. 14')] property Precision: string read FPrecision write FPrecision; [CLPPosition(1), CLPDescription('Input file'), CLPLong. Name('input_file'), CLPRequired] property Input. File: string read FInput. File write FInput. File;
REST SERVER [Authorize('User', TNCWAAuthorizer)] [Extra. Header('Access-Control-Allow-Headers', 'session. Id')] TFiles. Controller= class(TRest. Public. Controller) function Put(const file. Name, [From. Body]content: string): TRest. Response; function Save(const file. Name, [From. Body]content: string): TRest. Response;
CONCLUSION
PROS & CONS + Big code reduction + Self-describing code - Meaning sometimes unclear - RTTI can get complicated
LINKS Overview http: //docwiki. embarcadero. com/RADStudio/XE 5/en/Overview_of_Attributes http: //www. tindex. net/Language/Attributes. html http: //www. thedelphigeek. com/2012/10/multiple-attributes-in-one-line. html http: //delphi. fosdal. com/2010/11/another-generics-rtti-bug-attributes. html http: //stackoverflow. com/q/6119986 Gp. Auto. Create Serialization http: //robstechcorner. blogspot. com/2009/10/xml-serialization-control-via. html http: //robstechcorner. blogspot. de/2009/10/ini-persistence-rtti-way. html DUnit. X https: //github. com/VSoft. Technologies/DUnit. X http: //www. finalbuilder. com/Resources/Blogs/Post. Id/697/introducing-dunitx. aspx ORM mapping http: //www. thedelphigeek. com/2012/10/automagically-creating-object-fields. html http: //stackoverflow. com/a/14342203 Validation http: //forum. codecall. net/topic/76628 -using-attributes-for-validations/
QUESTIONS?
- Slides: 29