You are not logged in.
Hey ab,
I already use mORMot for stuff like
TSQLNamesRecord = class(TSQLRecordNoCase)
private
FName: RawUTF8;
published
property Name: RawUTF8 read FName write FName stored AS_UNIQUE;
end;
but I also have some classes that use composition with interfaces so e.g.
IDirInfo = interface
['{10101010-1010-0101-1001-111110110110}']
function GetDirname(): String;
property DirName: String read GetDirname;
end;
IFileInfo = interface
['{10101010-1010-0101-1001-111110110110}']
function GetFilename(): Integer;
function GetFileDate(): Integer;
property Filename: Integer read GetFilename;
property FileDate: Integer read GetFileDate;
end;
// and some other interfaces
and different classes that use these interfaces (implemented as own TAggregatedObject class to reuse them by delegation) as following
TDirs = class(TInterfacedObject, IDirInfo)
private
FDirInfo: IDirInfo;
public
constructor Create(...);
property DirInfo: IDirInfo read FDirInfo implements IDirInfo;
end;
TFilesDirs = class(TInterfacedObject, IDirInfo, IFileInfo)
private
FDirInfo: IDirInfo;
FFileInfo: IFileInfo;
public
constructor Create(...);
property DirInfo: IDirInfo read FDirInfo implements IDirInfo;
property FileInfo: IFileInfo read FFileInfo implements IFileInfo;
end;
My question is now
1. how to store this info with mORMot
2. how to know if it was TDirs or TFilesDirs if I want to create the class based on my saved data
Thanks in advance!
Offline
First point is that if you use interface just to store some values, without any try..finally..free block, then use a record instead.
Interfaces were not meant for making DTO, but mostly for abstraction / SOLID code against processing classes.
Currently, interface can't be serialized. They can only be recognized as calbacks for interface-based services.
So interface as properties, or interface with properties are not serialized yet.
The big problem is how to unserialize the interface values?
It is fine to convert into JSON (calling the properties getters and writing the JSON value).
To unserialize the interfaces, we would need to have the interface values already existing, then call the setter methods... but in a lot of cases, we won't have interface instances created.
IMHO this becomes very complicated.
The idea/workaround is to define record/class DTOs or TSQLRecord/TOrm types for SOA or ORM work, and keep the interfaces in the existing business logic.
Offline
First point is that if you use interface just to store some values, without any try..finally..free block, then use a record instead.
Interfaces were not meant for making DTO, but mostly for abstraction / SOLID code against processing classes.
Interfaces are the only way to make sure that all composition classes provide the same properties I need to access in some places in my code, no? With records I could easily forget one and then my program will crash *shrug*
TDirInfo = record
FDirName: String;
end;
TDirs = class
private
FDirInfo: TDirInfo;
public
constructor Create(...);
function ReadDirName: String; // needed because property can't be FDirInfo.FDirName
property DirName: String read ReadDirName;
end;
How to reuse all this code in TFilesDirs?
And actually I'm not sending any data or so, it should just be saved to database and reloaded/be available after a restart of it.
Last edited by w0rker (2021-03-19 13:16:29)
Offline
I am not sure I can really see the benefit of interfaces here - it seems overly complicated to me.
You can compose your objects using regular code, and the factory / aggregate patterns.
Use a set of TSQLRecord/TOrm classes in a (separated) persistence layer, to read and write your business classes like TDirs.
Otherwise, it is not possible for the ORM to know that DirName should be filled from FDirInfo.FDirName.
Offline