private OpenApiSchema GenerateSchemaForType(Type type, SchemaRepository schemaRepository)
        {
            if (TryGetCustomMapping(type, out var mapping))
            {
                return(mapping());
            }

            if (type.IsAssignableToOneOf(typeof(IFormFile), typeof(FileResult)))
            {
                return(new OpenApiSchema {
                    Type = "string", Format = "binary"
                });
            }

            if (_generatorOptions.GeneratePolymorphicSchemas)
            {
                var knownSubTypes = _generatorOptions.SubTypesResolver(type);
                if (knownSubTypes.Any())
                {
                    return(GeneratePolymorphicSchema(knownSubTypes, schemaRepository));
                }
            }

            var dataContract = _dataContractResolver.GetDataContractForType(type);

            var shouldBeReferened = (dataContract.EnumValues != null && !_generatorOptions.UseInlineDefinitionsForEnums) ||
                                    (dataContract.IsDictionary && dataContract.Type == dataContract.DictionaryValueType) ||
                                    (dataContract.IsArray && dataContract.Type == dataContract.ArrayItemType) ||
                                    (dataContract.IsObject && dataContract.Members != null);

            return((shouldBeReferened)
                ? GenerateReferencedSchema(dataContract, schemaRepository)
                : GenerateInlineSchema(dataContract, schemaRepository));
        }
Ejemplo n.º 2
0
        public DataContract GetDataContractForType(Type type)
        {
            if (!_messageTypeMapping.TryGetValue(type, out var messageDescriptor))
            {
                if (typeof(IMessage).IsAssignableFrom(type))
                {
                    var property = type.GetProperty("Descriptor", BindingFlags.Public | BindingFlags.Static);
                    messageDescriptor = property?.GetValue(null) as MessageDescriptor;

                    if (messageDescriptor == null)
                    {
                        throw new InvalidOperationException($"Couldn't resolve message descriptor for {type}.");
                    }

                    _messageTypeMapping[type] = messageDescriptor;
                }
            }

            if (messageDescriptor != null)
            {
                return(ConvertMessage(messageDescriptor));
            }

            if (type.IsEnum)
            {
                if (_enumTypeMapping.TryGetValue(type, out var enumDescriptor))
                {
                    var values = enumDescriptor.Values.Select(v => v.Name).ToList();
                    return(new DataContract(DataType.String, type, enumValues: values));
                }
            }

            return(_innerContractResolver.GetDataContractForType(type));
        }
Ejemplo n.º 3
0
        public Message GenerateMessage(Type type, MessageRepository messageRepository, MessageAttribute messageAttribute)
        {
            return(messageRepository.GetOrAdd(type, _options.SchemaIdSelector(type), () =>
            {
                var dataContract = _dataContractResolver.GetDataContractForType(type);
                var message = new Message
                {
                    Title = messageAttribute.Title,
                    Name = messageAttribute.Name
                };

                if (dataContract.DataType == DataType.Array)
                {
                    message.Summary = dataContract.ArrayItemType.GetXmlDocsSummary();
                    message.Payload = new Schema {
                        Type = "array", Items = new Reference(_options.SchemaIdSelector(dataContract.ArrayItemType), ReferenceType.Schema)
                    };
                }
                else
                {
                    message.Summary = type.GetXmlDocsSummary();
                    message.Payload = new Reference(_options.SchemaIdSelector(type), ReferenceType.Schema);
                }

                return message;
            }));
        }
Ejemplo n.º 4
0
        private OpenApiSchema GenerateSchemaForType(Type type, ParameterInfo parameterInfo, SchemaRepository schemaRepository)
        {
            if (TryGetCustomMapping(type, out var mapping))
            {
                return(mapping());
            }

            if (type.IsAssignableToOneOf(typeof(IFormFile), typeof(FileResult)))
            {
                return(new OpenApiSchema {
                    Type = "string", Format = "binary"
                });
            }

            if (_generatorOptions.GeneratePolymorphicSchemas)
            {
                var knownSubTypes = _generatorOptions.SubTypesResolver(type);
                if (knownSubTypes.Any())
                {
                    return(GeneratePolymorphicSchema(knownSubTypes, schemaRepository));
                }
            }

            var dataContract = _dataContractResolver.GetDataContractForType(type);

            var shouldBeReferenced =
                // regular object
                (dataContract.DataType == DataType.Object && dataContract.Properties != null && !dataContract.UnderlyingType.IsDictionary()) ||
                // dictionary-based AND self-referencing
                (dataContract.DataType == DataType.Object && dataContract.AdditionalPropertiesType == dataContract.UnderlyingType) ||
                // array-based AND self-referencing
                (dataContract.DataType == DataType.Array && dataContract.ArrayItemType == dataContract.UnderlyingType) ||
                // enum-based AND opted-out of inline
                (dataContract.EnumValues != null && !_generatorOptions.UseInlineDefinitionsForEnums);

            return((shouldBeReferenced)
                ? GenerateReferencedSchema(dataContract, parameterInfo, schemaRepository)
                : GenerateInlineSchema(dataContract, parameterInfo, schemaRepository));
        }
Ejemplo n.º 5
0
        private ISchema GenerateSchemaForType(Type type, SchemaRepository schemaRepository)
        {
            var schemaId           = _options.SchemaIdSelector(type);
            var dataContract       = _dataContractResolver.GetDataContractForType(type);
            var shouldBeReferenced =
                // regular object
                (dataContract.DataType == DataType.Object && dataContract.Properties != null && !dataContract.UnderlyingType.IsDictionary()) ||
                // dictionary-based AND self-referencing
                (dataContract.DataType == DataType.Object && dataContract.AdditionalPropertiesType == dataContract.UnderlyingType) ||
                // array-based AND self-referencing
                (dataContract.DataType == DataType.Array && dataContract.ArrayItemType == dataContract.UnderlyingType) ||
                // enum-based AND opted-out of inline
                (dataContract.EnumValues != null && !_options.UseInlineDefinitionsForEnums);

            var schema = shouldBeReferenced ? GenerateReferencedSchema(dataContract, schemaRepository) : GenerateInlineSchema(dataContract, schemaRepository);

            return(schema);
        }
Ejemplo n.º 6
0
        private OpenApiSchema GenerateSchemaForType(Type type, SchemaRepository schemaRepository)
        {
            if (type.IsNullable(out Type innerType))
            {
                return(GenerateSchemaForType(innerType, schemaRepository));
            }

            if (type.IsAssignableToOneOf(typeof(IFormFile), typeof(FileResult)))
            {
                return(new OpenApiSchema {
                    Type = "string", Format = "binary"
                });
            }

            if (type == typeof(object))
            {
                return(new OpenApiSchema {
                    Type = "object"
                });
            }

            Func <OpenApiSchema> definitionFactory;
            bool returnAsReference;

            var dataContract = _dataContractResolver.GetDataContractForType(type);

            switch (dataContract.DataType)
            {
            case DataType.Boolean:
            case DataType.Integer:
            case DataType.Number:
            case DataType.String:
            {
                definitionFactory = () => GeneratePrimitiveSchema(dataContract);
                returnAsReference = type.IsEnum && !_generatorOptions.UseInlineDefinitionsForEnums;
                break;
            }

            case DataType.Array:
            {
                definitionFactory = () => GenerateArraySchema(dataContract, schemaRepository);
                returnAsReference = type == dataContract.ArrayItemType;
                break;
            }

            case DataType.Dictionary:
            {
                definitionFactory = () => GenerateDictionarySchema(dataContract, schemaRepository);
                returnAsReference = type == dataContract.DictionaryValueType;
                break;
            }

            case DataType.Object:
            {
                if (_generatorOptions.UseOneOfForPolymorphism && IsBaseTypeWithKnownSubTypes(type, out IEnumerable <Type> subTypes))
                {
                    definitionFactory = () => GeneratePolymorphicSchema(dataContract, schemaRepository, subTypes);
                    returnAsReference = false;
                }
                else
                {
                    definitionFactory = () => GenerateObjectSchema(dataContract, schemaRepository);
                    returnAsReference = true;
                }

                break;
            }

            default:
            {
                definitionFactory = () => new OpenApiSchema();
                returnAsReference = false;
                break;
            }
            }

            return(returnAsReference
                ? GenerateReferencedSchema(type, schemaRepository, definitionFactory)
                : definitionFactory());
        }