Ian
Ian

Reputation: 34489

Serialization - Viewing the Object Graph from a Stream

I'm wondering if there's a way in which I can create a tree/view of a serialised object graph, and whether anyone has any pointers? EDIT The aim being that should we encounter a de-serialization problem for some reason, that we can actually view/produce a report on the serialized data to help us identify the cause of the problem before having to debug the code. Additionally I want to extend this in the future to take two streams (version 1, version 2) and highlight differences between the two of them to help ensure that we don't accidently remove interesting information during code changes. /EDIT

Traditionally we've used Soap or XML serialization, but these are becoming too restricted for our needs, and Binary serialization would generally do all that we need. The reason that this hasn't been adopted, is because it's much harder to view the serialized contents to help fix upgrade issues etc.

So I've started looking into trying to create a view on the serialized information. I can do this from an ISerializable constructor to a certain extent :

public A(SerializationInfo info, StreamingContext context)
{}

Given the serialization info I can reflect the m_data member and see the actual serialized contents. The problem with this approach is

  1. It will only display a branch from the tree, I want to display the entire tree from the root and it's not really possible to do from this position.
  2. It's not a convenient place to interrogate the information, I'd like to pass a stream to a class and do the work there.

I've seen the ObjectManager class but this works on an existing object graph, whereas I need to be able to work from the stream of data. I've looked through the BinaryFormatted which uses an ObjectReader and a __BinaryParser, hooking into the ObjectManager (which I think will then have the entire contents, just maybe in a flat list), but to replicate this or invoke it all via reflection (2 of those 3 classes are internal) seems like quite a lot of work, so I'm wondering if there's a better approach.

Upvotes: 6

Views: 722

Answers (2)

BananaPoop
BananaPoop

Reputation: 121

You could put a List<Child class> in every parent class (Even if there the same)

and when you create a child you immediately place it in that list or better yet declare it whilst adding it the list

For instance

ListName.Add(new Child(Constructer args));

Using this you would serialize them as one file which contains the hierarchy of the objects and the objects themselves.

If the parent and child classes are the same there is no reason why you cannot have dynamic and multi leveled hierarchy.

Upvotes: 1

Vladimir Perevalov
Vladimir Perevalov

Reputation: 4159

In order to achieve what you describe you would have to deserialize whole object graph from stream without knowing a type from which it was serialized. But this is not possible, because serializer doesn't store such information. AFAIK it works in a following way. Suppose you have a couple of types:

class A { bool p1 }
class B { string p1; string p2; A p3}
// instantiate them:
var b = new B { p1 = "ppp1", p2 = "ppp2", p3 = new A { p1 = true} };

When serializer is writing this object, it starts walking object graph in some particular order (I assume in alphabetic order) and write object type and then it's contents. So your binary stream will like this:

[B:[string:ppp1][string:ppp2][A:[bool:true]]]

You see, here there are only values and their types. But order is implicit - like it is written. So, if you change your object B, to suppose

class B { A p1; string p3; string p3;}

Serialzer will fail, because it will try to assing instance of string (which was serialized first) to pointer to A. You may try to reverse engineer how binary serialization works, then you may be able to create a dynamic tree of serialized objects. But this will require considerable effort.

For this purpose I would create class similar to this:

class Node
{
    public string NodeType;
    public List<Node> Children;
    public object NodeValue;
}

Then while you will be reading from stream, you can create those nodes, and recreate whole serialized tree and analyze it.

Upvotes: 0

Related Questions