Friday, November 21, 2008
Converting Deserialized Objects ... and why

Lightbulbs go on in spurts it seems, you bang your head against a wall for weeks then one day the Gods take pity on you and let you see through a crack in the plaster.

2 things I know I'll forget if I don't put them somewhere and this seems an ok place:

Intro: Doing object serialization VS7 is really simple, you just set the Serializable attribute on all the classes you want to slurp and you're done. Thing is, this type of serialization is not all that helpful. Yes, you now have a second object exactly like the first ... but is that really what you want?

To use such serialization to pass objects across boundaries (whatever they may be) you would have to have State, Business and Database logic all in the object. If you just defined an object to hold state it is pretty worthless as it can't load itself without db logic and can't enforce rules without business logic (unless I missed something in all my books, which is possible). So just using the Serializable attribute means making a pretty fat object definition.

When I asked guru Rockford Lhotka about this at WinDev 2002 in New Orleans he said that we should stop thinking in terms of "Physical layers" and instead think "Logical Layers" and to him that meant that a class that had all the DB and all the Business logic was just fine since you should only call the right methods at the right time even though every method under the sun is defined in the object. (Interfaces could shield you from the noise, but they are still there and tempting.)

VS7 does also offer the ISerializable interface and when you Implement this you have to do a lot more coding but it's not too hard to get the hang of since it's very similar to the old PropertyBag object from VB6. All that extra busy-work coding aside (coding that is so repetitive that it could be turned into an IDE add-in that devs would pay $20 for), ISerializable offers the nice option of being able to serialize into a different Type from the original. That's neat.

The best starting point for trying out ISerializable Rockys' article at http://msdn.microsoft.com/library/en-us/dnadvnet/html/vbnet09252001.asp

It's on Binary Formatted serialization because for one the performance of binary is normally going to be better than doing SOAP/XML and getting the hits of parsing text. With that intro, here's what I don't want to forget, and you may want to remember too:

1) Excellent article, but remember that the release version of the framework requires extra work to get the effect. The article says that you can get the type conversion by starting the Info object filling with

With Info
   .FullTypeName = "TargetNameSpace.TargetClassType"
   ...
End With

And that doesn't work, all you'll get on the Deserialize of the clone is "System.Runtime.Serialization.SerializationException' occurred in mscorlib.dll -- Additional information: Type is not resolved for member" Instead you have to instantiate an object of the target type and use Info.SetType as in:

 

With Info
   Dim x As New TargetClassType()
   .SetType(x.GetType)
   ...
End With

 

Pretty simple (once you figure it out ).

2) Rocky is known as the King of VB Serialization, there were little and big issues we had to work out in the real-world, but Rocky was the first guy who showed and explained VB devs the real concepts and introduced Serialization to most VB professionals so he will always be a great King and if you have not read the Classic Professional VB Business Objects you are missing out (even for VB.net development). That is the pillow, here's the stone:

In that same article mentioned above, Rocky let an important issue slide. In the section on the Serializable attribute he showed that Child Objects are slurped up automatically for you just like simple types, no fuss no muss. But in the section on ISerializable he pulls a fast one ... he ignores the "complex" Child Object in the Clone method (The Child Object in this case is a hashtable of Room objects) and then covers up for it in the targets' Deserialize by having the constructor just create a new HashTable out of the blue! Some serialization, If you have a parent object with Name and Age, and a child Address object your cloned object would have an Address object alright but the values would of course be empty.

To be fair, he wrote that article way back in July 2001 (how time flies, huh?) but still, there are very few Google items on how to get around this... here's a solution that works for me:

The Child Object must also implement ISerializable and must also have a Clone method. Just as the Parent object's Clone method has to return the type you want to pass (Such as "ParentStateOnly")Each of these Clone methods must also return the type you want to pass (Such as a "ChildStateOnly" type)

In the Source Parent GetObjectData method, you get the child to serialize by calling it's clone as in:

...
   .AddValue("MyChild", m_MyChild.Clone)
...

 

In the parent target class' constructor you have to give up the built-in Info.Getxxx methods and instead unpack the child object like this:

...
   m_MyChild = (Info.GetValue("MyChild", _
      GetType(TargetNamespace.ChildStateOnly)))
...

 

It's not as nice and clean as VB5/6's LSET but it's not too different from using manual PropertyBag code, and with this you can have the deep serialization that you want, plus get only the important stuff serialized: the State. Now you can pass the State around and pour it into the properties of Business or DB oriented objects as you desire (or just create your own Undo buffers), getting back what Rocky got us all excited about way back when.

Robert Smith
Kirkland, WA

added September 2002


Print  

pagecomment
  Add Comment



Submit Comment
  View Ratings
50.00%0
40.00%0
30.00%0
20.00%0
10.00%0

Number of Comments 0 , Average of Ratings
  View Comments
No comment.


Privacy Statement  |  Terms Of Use
Copyright 2008 by Robert C. Smith