В проекте я сейчас использую DataContractSerializer
для сериализации моих данных. И я хотел бы использовать Protobuf
вместо этого по соображениям производительности.
Я использую сериализатор для хранения больших двоичных объектов внутри базы данных, и я хочу сохранить функции управления версиями данных WCF для более удобной обработки изменений контракта данных после выпуска проекта в реальном мире.
Контракты данных этих BLOB-объектов не известны во время компиляции. (Список «расширений» указан в файле конфигурации, поэтому расширения регистрируются DataContracts
, которые они знают во время выполнения)
Однако кажется, что единственный способ сообщить protobuf об известном типе - это атрибут [ProtoInclude]
.
Чтобы быть более конкретным, вот пример того, что я хочу сериализовать.
[DataContract]
public class Mydata
{
[DataMember(Order = 1)]
public int Saved
{
get;
set;
}
}
[DataContract]
public class Container
{
[DataMember(Order = 1)]
public object Data
{
get;
set;
}
}
С DataContractSerializer
вот как я:
[TestMethod]
public void SerializeWithDataContractSerializer()
{
var container = new Container()
{
Data = new Mydata()
{
Saved = 1
}
};
DataContractSerializer serializer = new DataContractSerializer(typeof(Container), new[] { typeof(Mydata) });
var ms = new MemoryStream();
serializer.WriteObject(ms, container);
ms.Position = 0;
var containerSerialized = (Container)serializer.ReadObject(ms);
Assert.AreEqual(((Mydata)container.Data).Saved, ((Mydata)containerSerialized.Data).Saved);
}
С protobuf
здесь, как я хотел сделать (но не возможно Serializer.CreateFormatter<T>()
не принимает параметр knownTypes
):
[TestMethod]
public void SerializeWithProtoBuf()
{
var container = new Container()
{
Data = new Mydata()
{
Saved = 1
}
};
var formatter = Serializer.CreateFormatter<Container>(new[] { typeof(Mydata) });
var ms = new MemoryStream();
formatter.Serialize(ms, container);
ms.Position = 0;
var containerSerialized = (Container)formatter.Deserialize(ms);
Assert.AreEqual(((Mydata)container.Data).Saved, ((Mydata)containerSerialized.Data).Saved);
}
Есть решение?