Да, это может быть сложно, когда вы впервые добавляете информацию Version
, потому что вы хотите иметь номер версии в конструкторе, чтобы каждому вызову была назначена его неявная версия, в то же время тот же самый конструктор используется, когда вы deserialize в новый DTO.
К сожалению, поскольку в оригинальной DTO версии нет, она не сериализуется на проводе, поэтому никогда не отменяет неявно назначенное поле Version.
Чтобы обойти это (и сохранить неявно назначенный номер версии в конструкторе), вам необходимо эффективно сбросить версию, используемую при десериализации.
Вы можете сделать это с помощью сериализаторов JSON/JSV, переопределив JsConfig.ModelFactory
на App_Start (то есть в AppConfig), который позволяет вам управлять экземпляром, созданным для каждого типа POCO, используемого при десериализации.
В этом случае мы хотим сбросить любой DTO, который имеет версию обратно 0
что путь DTOs без номера версии назначается 0
пока DTOS с номером версии будет переопределить его:
JsConfig.ModelFactory = type => {
if (typeof(IHasVersion).IsAssignableFrom(type))
{
return() => {
var obj = (IHasVersion)type.CreateInstance();
obj.Version = 0;
return obj;
};
}
return() => type.CreateInstance();
};
Я используя явный интерфейс IHasVersion
для простоты, но вы также можете легко использовать отражение для обнаружения и переназначения типов, содержащих номер версии.
Вот пример оригинального DTO без собственности Версии десериализации в 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;
}
}
Теперь, когда вы Deserialize оригинального 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
Условное решение. Спасибо, миф – BoKDamgaard