我正在try 制作定制的OpenApiSchema生成器.
如何运作:
以下是示例接口:
[ApiCommands]
abstract public class Commands
{
[ApiArgument( typeof( SubjectsListArguments ), isOptional: true )]
[ApiReturn( typeof( SubjectsListResponse ) )]
[Title]
[Description]
public const string SubjectsList = "subjects_list";
}
因此,ApiArgument、ApiReturn代表DTO.我所需要的就是通过这个模型创建OpenApiSchema.让我们看看获得IDictionary<string, OpenApiSchema>
的代码:
private IDictionary<string, OpenApiSchema> GenerateProperties(Type arguments)
{
var properties = new Dictionary<string, OpenApiSchema>();
GeneratePropertiesRecursive(arguments, properties);
return properties;
}
private void GeneratePropertiesRecursive(
Type type,
IDictionary<string, OpenApiSchema> properties)
{
if (type == null) return;
var propertyInfos = type.GetProperties();
foreach (var propertyInfo in propertyInfos)
{
var attributeValue = propertyInfo
.GetCustomAttribute<JsonPropertyAttribute>();
if (attributeValue == null)
continue;
var propertyName = attributeValue.PropertyName;
var propertyType = propertyInfo.PropertyType;
var propertySchema = new OpenApiSchema();
if (propertyType.IsClass && !_excludedTypes.Contains(propertyType))
{
if (ImplementsEnumerableTypes(propertyType, out var genericTypes))
{
var itemsSchema = new OpenApiSchema();
foreach (var genericType in genericTypes)
{
if (_excludedTypes.Contains(genericType))
{
itemsSchema = genericType.MapTypeToOpenApiType(propertySchema);
break;
}
GeneratePropertiesRecursive(genericType, itemsSchema.Properties);
}
propertySchema.Type = "array";
propertySchema.Items = itemsSchema;
properties.Add(propertyName, propertySchema);
continue;
}
GeneratePropertiesRecursive(propertyType, propertySchema.Properties);
}
if (propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(OptionalValue<>))
{
var genericType = propertyType.GetGenericArguments()[0];
GeneratePropertiesRecursive(genericType, propertySchema.Properties);
propertyType = genericType;
}
if (IsNullableType(propertyType, out var nullableType))
propertyType = nullableType;
if (propertyType.IsEnum)
{
var types = propertyType.GetOpenApiTypesFromEnumPropertyType();
propertySchema.Type = "string";
propertySchema.Enum = types;
properties.Add( propertyName, propertySchema );
continue;
}
propertySchema = propertyType.MapTypeToOpenApiType(propertySchema);
properties.Add(propertyName, propertySchema);
}
}
我有三个问题:
- 我可以为一个类型多次生成OpenApiSchema,我不能控制这一点,我也不知道怎么做.
- 我们可以循环进入dto,这就是为什么堆栈溢出异常.例如:我们有
SubjectDto
个和DepartmentDto
个.SubjectDto
引用DepartmentDto
,DepartmentDto
引用SubjectDto
- 它真的很难读...
我们还可以添加引用:
Schema = new OpenApiSchema
{
Reference = new OpenApiReference
{
Id = $"{name}_response",
Type = ReferenceType.Schema
}
}