私はMarc GravellのProtoBuf-netライブラリ(r480、net20)を使用して、既知のタイプの辞書<object, object>
を含むカスタムクラスをシリアライズ/デシリアライズします。サーバー/クライアントのシナリオ(両方のC#)で使用されます。
これは、BinaryFormatterを使用した現在のアプローチを置き換えます。
基礎として、私はここで作られた提案を以下のよ: protobuf-and-listobject-how-to-serialize-deserialize、ここprotobuf-and-listobject-how-to-serialize-deserializeを。Protobuf-net:Dictionary <object、object>を含むカスタムクラスをシリアライズ
現在のアプローチは、私がいるProtobufネットに精通誰かが私にそれを改善する方法についてのヒントを与えることができることを願っています、しかし、いくつかの欠点を有しています。 OnSerialising()呼び出しで<ProtoObject, ProtoObject>
を辞書に辞書<object, object>
の
- コピー。
- 新しいタイプ(それぞれがProtoObject.Create(オブジェクトobj)にProtoIncludeタグと対応するキャストロジックを必要とする)を追加する際のメンテナンスオーバーヘッド
- 必要なタイプはすべてProtoObjectによって認識されている必要があります。これにより、プロジェクト間の循環参照の問題が発生しますが、プロジェクト構造のより大きなリファクタリングによって解決することができます。
理想的には私はRuntimeTypeModelのアプローチを使用したいが、私は(クライアントにTypeModel DLLをコンパイルして送信する?)私は種類のクライアントに認識させることができる方法が表示されません。
はまた、最初のトピックでは、マルクGravellは、今後の「ランタイム拡張可能なスキーマは」ものはまだ実装されている場合、誰もが知っている助けることができることを、彼らがどのように機能するかを言及しましたか?
私は私が得るものは何でも応答のために非常に感謝しています、私はもっと何かを明確にすることができますなら、私に知らせてください。
とにかく、彼の素晴らしいライブラリのMarc Gravellに感謝します:)。
ここでは、コードです:あなたがかもしれませんが、単純にDictionary<object,object>
をシリアル化
[Serializable]
[ProtoContract]
public class Attributes : IXmlSerializable, IEnumerable, IEquatable<Attributes>, ICloneable
{
// Non ProtoBuf-net relevant code was removed
private Dictionary<object, object> attributes = new Dictionary<object, object>();
[ProtoMember(1)]
private Dictionary<ProtoObject, ProtoObject> protoDictionary;
[OnSerializing]
public void OnSerializing(StreamingContext context)
{
this.protoDictionary = new ProtoDictionary();
foreach (var attribute in attributes)
{
this.protoDictionary.Add(ProtoObject.Create(attribute.Key), ProtoObject.Create(attribute.Value));
}
}
[OnDeserialized]
public void OnDeserialized(StreamingContext context)
{
if (this.protoDictionary != null)
{
this.attributes = new SerializableHashtable();
foreach (var o in this.protoDictionary)
{
this.attributes.Add(o.Key.Value, o.Value.Value);
}
}
}
}
[ProtoContract]
[ProtoInclude(1, typeof(ProtoObject<bool>))]
[ProtoInclude(2, typeof(ProtoObject<byte>))]
[ProtoInclude(3, typeof(ProtoObject<sbyte>))]
[ProtoInclude(4, typeof(ProtoObject<ushort>))]
[ProtoInclude(5, typeof(ProtoObject<short>))]
[ProtoInclude(6, typeof(ProtoObject<uint>))]
[ProtoInclude(7, typeof(ProtoObject<int>))]
[ProtoInclude(8, typeof(ProtoObject<ulong>))]
[ProtoInclude(9, typeof(ProtoObject<long>))]
[ProtoInclude(10, typeof(ProtoObject<float>))]
[ProtoInclude(11, typeof(ProtoObject<double>))]
[ProtoInclude(12, typeof(ProtoObject<decimal>))]
[ProtoInclude(13, typeof(ProtoObject<string>))]
[ProtoInclude(20, typeof(ProtoObject<Vector2F>))]
[ProtoInclude(21, typeof(ProtoObject<Vector3F>))]
[ProtoInclude(22, typeof(ProtoObject<Shape>))]
[ProtoInclude(23, typeof(ProtoObject<SharedUser>))]
[ProtoInclude(24, typeof(ProtoObject<SharedShip>))]
//[ProtoInclude(25, typeof(ProtoObject<IVehicleConfiguration>))] // Requires Steering dll -> cyclic reference
[ProtoInclude(26, typeof(ProtoObject<DroneState>))]
[ProtoInclude(27, typeof(ProtoObject<BuffCode>))]
[ProtoInclude(28, typeof(ProtoObject<ItemAttribute>))]
[ProtoInclude(40, typeof(ProtoObject<List<int>>))]
public abstract class ProtoObject
{
protected ProtoObject()
{
}
// Replaces public static ProtoObject<T> Create<T>(T value)
// in order to use the actual type of the object
public static ProtoObject Create(object obj)
{
if (obj is bool)
{
return new ProtoObject<bool>((bool)obj);
}
if (obj is byte)
{
return new ProtoObject<byte>((byte)obj);
}
// etc. for all required types
return null;
}
public static ProtoObject Create(bool obj)
{
TypeModel.Add(obj.GetType(), true);
return new ProtoObject<bool>(obj);
}
public static ProtoObject Create(byte obj)
{
return new ProtoObject<byte>(obj);
}
// ... public static ProtoObject Create(type obj) -> for all required types
public object Value
{
get { return ValueImpl; }
set { ValueImpl = value; }
}
protected abstract object ValueImpl { get; set; }
}
[ProtoContract]
public sealed class ProtoObject<T> : ProtoObject
{
public ProtoObject()
{
}
public ProtoObject(T value)
{
Value = value;
}
[ProtoMember(1)]
public new T Value { get; set; }
protected override object ValueImpl
{
get { return Value; }
set { Value = (T)value; }
}
public override string ToString()
{
return Value.ToString();
}
}
あなたの答えマルクいただきありがとうございます。私は現在、カスタムシリアル化を実装しています。できる限り、Protobuf-netを使用します。 –