This class allows you to create or extend an object with 'dynamic' properties by simply referencing non-existing properties on the instance. Any non-existing properties you reference will automatically be created - this model is similar to the way JavaScript or Expando objects work.
In essence this is a cleaner and non-declarative way to write ADDPROPERTY()
logic. This makes a great tool for creating complex objects on the fly in user code which is especially useful when creating data transfer objects for JSON or XML Services to transmit.
Here's an example of what you can do:
*** Extend an existing object
loCust = CREATEOBJECT("cCustomer")
loItem = CREATEOBJECT("wwDynamic",loCust)
*** Alternately you create a new object (EMPTY class)
* loItem = CREATEOBJECT("wwDynamic")
*** Add new properties that don't exist on cCustomer
loItem.Bogus = "This is bogus"
loItem.Entered = DATETIME()
? loItem.Bogus
? loItem.Entered
*** You can even create nested objects as a chain
loItem.oChild.Bogus = "Child Bogus"
loItem.oChild.Entered = DATETIME()
? loItem.oChild.Bogus
? loItem.oChild.Entered
*** Access original cCustomer props and methods
? loItem.cFirstName
? loItem.cLastName
? loItem.GetFullName()
Help with JSON Serialization and Property Casing
For JSON serialization you can also use the explicit .AddProp()
method which automatically sets an internal __PropertyNameOverrides
list for non lower-cased property names. By default properties are JSON serialized as lower case, and this override list allows for proper casing on property names.
loMessage = CREATEOBJECT("wwDynamic")
loMessage.sid = "" && prop is non-cased (lower)
loMessage.AddProp("dateCreated", DATETIME())
loMessage.AddProp("dateUpdated", DATETIME())
loMessage.AddProp("dateSent",DATETIME())
loMessage.AddProp("accountSid","")
loMessage.AddProp("apiVersion","")
*** Empty Value creates wwDynamic instance
loMessage.AddProp("fileInfo")
loMessage.FileInfo.AddProp("fileTime", DateTime())
loMessage.FileInfo.attribute = "A" && prop is non-cased (lower)
* "dateCreated,dateUpdated,dateSent,accountSid,apiVersion,fileInfo,fileTime"
? loMessage.__PropertyNameOverrides
? loMessage.DateCreated
? loMessage.DateUpdated
loSer = CREATEOBJECT("wwJsonSerializer")
? loSer.Serialize(loMessage, .T.) && produces properly cased property names
which produces the following serialized JSON:
{
"accountSid": "",
"apiVersion": "",
"dateCreated": "2020-01-02T21:23:14Z",
"dateSent": "2020-01-02T21:23:14Z",
"dateUpdated": "2020-01-02T21:23:14Z",
"fileInfo": {
"attribute": "A",
"fileTime": "2020-01-02T21:23:14Z"
},
"sid": ""
}
Remarks
Performance Notice:
This code uses anTHIS_Access()
accessor method to intercept every property and method access and then checks to see whether that property/method exists. This has a bit of overhead and is considerably slower than direct object property/method access. Use with care in critical path operations and test for performance carefully.
Class Members
Member | Description | |
---|---|---|
AddProp |
This method explicitly adds a new property to this wwDynamic instance and it automatically adds the property to the __PropertyNameOverrides list which is used during JSON serialization to produce properly cased serialization output.o.AddProp(lcProperty, lvValue) |
|
GetProp |
Retrieves a value from a dynamic property. o.GetProp(lcProperty) |
|
Init |
The constructor allows you to pass in an existing object reference that is then extended with any properties you assign. o.Init(loExistingInstance) |
|
__PropertyNameOverrides |
If using AddProperty() to add properties the property name is added to this property. This property is used during JSON serialization to automatically provide proper casing. |
|
__Reference |
The internal reference of the raw object that holds the actual values for this dynamic instance. |
See also:
Class wwDynamic© West Wind Technologies, 2024 • Updated: 01/02/20
Comment or report problem with topic