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?