我是一个小单元测试来测试循环依赖。
我的目标如下:
[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>();
}
}
以下服务:
[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;
}
}
在客户端,我计算对象的数量:
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;
}
}
当我调用它时,我希望接收整个层次结构,包含3个唯一对象实例(一个用于&#34;节点A和#34;,&#34;节点B&#34;,&#34;节点C&#34;。)
但似乎我有4个不同的对象,是对象A的两倍。
由于我的班级不是AsReferenceDefault
,我有点担心它看不到它与它得到的对象相同。
就我而言,我是一个非常大的商业模式(约500种不同的模型),它们都来自同一个根类。每个类在技术上(在模型的角度来看)都可以被另一个类引用,它总是非常清楚每个类只有一个且只有一个所有者,而其他类只是指它。 这是我可以用protobuf做的事吗?
因为即使我不知道在使用引用时幕后发生了什么,我有点害怕它意味着每个字段都会放置一个唯一的ID,即使它们没有被引用
修改
事实上,即使在AsReferenceDefault = true
上设置ProtoContract
,我仍然会获得4个对象而不是3个,现在我有点迷失了。
编辑2
我做了另一个测试,我尝试了一个Container类(我的不同操作现在返回一些Task<Container<Node>>
。这个Container只包含一个标记为AsReference = true
的属性。现在它可以工作了,我和#39;只有3个实例。
但似乎暗示我没有正确理解AsReference
机制。我以为有可能有一个&#34;所有者&#34;未标记AsReference=true
的对象,以及引用此对象的所有其他对象将为AsReference =true
。但如果我理解正确,这将导致有两个不同的实例?
如果是,我不明白将AsReference = true
设置为AsReferenceDefault
的优势吗?
我理解得对吗?
答案 0 :(得分:1)
对我来说,看起来问题类似于this question,我们意识到根级实体存在问题。
我们还得到的是,对于子对象,引用的位置是正确的,但是如果再次引用了根项,则在反序列化后副本就在那里。
我们使用了一段时间(然后我们切换到纯JSON)的解决方法是添加一个额外的根节点。使用这个额外的根节点引用正确的deseriliazed。所以这可能是你可以尝试的解决方法。