How to avoid having duplicate objects in WCF over protobuf

Viewed 500

I've a small units tests to test circular dependencies.

My object is the following:

[ProtoContract]
public class Node
{
    [ProtoMember(1)]
    public String Name { get; set; }

    [ProtoMember(2,AsReference = true)]
    public List<Node> Childs { get; set; }

    public Node()
    {
        Childs = new List<Node>();
    }
}

And the following service:

[ServiceContract]
public interface INodeService : IService
{
    [OperationContract]
    Task<Node> GetCyclicNodes();
}

public class NodeService : Service, INodeService
{
    public async Task<int> Add(int a, int b)
    {
        return a + b;
    }

    public async Task<Node> GetCyclicNodes()
    {
        Node nodeA = new Node() {Name = "Node A"};
        Node nodeB = new Node() {Name = "Node B"};
        Node nodeC = new Node() {Name = "Node C"};
        nodeA.Childs.Add(nodeB);
        nodeB.Childs.Add(nodeC);
        nodeC.Childs.Add(nodeA);
        return nodeA;
    }
}

On client side I count the number of objects:

    private int CountNodes(Node node, List<Node> countedNodes = null)
    {
        if (countedNodes == null)
        {
            countedNodes = new List<Node>();
        }
        if (countedNodes.Contains(node))
        {
            return 0;
        }
        else
        {
            countedNodes.Add(node);
            int count = 1;
            foreach (Node nodeChild in node.Childs)
            {
                count += CountNodes(nodeChild, countedNodes);
            }
            return count;
        }
    }

When I call it, I would expect to receive the whole hierarchy, with 3 unique objects instances(one for "Node A", "Node B", "Node C").

But it seems that I've 4 differents objects, two times the object A.

Since my class is not AsReferenceDefault, I'm a little bit afraid that it doesn't see it is the same object than the one it gets.

In my case, I've a very big business model(~500 different models), which all herits from the same root class. Every class can be technically(in a model point of view) referenced by another one, it's always very clear that every class a ONE and ONLY ONE owner, and the other ones are only referring to it. Is this something I can do with protobuf?

Because even I don't know what is happening behind the scene when using references, I'm a little bit afraid it implies an unique ID is put on EVERY field, even if they are not referenced

EDIT

In fact, even while setting the AsReferenceDefault = true on the ProtoContract, I still get 4 objects instead of 3, now I'm a little bit lost.

EDIT 2

I did make another test, I tried to have a Container class(my differents operations return now some Task<Container<Node>>. This Container contains only one property which is marked as AsReference = true. Now it works, I've only 3 instances.

But seems to implies that I didn't understood properly the AsReference mechanism. I was thinking it was possible to have one "owner" of the object, which is NOT marked with the AsReference=true, and all the other ones that also reference this object would be AsReference =true. But if I understand properly, this will result in having 2 different instances?

If yes, I don't understand the advantage of setting AsReference = true over the AsReferenceDefault?

Did I understood properly?

1 Answers
Related