Arcady,
This is an example of a .NET wrapper for a class that has a complex property (the code is in VB.NET):
Public Class Class1 ' Third party class
Property Prop1 As Integer
Property Prop2 As Integer
Public Function Sum() As Integer
Return Prop1 + Prop2
End Function
End Class
Public Class Class2 ' Third party class
Property Prop3 As Integer
Property Prop4 As New Class1
Public Function Sum() As Integer
Return Prop3 + Prop4.Sum()
End Function
End Class
Public Class Class2W ' Wrapper class for Class2
Public C2 As New Class2
Property Prop3 As Integer
Get
Return C2.Prop3
End Get
Set(value As Integer)
C2.Prop3 = value
End Set
End Property
Property Prop4_Prop1 As Integer
Get
Return C2.Prop4.Prop1
End Get
Set(value As Integer)
C2.Prop4.Prop1 = value
End Set
End Property
Property Prop4_Prop2 As Integer
Get
Return C2.Prop4.Prop2
End Get
Set(value As Integer)
C2.Prop4.Prop2 = value
End Set
End Property
Public Function Sum() As Integer
Return Prop3 + C2.Prop4.Sum()
End Function
End Class
This is how Class1 and Class2W (the wrapper class for Class2) are used in PowerBuilder:
DotNetAssembly ldn_assembly
ldn_assembly = Create DotNetAssembly
String ls_dll
ls_dll = "C:\Datos\VB.NET2017\TEST2\bin\Debug\Test.dll"
// Load assembly
Long ll_return
ll_return = ldn_assembly.LoadWithDotNetFrameWork(ls_dll)
// Check for errors
If ll_return < 0 then
Messagebox("Load Assembly", "Return: " + string(ll_return) + "~r~rLoad of "+ls_dll+" failed.~r~r" + ldn_assembly.ErrorText)
Return
End if
// Declare and create DotNetObject #1
DotNetObject ldn_obj1
ldn_obj1 = Create DotNetObject
// Create instance of Class1 and bind it to DotNetObject #1
ll_return = ldn_assembly.CreateInstance ("Test.Class1", ldn_obj1)
// Check for errors
If ll_return < 0 then
Messagebox("Create Instance", "Return " + string(ll_return) + "~r~rInstance creation of Test.Class1 failed.")
Return
End if
// Assign values to properties
ldn_obj1.Prop1 = 10
ldn_obj1.Prop2 = 20
// Perform sum
long ll_s1
ll_s1 = ldn_obj1.Sum()
MessageBox("Sum1", ll_s1) // 30
// Declare and create DotNetObject #2
DotNetObject ldn_obj2
ldn_obj2 = Create DotNetObject
// Create instance of Class2W and bind it to DotNetObject #2
ll_return = ldn_assembly.CreateInstance ("Test.Class2W", ldn_obj2)
// Check for errors
If ll_return < 0 then
Messagebox("Create Instance", "Return " + string(ll_return) + "~r~rInstance creation of Test.Class2W failed.")
Return
End if
// Assign values to properties
ldn_obj2.Prop3 = 50
ldn_obj2.Prop4_Prop1 = 100
ldn_obj2.Prop4_Prop2 = 200
// Perform sum
long ll_s2
ll_s2 = ldn_obj2.Sum()
MessageBox("Sum2", ll_s2) // 350
This would work for very simple classes, but our interfaces (which currently work with OLE object) are much more complex. We use them for fiscalzation and credit card processing, so they have dozens of complex properties and functions. So, the approach you stated is not cost-effective. Unless we find a simple way to convert a generic class into a JSON string and vice-versa, we will have to stay with OLE.
Now, the proposal of serializing a class to a XML or JSON string and deserializing it back to an NVO does not make much sense to me IF you still need to access the methods or functions within the class. You will solve the "data" part but not the "methods or functions" part. We are not talking here about Web APIs but COM/.NET Interop which is different.
So, my advise is that for now and until Appeon extends the functionality of the DotNet objects and .NET Importer, you should continue using the OLE path, that is, the COM Callable Wrapper path. Bruce Armstrong has an excelent and very detailed video loaded in PowerBuilder TV that you can watch to understand better this subject. Here is the link: https://www.powerbuildertv.com/index.php/en/component/content/article/9-recording/206-using-net-assemblies-with-powerbuilder-recording