domain objects • Zero DB types exposed (incl. TDataset & TField) • SQL moved from DFMs to … somewhere (and kept static) • Supporting all types of DB objects and DDL/DML operations • Independent of client/driver (e.g. ODAC instead of ADO) • Making logic fully unit-testable (thanks to total abstraction) We wanted something:
be declared as an implementation of an interface • Handler (implementation) has to know how to adjust its behaviour based on: • RTTI information (type description: names, types, attributes etc.) • arguments (just like any other method accepting those). So, if we can fit all control information into type declaration and normal arguments, we are going to get ourselves a generic implementation of some kind of interfaces. Like any and all SQL statements.
code generator • Generated code is quite simplistic and rigid • But: implementation is repeatable • Most complex DTOs can be easily marshalled into JSON • Special cases can be handled with attributes. SERVICE 2 API DB
still is significant. • Sizeable implementations will bloat your binaries (biggest Vanessa DCU: registration of 1 API + 8 statements), • Generics are useless during type inspection: you’ll do TypeInfo(T) and proceed with PTypeInfo anyway • Use generic stub to: 1) Do that cast and, 2) Pass resulting PTypeInfo to an actual implementation.
Invoke is wrong on many levels: • Will be executed multiple time (RTTI is fast enough, but still…), • Often will be too late: context can depend on previous call, • It is a bit too late to learn that something is missing or wrong, Instead: • Inspect type once, preferably before instantiation, • Raise inspection errors, log warnings and information, • Cache results in some structure and just serve it, • Every new instance will be fully operational instantly, • Bonus: they won’t need generics and maybe even PTypeInfo.