我有同樣的問題,並且我已經用TypeModel解決了它。它是基於通過它們的名字排序屬性(但它不檢查setter/getter屬性存在或序列化能力給定類型的):
[TestFixture]
public class InferredProtoPoc
{
[Test]
public void UsageTest()
{
var model = TypeModel.Create();
// Dynamically create the model for MyPoco
AddProperties(model, typeof(MyPoco));
// Display the Generated Schema of MyPoco
Console.WriteLine(model.GetSchema(typeof(MyPoco)));
var instance = new MyPoco
{
IntegerProperty = 42,
StringProperty = "Foobar",
Containers = new List<EmbeddedPoco>
{
new EmbeddedPoco { Id = 12, Name = "MyFirstOne" },
new EmbeddedPoco { Id = 13, Name = "EmbeddedAgain" }
}
};
var ms = new MemoryStream();
model.Serialize(ms, instance);
ms.Seek(0, SeekOrigin.Begin);
var res = (MyPoco) model.Deserialize(ms, null, typeof(MyPoco));
Assert.IsNotNull(res);
Assert.AreEqual(42, res.IntegerProperty);
Assert.AreEqual("Foobar", res.StringProperty);
var list = res.Containers;
Assert.IsNotNull(list);
Assert.AreEqual(2, list.Count);
Assert.IsTrue(list.Any(x => x.Id == 12));
Assert.IsTrue(list.Where(x => x.Id == 12).Any(x => x.Name == "MyFirstOne"));
Assert.IsTrue(list.Any(x => x.Id == 13));
Assert.IsTrue(list.Where(x => x.Id == 13).Any(x => x.Name == "EmbeddedAgain"));
}
private static void AddProperties(RuntimeTypeModel model, Type type)
{
var metaType = model.Add(type, true);
foreach (var property in type.GetProperties().OrderBy(x => x.Name))
{
metaType.Add(property.Name);
var propertyType = property.PropertyType;
if (!IsBuiltinType(propertyType) &&
!model.IsDefined(propertyType) &&
propertyType.GetProperties().Length > 0)
{
AddProperties(model, propertyType);
}
}
}
private static bool IsBuiltinType(Type type)
{
return type.IsValueType || type == typeof (string);
}
}
public class MyPoco
{
public int IntegerProperty { get; set; }
public string StringProperty { get; set; }
public List<EmbeddedPoco> Containers { get; set; }
}
public class EmbeddedPoco
{
public int Id { get; set; }
public String Name { get; set; }
}
這就是你運行它得到了什麼。
message EmbeddedPoco {
optional int32 Id = 1;
optional string Name = 2;
}
message MyPoco {
repeated EmbeddedPoco Containers = 1;
optional int32 IntegerProperty = 2;
optional string StringProperty = 3;
}
爲了提高性能,您可以選擇編譯TypeModel,和/或存儲生成的proto以備將來使用。但是請注意,如果poco(普通舊容器對象)不斷髮展,對Protocol Buffer的隱藏依賴可能會長期存在危險。
來源
2015-09-21 11:56:48
Fab
您是否必須隨時存儲這些結果,或者數據是否始終存在?你有多確定兩端會同步?除此之外,它聽起來像應該很好... –