JsonConverter
- правильный путь к go, однако ConcreteTypeConverter
не подходит для вашего случая.
Предположим, вам нужно определить, какой конкретный тип создать во время выполнения, на основе TypeId
, вам понадобится JsonConverter
на Dto
, а не на Type
свойство.
Попробуйте это:
[JsonConverter(typeof(DtoJsonConverter))]
public class Dto
{
public IType Type { get; set; }
public int TypeId { get; set; }
}
class DtoJsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(Dto);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
{
return null;
}
// Load this to a JObject so that we can read TypeId
var obj = JObject.Load(reader);
var typeId = obj["TypeId"].Value<int>();
// Figure out JSON covnerter for type property based on TypeId
JsonConverter converter = null;
switch (typeId)
{
// Assuming 1 means Type1
case 1:
converter = new CreateITypeJsonConverter(() => new Type1());
break;
case 2:
converter = new CreateITypeJsonConverter(() => new Type2());
break;
}
if (converter != null)
{
serializer.Converters.Add(converter);
}
try
{
// Now create Dto and populate the object.
// This will call the JsonConverter we just added for Type property.
var dto = new Dto();
serializer.Populate(obj.CreateReader(), dto);
return dto;
}
finally
{
if (converter != null)
{
serializer.Converters.Remove(converter);
}
}
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotSupportedException();
}
}
class CreateITypeJsonConverter : CustomCreationConverter<IType>
{
private readonly Func<IType> _factory;
public CreateITypeJsonConverter(Func<IType> factory)
{
_factory = factory;
}
public override IType Create(Type objectType)
{
return _factory();
}
}
DtoJsonConverter
определяет конкретный тип IType
согласно значению TypeId
, и использовать другой CreateITypeJsonConverter
для создания экземпляра конкретного типа, затем заполните Dto
.
Также возможно, что вы могли бы переместить TypeId
в IType
, затем используйте один из методов в этом вопросе: JsonConverter с интерфейсом