Как я могу изменить тип свойства с NJsonSchema - PullRequest
0 голосов
/ 11 июня 2019

У меня есть серия универсальных объектов ответа, которые возвращаются со свойством, являющимся абстрактным классом. NSwag и NJsonSchema генерируют схему с абстрактным классом, что создает проблемы. Конкретный класс легко определяется с помощью рефлексии, однако, кажется, нет чистого способа заставить NJsonSchema заменить абстрактный тип на соответствующий конкретный тип. Как правильно это сделать?

public abstract class AppRequest<TData> {
    public Guid RequestId { get; set; }
}

public class AppResponse<TData> {
    public TData Data { get; set; }
    public AppRequest<TData> OriginalRequest { get; set; }
}

public class User {
....
}

public class UserRequest: AppRequest<User> {
    public Guid UserId { get; set; }
}

NSwag генерирует объект ответа как AppResponseOfUser, что нормально, однако оно говорит, что свойство OriginalRequest является AppRequestOfUser и является абстрактным. Я хочу создать SchemaProcessor, который сопоставляет этот AppRequestOfUser с UserRequest. Как то так:

public class MySchemaProcessor
    : ISchemaProcessor
{
    public async Task ProcessAsync(SchemaProcessorContext context)
    {
        if (context.Type.IsGenericOf(typeof(AppResponse<>)))
        {
            var modelType = context.Type.GenericTypeArguments[0];
            var abstractRequestType = typeof(AppRequest<>).MakeGenericType(modelType);

            var actualRequestType = modelType.Assembly.GetTypes()
                .Single(t => t.IsClass && t.BaseType == abstractRequestType);

            var requestSchema = await JsonSchema4.FromTypeAsync(actualRequestType);

            var originalRequestProperty = context.Schema.Properties["originalRequest"];
            originalRequestProperty.IsReadOnly = true;
            originalRequestProperty.IsAbstract = false;

            // CHANGE PROPERTY TYPE HERE!!!
        }
    }
}

К сожалению, NJsonSchema не кажется очень гибкой, и нет четкого способа, как это сделать. Я не хочу использовать свойство дискриминатора. Я хочу переназначить на соответствующий конкретный тип.

1 Ответ

0 голосов
/ 24 июня 2019

Если кому-то интересно, вот окончательное решение:

var classesToMap = typeof(Startup)
                .Assembly
                .GetTypes()
                .Where(t => t.IsClass && t.BaseType.IsGenericOf(typeof(AppRequest<>)));

            var settings = new JsonSchemaGeneratorSettings()
            {
                FlattenInheritanceHierarchy = true,

            };
            foreach (var type in classesToMap)
            {
                var actualSchema = JsonSchema4.FromTypeAsync(type,settings).Result;
                options.TypeMappers.Add(new ObjectTypeMapper(type.BaseType, actualSchema));
            }
...