Hallo
Experimentiere gerade mit der Klasse TJsonSerializer aus System.JSON.Serializers von Tokyo. Scheint ziemlich gut und einfach zu bedienen zu sein.
Da bei mir jede Klasse von einem Interface kommt, sind Properties immer an ein Interface gebunden. Der Serializer serialisiert aber nur Klassen, keine Interface.
Delphi-Quellcode:
program Project1;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.JSON.Serializers,
System.JSON.Types,
System.SysUtils;
{$M+}
type
IFooOne = interface
['{1DA05420-61BD-404F-BD6F-15D638FE0CB5}']
function GetOneProp(): Integer;
procedure SetOneProp(Value: Integer);
property OneProp: Integer read GetOneProp write SetOneProp;
end;
IFooSecond = interface
['{0D31D4A7-F31A-4B1A-8767-0DBD08BD97EA}']
function GetSecondProp(): string;
procedure SetSecondProp(const Value: string);
function GetSecondObj(): IFooOne;
procedure SetSecondObj(const Value: IFooOne);
function ToJson(): string;
property SecondProp: string read GetSecondProp write SetSecondProp;
property SecondObj: IFooOne read GetSecondObj write SetSecondObj;
end;
TFooOne = class(TInterfacedObject, IFooOne)
strict private
FOneProp: Integer;
private
function GetOneProp(): Integer;
procedure SetOneProp(Value: Integer);
end;
[JsonSerialize(TJsonMemberSerialization.&In)]
TFooSecond = class(TInterfacedObject, IFooSecond)
strict private
[JsonName('SecondProp')] [JsonIn] FSecondProp: string;
[JsonName('SecondObj')] [JsonIn] FSecondObj: IFooOne;
private
function GetSecondProp(): string;
procedure SetSecondProp(const Value: string);
function GetSecondObj(): IFooOne;
procedure SetSecondObj(const Value: IFooOne);
public
function ToJson(): string;
end;
{$M-}
{ TFooOne }
function TFooOne.GetOneProp: Integer;
begin
Result := FOneProp;
end;
procedure TFooOne.SetOneProp(Value: Integer);
begin
FOneProp := Value;
end;
{ TFooSecond }
function TFooSecond.GetSecondProp(): string;
begin
Result := FSecondProp;
end;
function TFooSecond.GetSecondObj(): IFooOne;
begin
Result := FSecondObj;
end;
procedure TFooSecond.SetSecondProp(const Value: string);
begin
FSecondProp := Value;
end;
procedure TFooSecond.SetSecondObj(const Value: IFooOne);
begin
FSecondObj := Value;
end;
function TFooSecond.ToJson: string;
var
Serializer: TJsonSerializer;
begin
Serializer := TJsonSerializer.Create;
try
Serializer.Formatting := TJsonFormatting.Indented;
Result := Serializer.Serialize(Self);
finally
Serializer.Free;
end;
end;
var
Return: string;
FooImpl1: IFooOne;
FooImpl2: IFooSecond;
begin
ReportMemoryLeaksOnShutdown := True;
FooImpl1 := TFooOne.Create;
FooImpl1.OneProp := 4711;
FooImpl2 := TFooSecond.Create;
FooImpl2.SecondProp := 'My second property.';
FooImpl2.SecondObj := FooImpl1;
Return := FooImpl2.ToJson;
Writeln(Return);
Writeln('');
Writeln('Press any key...');
ReadLn;
end.
Das Ergebnis sieht dann so aus:
Code:
{
"SecondProp": "My second property.",
"SecondObj": {}
}
anstatt:
Code:
{
"SecondProp": "My second property.",
"SecondObj": {
"FOneProp": 4711,
"FRefCount": 2
}
}
Weiß jemand wie ich das Interface Property Serialisieren kann ohne eine Instanzvariable daraus zu machen und mich dann um die Freigabe zu kümmern?
Die Doku von Embarcadero zu TJsonSerializer ist nicht gerade voll mit Beispielen.
Danke schon mal.