コンストラクターにバージョン番号が必要なため、最初に情報を追加するときは注意がVersion
必要です。これにより、新しい DTO に逆シリアル化するたびに同じコンストラクターが使用されると同時に、各呼び出しに暗黙的なバージョンが割り当てられます。
残念ながら、元の DTO には Version がないため、ワイヤ上にシリアル化されていないため、暗黙的に割り当てられた Version フィールドをオーバーライドすることはありません。
これを回避する (そしてコンストラクターで暗黙的に割り当てられたバージョン番号を保持する) には、逆シリアル化で使用されるバージョンを効果的にリセットする必要があります。
JSON/JSVJsConfig.ModelFactory
シリアライザーで on App_Start をオーバーライドすることでこれを行うことができます (つまり、AppConfig で)。これにより、デシリアライゼーションで使用される各 POCO タイプに対して作成されたインスタンスを制御できます。
この場合、バージョンを持つ DTO をリセットして0
、バージョン番号のない DTO が割り当てられ、バージョン番号を持つ DTO0
がそれをオーバーライドするように戻します。
JsConfig.ModelFactory = type => {
if (typeof(IHasVersion).IsAssignableFrom(type))
{
return () => {
var obj = (IHasVersion)type.CreateInstance();
obj.Version = 0;
return obj;
};
}
return () => type.CreateInstance();
};
IHasVersion
ここでは簡単にするために明示的なインターフェイスを使用していますが、リフレクションを使用して、バージョン番号を含む型を簡単に検出して再割り当てすることもできます。
暗黙的に割り当てられたバージョン番号を持つ DTO に逆シリアル化する Version プロパティのない元の DTO の例を次に示します。
public class Dto
{
public string Name { get; set; }
}
public interface IHasVersion
{
int Version { get; set; }
}
public class DtoV1 : IHasVersion
{
public int Version { get; set; }
public string Name { get; set; }
public DtoV1()
{
Version = 1;
}
}
元の DTO を新しいDtoV1
ものに逆シリアル化すると、0 のままになります。
var dto = new Dto { Name = "Foo" };
var fromDto = dto.ToJson().FromJson<DtoV1>();
fromDto.Version // 0
fromDto.Name // Foo
新しい DTO を使用すると、バージョン番号が入力されます。
var dto1 = new DtoV1 { Name = "Foo 1" };
var fromDto1 = dto1.ToJson().FromJson<DtoV1>();
fromDto.Version // 1
fromDto.Name // Foo 1