В protobuf-net ver 2 есть аккуратная опция, которая называется [ProtoMember (2, AsReference = true)]. По большей части, это следующий вопрос:
Мне стало интересно, всегда ли поддерживается ссылочная целостность независимо от того, когда происходит сериализация / десериализация. protobuf-net уже делает это, когда вы используете опцию AsReference ?
Я собрал базовый пример кода для иллюстрации, а затем подумал: «Может быть, мне нужно позаимствовать некоторые идеи из мира ORM?» Должен ли я реализовывать карту личности? Должен ли я как-то сказать protobuf (через делегатов?) Вместо разрешения ссылок на / из значений внешнего ключа.
Ответ, который я хотел бы услышать, заключается в том, что каким-то образом protobuf-net может поддерживать целостность ссылок через границы сборки, даже с типами, которые просто похожи друг на друга.
Тем не менее, вот альтернативная последовательность просто на всякий случай:
a => 1. разрешить ссылку на первичный ключ int, 2. сериализовать
b => 3. десериализация, 4. преобразование первичного ключа int в ссылку
Примечания / Ограничения:
классы являются зеркальным отображением друг друга, но перекомпилируются в каждой сборке.
граф объектов должен быть одинаковым независимо от того, когда объекты сериализуются. то есть A.ref = B (сериализация / десериализация). C.ref = B (сериализация / десериализация).
Пример для обсуждения:
using System;
using System.Collections.Generic;
using ProtoBuf;
namespace protobuf_question
{
class Program
{
static void Main(string[] args)
{
var a = new A() { key = 1 };
var b = new B() { A = a, key = 2 };
}
}
[ProtoContract]
public class A
{
[ProtoMember(1)]
public int key { get; set; }
}
[ProtoContract]
public class B
{
[ProtoMember(1)]
public int key { get; set; }
[ProtoMember(2,AsReference=true)]
public A A { get; set; } // a reference
}
[ProtoContract]
public class IdentityMap<T,TKey>
{
public static readonly IdentityMap<T,TKey> instance = new IdentityMap<T,TKey>(); // singleton
private Dictionary<string, T> identitySpace { get; set; }
public IEnumerable<string> GetIdentitySet (/* some criteria */)
{
// used for serializing with reference safety between assemblies.
throw new NotImplementedException();
}
public TKey GetKey(T reference)
{
// map object reference to identity map; return identity.
throw new KeyNotFoundException();
}
}
}