-
Notifications
You must be signed in to change notification settings - Fork 85
NeonFactory & NeonItemFactory
Tip
NeonItemFactory
attribute lets you create different type of objects (without breaking the type compatibility of Delphi)
The NeonItemFactory
attribute is used to (custom) create the items of a collection (array, list, dictionary, etc…), this gives Neon the feature to support heterogeneous collections.
Let’s say you have this classes: TBaseClass, TDerivedClass1, TDerivedClass2, TDerivedClass3
. Now using the NeonItemFactory
attribute if you declare a property of type TBaseClass
you can create items of type TDerivedClass1, TDerivedClass2, TDerivedClass3
. Of course you have to deduce the object type based on the JSON you read from.
So, how does it work?
In order to create an object factory you must derive from a base (and very simple) class: TCustomFactory
and override the virtual abstract method Build
:
/// <summary>
/// Base class for an Object Factory
/// </summary>
TCustomFactory = class abstract(TObject)
public
function Build(const AType: TRttiType; AValue: TJSONValue): TObject; virtual; abstract;
end;
As you can see you have to provide an object as a result but you can decide based on the AType
parameter and the JSON Neon is reading from (for example):
[
{
"$type": "TDerivedClass1",
"Name": "Obj1",
"Prop1": 123
},
{
"$type": "TDerivedClass3",
"Name": "Obj1",
"Prop1": "This is a sample value",
"Prop2": true
},
{
"$type": "TDerivedClass2",
"Name": "Obj1",
"Prop1": [3,5,7,9],
"PropX": "Another sample value"
}
]
Of course the $type
is only in this JSON example, you can have any JSON fragment as a source of your objects as long as you can infer the type of the object to be created from the same JSON fragment! Let see ho to use the NeonItemFactory
attribute:
type
TBaseClass = class
// Base class stuff
end;
TDerivedClass1 = class(TBaseClass)
// DerivedClass1 class stuff
end;
TDerivedClass2 = class(TBaseClass)
// DerivedClass2 class stuff
end;
TDerivedClass3 = class(TBaseClass)
// DerivedClass3 class stuff
end;
TMyClass = class
private
FName: string;
FList: TArray<TBaseClass>;
public
constructor Create;
destructor Destroy; override;
public
property Name: string read FName write FName;
[NeonItemFactory(TBaseClassFactory)]
property List: TArray<TBaseClass> read FList write FList;
end;
Tip
NeonFactory
attribute lets you create different type of objects (without breaking the type compatibility of Delphi)
The NeonFactory
attribute is quite similar to the previous attributeNeonItemFactory
but is used to signal Neon to create a sub-object of a class. Let see an example
type
TLink = class
private
FLinkType: string;
FAddress: string;
public
property LinkType: string read FLinkType write FLinkType;
property Address: string read FAddress write FAddress;
end;
TContainer = class
private
FLink: TLink;
FName: string;
public
property Name: string read FName write FName;
property Link: TLink read FLink write FLink;
end;
var
container: TContainer;
As you can see the TContainer
class has a sub-object but it hasn’t a constructor so the Link properties will be nil
after you create the object container
.
type
...
TContainer = class
private
FLink: TLink;
FName: string;
public
property Name: string read FName write FName;
[NeonFactory(TLinkFactory)]
property Link: TLink read FLink write FLink;
end;
Now if you annotate the Link property with the NeonFactory
attribute Neon will create the object invoking the TLinkFactory
factory.
Warning
You can create new object through the NeonFactory
attribute only if the property/field is nil
Neon Libray • Project Home • paolo's Repositories