How to avoid duplication of objects in WCF over protobuf

I have small units for testing circular dependencies.

My object is as follows:

[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 the 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 expect to get the whole hierarchy with three instances of unique objects (one for "Node A", "Node B", "Node C").

But it seems that I have 4 different objects, twice the size of A.

Since my class is not AsReferenceDefault , I'm a little afraid that it does not see that it is the same object as the one that it receives.

In my case, I have a very large business model (~ 500 different models) that all use from the same root class. Each class can be technically (from the point of view of the model) referenced by the other, it is always very clear that each class is ONE and ONLY ONE owner, while others refer only to it. Is this something I can do with protobuff?

Because even I don’t know what happens behind the scenes when using links, I’m a little afraid that this means that the unique identifier is placed in the EVERY field, even if they are not referenced

EDIT

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

EDIT 2

I did another test, I tried to create the Container class (my operations with different values ​​now return Task<Container<Node>> . This container contains only one property, which is marked as AsReference = true . Now it works, I have only 3 instances .

But it seems to imply that I did not correctly understand the AsReference mechanism. I thought it was possible to have one β€œowner” of an object that is NOT marked AsReference=true , and all the others that also reference this object will be AsReference =true . But if I understand correctly, will this lead to the presence of two different instances?

If so, I do not understand the benefits of setting AsReference = true over AsReferenceDefault ?

Did I understand correctly?

+7
wcf protocol-buffers protobuf-net
source share
1 answer

It seems to me that the question is similar to this question , where we understood the problem with the root level.

What we had was that for the child, the link is where it is correct, but if the root element was added, the copy was after deserialization.

Our work, which we used for a while (and then we switched to pure JSON), was to add an extra root to the node. With these additional root node links, where deseriliazed is correct. So this could be a problem that you could try.

+1
source share

All Articles