這是this one的後續問題。我試圖實現的是將我的類替換爲[JsonConstructor]
,以便在沒有進行任何序列化的項目中擺脫對Json.Net的依賴關係。通過我從其他來源收集的信息,使用ContractResolver
是實現某種「爲Foo類型使用代理欄創建實例」的示例(請參閱MongoDB's class map)。對我來說重要的是,我想堅持我的實體中只讀字段,因此我必須使用一些帶參數的工廠方法來創建實例,而在創建過程中將給定參數分配給只讀字段。 (我從一個公共無參數構造函數,一個屬性構造函數,一個私有無參數構造函數,到根本沒有歸屬構造函數,並且每一步都探索了被覆蓋的行爲我的合同分解的方法):使用ContractResolver在Newtonsoft的Json.NET中實現等效於MongoDB的BSON類映射
class Thing
{
public int Id { get; private set; }
public string Name { get; private set; }
//private Thing() { }
//[JsonConstructor]
private Thing(int id, string name)
{
this.Id = id;
this.Name = name;
}
public static Thing Create(int id, string name)
{
return new Thing(id, name);
}
public static object Create2(object[] values)
{
return new Thing((int)values[0], (string)values[1]);
}
}
我的合同解析如下所示:
class CustomResolver : DefaultContractResolver
{
public override JsonContract ResolveContract(Type type)
{
var b = base.ResolveContract(type);
if(type == typeof(Thing))
{
var bb = b as JsonObjectContract;
// figured out the name of the backing field using ILSpy
var prop = typeof(JsonObjectContract).GetField("_creatorParameters",
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
// in order to set the value of property CreatorParameters
// which is used as parameter when OverrideCreator is invoked
prop.SetValue(bb, bb.Properties);
bb.OverrideCreator = new ObjectConstructor<object>(Thing.Create2);
}
return b;
}
}
這是它的用法:
Thing t1 = Thing.Create("Flim", 1);
// Serializer settings
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.ContractResolver = new CustomResolver();
settings.PreserveReferencesHandling = PreserveReferencesHandling.None;
settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
settings.Formatting = Newtonsoft.Json.Formatting.Indented;
string json = JsonConvert.SerializeObject(t1, settings);
Thing t2 = JsonConvert.DeserializeObject<Thing>(json, settings);
它可以像我期望的那樣工作,但是由於我使用反射破解了系統,我相信我正在做一些完全錯誤的事情,並且必須有一種更清晰的方式。有任何想法嗎?
編輯
什麼我都沒有想到直到現在,我有一些類這些都歸功於與[JsonConverter(typeof(SomeSubstituteType))]
這也是我就會改掉,如果我想完全elmininate的depency的。這些類迄今尚未包含在合同解析器類的類型檢查中。有沒有一種優雅的方式可以讓它在沒有屬性的情況下工作,也不需要通過以某種方式將JsonSerializerSettings
另外配置到目前爲止配置的內容來在解析器中添加額外的檢查?
請看看我的編輯。或者我可以做另一個後續問題。 – David
@David - 答案已更新。 – dbc