-
Notifications
You must be signed in to change notification settings - Fork 97
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 TContainerclass 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