Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Complex objects modeling
Message
From
23/11/2018 10:16:47
 
General information
Forum:
Visual FoxPro
Category:
Visual FoxPro and .NET
Environment versions
Visual FoxPro:
VFP 9 SP2
OS:
Windows 10
Miscellaneous
Thread ID:
01662805
Message ID:
01663739
Views:
60
Of course, there's ways to circunveil that problems, not to mention that inspecting the object is not an easy task too. :(

But that's what in the end I managed to solve with underscore

( a temporal observer/constructor with new empty based objects with span life automatically limited by the scope of with - endwith )

By now a next improvement I'll incorportate is adding a 3rd parameter to specify the base class for the new dynamic ( observed ) object:
with _( .myCustomObject, '','myBaseClass' ) && like newobject() 
and shortcuts to construct deep paths at once like:
with  _(  m.myProduct )
    
    ._('info.about.productNumber') = 'zsaasd22112zz'

endwith
and directly:
    _( m.myproduct, 'info.about.productNumber' ) = 'zsaasd22112zz'  
Of course, this must pass the real use cases test to see if I find myself using it or not.


>I see what you mean - certainly it's a problem when serializing. For my own serializer I had to add some special logic to handle the dynamic type.
>
>But there are a couple of things that help here. First I think some additional code is needed to be able to return native properties of the dynamic object so you can return properties like class name which is key for at least my own serializer which needs to understand and check for special types.
>
>Code in a Github Gist
>
>For that to work I need to change the accessor to:
>
>
>FUNCTION THIS_Access(lcPropertyOrMethod)
>
>
>If Lower(lcPropertyOrMethod) ==  "__oreference" OR ;  
>   Pemstatus(this,lcPropertyOrMethod,5)
>	RETURN this
>Endif
>
>If !Pemstatus(this.__oReference,lcPropertyOrMethod,5)
>   AddProperty(this.__oReference,lcPropertyOrMethod,Createobject('wwDynamic'))
>ENDIF
>	
>RETURN this.__oReference
>ENDFUNC
>
>
>Notice the first check to see if the property exists on the dynamic host - this allows `loHost.Class` to be accessible. If you don't do this loItem.Class returns type object which is a problem, so I think that bit is unfortunately required no matter what.
>
>Then for serialization I can now check specifically for the `wwDynamic` type and if I see that return the `__oReference` instead of the host which allows serialization of just the data elements and not the host. Note this is specific to my wwJsonSerializer implementation but I suspect something similar can be used in other implementations:
>
>
>CASE lcValueType = "C" AND LOWER(lvValue.Class) = "wwdynamic"
>    this.WriteObject( EVALUATE("lvValue.__oReference"))		    		
>
>
>This code basically skips over the wwDynamic instance and just serializes the reference.
>
>This means that this code:
>
>
>DO wwDynamic
>DO wwJsonSerializer
>
>CLEAR
>
>loItem = CREATEOBJECT("wwDynamic")
>
>? loItem.Class  && wwDynamic
>
>loItem.Bogus = "This is bogus"
>loItem.Entered = DATETIME()
>
>? loItem.Bogus
>? loItem.Entered
>
>
>WITH loItem.Child 
>  .Bogus2 = "Child Bogus"
>  .Entered2 = DATETIME()
>
>   ? .Bogus2
>   ? .Entered2
>ENDWITH
>
>
>loSer = CREATEOBJECT("wwJsonSerializer")
>lcJson = loSer.Serialize(loItem,.T.)
>
>? lcJson
>_cliptext = lcJson
>
>
>
>produces this straight forward JSON:
>
>
>{
>  "bogus": "This is bogus",
>  "child": {
>    "bogus2": "Child Bogus",
>    "entered2": "2018-11-23T06:38:18Z"
>  },
>  "entered": "2018-11-23T06:38:18Z"
>}
>
>
>which is what you'd expect for a raw DTO.
>
>Unfortunately that additional check for the parent object adds yet another perf hit to the accessor, but hey at least it works properly with the serializer and the base properties now.
>
>
>+++ Rick ---
>
>
>>>>Indeed, I started working with a similar object like the one you propose but that only allowed me to work with new objects based on the
>>>>expandobject-like class ( can't add properties to existing ones ) and did not offer the use of with..endwith constructors to create new
>>>>members on the fly.
>>>
>>>Hmmm... that should work. But in any case even if it doesn't you still could benefit from just assigning `CREATEOBJECT("nfDyn")` - then you can use either direct assignment or the constructor approach.
>>>
>>>Either way this is really cool. I'm just really blown away I've missed this particular thing in all these years (THIS_Access()) because I've wanted to do this sort of thing myself for a number of things (that I now no longer remember :-)). Definitely can see it useful for user object contruction for returning as result values especially in service type application where I often have to wrap results into a service header object. I use ADDPROPERTY() for this today which is cumbersome although it works. For those use cases this will be perfect (ie. non-high perf impacts).
>>>
>>>Again thanks for posting and giving me a few new ideas...
>>>
>>>+++ Rick ---
>>>
>>>>
>>>>I use it basically to make dynamic changes to DTOs , so Vfp can do real message based communications with ease.
>>>>
>>>>Configuration objects, parameter objects can benefit too; but I'm rounding a definitive spec to get Intellisense to work with object constructor functions that make use of _()
>>
>>Hi Rick, I see what you mean ( sorry for not checking well your code.. been on very busy day! ) you are right with.. .endwith works
>> using your sample.. You made me hesitate for a minute and wonder why I did not did it that way. And now I remember I did it like that before.. you are using a decorator. I started with a similar approach too but it has many drawbacks when it's used just to extend properties and not functionallity: To modify existing objects you end up with 2 objects ( the one you need and the decorator ) and dynamic objects must be based on relation/custom/line wich adds noise ( strange properties, events and methods ) to what we need to be a simple DTO.
>>
>>Thanks again for showing your enthusiasm about this. :) I'm sure Vfp just needs a little here and there..
>>Any suggestions, improvements, bugs..you know..
>>
>>Marco
>>@nfoxProject
@nfoxdev
github.com/nfoxdev
Previous
Reply
Map
View

Click here to load this message in the networking platform