I want to create a generic serializer that is able to serialize and deserialize data provided in a specific enforced format. Lets say I have implemented two data structures with atributes (for JSON and MessagePack) and a simple serializer implementation:
public List<JsonHandFrame> Frames { get; set; }
public class JsonHandFrame
[JsonProperty("leftHand")]
public JsonHand LeftHand { get; set; }
[JsonProperty("rightHand")]
public JsonHand RightHand { get; set; }
public JsonJoint[] Joints { get; set; }
public float JsonX { get; set; }
public float JsonY { get; set; }
public float JsonZ { get; set; }
<code>[Serializable]
public class JsonDataset
{
[JsonProperty("frames")]
public List<JsonHandFrame> Frames { get; set; }
}
[Serializable]
public class JsonHandFrame
{
[JsonProperty("leftHand")]
public JsonHand LeftHand { get; set; }
[JsonProperty("rightHand")]
public JsonHand RightHand { get; set; }
}
[Serializable]
public class JsonHand
{
[JsonProperty("joints")]
public JsonJoint[] Joints { get; set; }
}
[Serializable]
public class JsonJoint
{
[JsonProperty("x")]
public float JsonX { get; set; }
[JsonProperty("y")]
public float JsonY { get; set; }
[JsonProperty("z")]
public float JsonZ { get; set; }
}
</code>
[Serializable]
public class JsonDataset
{
[JsonProperty("frames")]
public List<JsonHandFrame> Frames { get; set; }
}
[Serializable]
public class JsonHandFrame
{
[JsonProperty("leftHand")]
public JsonHand LeftHand { get; set; }
[JsonProperty("rightHand")]
public JsonHand RightHand { get; set; }
}
[Serializable]
public class JsonHand
{
[JsonProperty("joints")]
public JsonJoint[] Joints { get; set; }
}
[Serializable]
public class JsonJoint
{
[JsonProperty("x")]
public float JsonX { get; set; }
[JsonProperty("y")]
public float JsonY { get; set; }
[JsonProperty("z")]
public float JsonZ { get; set; }
}
<code>[MessagePackObject]
public List<MPHandFrame> Frames { get; set; }
public Hand MPLeftHand { get; set; }
public Hand MPRightHand { get; set; }
public MPJoint[] Joints { get; set; }
public float MPX { get; set; }
public float MPY { get; set; }
public float MPZ { get; set; }
<code>[MessagePackObject]
public class MPDataset
{
[Key(0)]
public List<MPHandFrame> Frames { get; set; }
}
[MessagePackObject]
public class MPHandFrame
{
[Key(0)]
public Hand MPLeftHand { get; set; }
[Key(1)]
public Hand MPRightHand { get; set; }
}
[MessagePackObject]
public class MPHand
{
[Key(0)]
public MPJoint[] Joints { get; set; }
}
[MessagePackObject]
public class MPJoint
{
[Key(0)]
public float MPX { get; set; }
[Key(1)]
public float MPY { get; set; }
[Key(2)]
public float MPZ { get; set; }
}
</code>
[MessagePackObject]
public class MPDataset
{
[Key(0)]
public List<MPHandFrame> Frames { get; set; }
}
[MessagePackObject]
public class MPHandFrame
{
[Key(0)]
public Hand MPLeftHand { get; set; }
[Key(1)]
public Hand MPRightHand { get; set; }
}
[MessagePackObject]
public class MPHand
{
[Key(0)]
public MPJoint[] Joints { get; set; }
}
[MessagePackObject]
public class MPJoint
{
[Key(0)]
public float MPX { get; set; }
[Key(1)]
public float MPY { get; set; }
[Key(2)]
public float MPZ { get; set; }
}
<code>public interface ISerializer<T>
public byte[] Serialize(T handDataset);
public T Deserialize(byte[] data);
public class JsonSerializer: ISerializer<JsonDataset>
public byte[] Serialize(JsonDataset handDataset)
string json = JsonConvert.SerializeObject(handDataset);
return System.Text.Encoding.UTF8.GetBytes(json);
public JsonDataset Deserialize(byte[] data)
string json = System.Text.Encoding.UTF8.GetString(data);
return JsonConvert.DeserializeObject<JsonDataset>(json);
public class MessagePackSerializer: ISerializer<MPDataset>
public byte[] Serialize(MPDataset handDataset)
return MessagePack.MessagePackSerializer.Serialize(handDataset);
public MPDataset Deserialize(byte[] data)
return MessagePack.MessagePackSerializer.Deserialize<MPDataset>(data);
<code>public interface ISerializer<T>
{
public byte[] Serialize(T handDataset);
public T Deserialize(byte[] data);
}
public class JsonSerializer: ISerializer<JsonDataset>
{
public byte[] Serialize(JsonDataset handDataset)
{
string json = JsonConvert.SerializeObject(handDataset);
return System.Text.Encoding.UTF8.GetBytes(json);
}
public JsonDataset Deserialize(byte[] data)
{
string json = System.Text.Encoding.UTF8.GetString(data);
return JsonConvert.DeserializeObject<JsonDataset>(json);
}
}
public class MessagePackSerializer: ISerializer<MPDataset>
{
public byte[] Serialize(MPDataset handDataset)
{
return MessagePack.MessagePackSerializer.Serialize(handDataset);
}
public MPDataset Deserialize(byte[] data)
{
return MessagePack.MessagePackSerializer.Deserialize<MPDataset>(data);
}
}
</code>
public interface ISerializer<T>
{
public byte[] Serialize(T handDataset);
public T Deserialize(byte[] data);
}
public class JsonSerializer: ISerializer<JsonDataset>
{
public byte[] Serialize(JsonDataset handDataset)
{
string json = JsonConvert.SerializeObject(handDataset);
return System.Text.Encoding.UTF8.GetBytes(json);
}
public JsonDataset Deserialize(byte[] data)
{
string json = System.Text.Encoding.UTF8.GetString(data);
return JsonConvert.DeserializeObject<JsonDataset>(json);
}
}
public class MessagePackSerializer: ISerializer<MPDataset>
{
public byte[] Serialize(MPDataset handDataset)
{
return MessagePack.MessagePackSerializer.Serialize(handDataset);
}
public MPDataset Deserialize(byte[] data)
{
return MessagePack.MessagePackSerializer.Deserialize<MPDataset>(data);
}
}
As it can be seen there is a quite substantial amount of code duplication when describing types, especially if new ones were to be added. Is there some way to use interfaces or abstract classes to enforce this specific datastructure when new types are added using inheritance? Are there any design patterns which could help in this case? I have tried a few implementations using interfaces and abstract classes but I always end up with code which suggests hiding properties or allows invalid datatype combinations (e. g. if I create an interface for each object in hierarchy in the end I am able to assign MLHandFrames
to JsonDataset
and vice versa). Any suggestions are aprreciated.