Skip to content
This repository was archived by the owner on Nov 16, 2023. It is now read-only.

Added support for allOf and oneOf #234

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -146,14 +146,14 @@ internal void RegisterAssemblyPaths(IList<string> assemblyPaths)
/// <param name="operationElements">The operation xelements.</param>
/// <param name="propertyElements">The property xelements</param>
/// <param name="documentVariantElementName">The document variant element name.</param>
/// <param name="internalSchemaGenerationSettings"><see cref="InternalSchemaGenerationSettings"/></param>
/// <param name="schemaGenerationSettings"><see cref="SchemaGenerationSettings"/></param>
/// <returns>Serialized <see cref="InternalGenerationContext"/></returns>
public string BuildInternalGenerationContext(
IList<string> contractAssembliesPaths,
IList<string> operationElements,
IList<string> propertyElements,
string documentVariantElementName,
InternalSchemaGenerationSettings internalSchemaGenerationSettings)
SchemaGenerationSettings schemaGenerationSettings)
{
var crefSchemaMap = new Dictionary<string, InternalSchemaGenerationInfo>();

Expand All @@ -175,14 +175,6 @@ public string BuildInternalGenerationContext(

var referenceRegistryMap = new Dictionary<DocumentVariantInfo, SchemaReferenceRegistry>();

var schemaGenerationSettings = new SchemaGenerationSettings(new DefaultPropertyNameResolver());

if (internalSchemaGenerationSettings.PropertyNameResolverName ==
typeof(CamelCasePropertyNameResolver).FullName)
{
schemaGenerationSettings = new SchemaGenerationSettings(new CamelCasePropertyNameResolver());
}

var internalGenerationContext = new InternalGenerationContext();

#if !NETFRAMEWORK
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
// ------------------------------------------------------------

using System;
using System.Reflection;
using Microsoft.OpenApi.CSharpAnnotations.DocumentGeneration.Extensions;

Expand All @@ -11,6 +12,7 @@ namespace Microsoft.OpenApi.CSharpAnnotations.DocumentGeneration
/// <summary>
/// Resolves property name by camel casing.
/// </summary>
[Serializable]
public class CamelCasePropertyNameResolver : DefaultPropertyNameResolver, IPropertyNameResolver
{
/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// Licensed under the MIT License (MIT). See License.txt in the repo root for license information.
// ------------------------------------------------------------

using System;
using System.Linq;
using System.Reflection;
using Microsoft.OpenApi.CSharpAnnotations.DocumentGeneration.ReferenceRegistries;
Expand All @@ -12,6 +13,7 @@ namespace Microsoft.OpenApi.CSharpAnnotations.DocumentGeneration
/// <summary>
/// Used by <see cref="SchemaReferenceRegistry"/> to resolve property name for a given <see cref="PropertyInfo"/>.
/// </summary>
[Serializable]
public class DefaultPropertyNameResolver : IPropertyNameResolver
{
/// <summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System;
using Microsoft.OpenApi.CSharpAnnotations.DocumentGeneration.Extensions;
using Microsoft.OpenApi.CSharpAnnotations.DocumentGeneration.ReferenceRegistries;

namespace Microsoft.OpenApi.CSharpAnnotations.DocumentGeneration
{
/// <summary>
/// Used by <see cref="SchemaReferenceRegistry"/> to resolve schema id name for a given <see cref="Type"/>.
/// </summary>
[Serializable]
public class DefaultSchemaIdResolver : ISchemaIdResolver
{
/// <inheritdoc />
public string ResolveSchemaId(Type type)
{
// Type.ToString() returns full name for non-generic types and
// returns a full name without unnecessary assembly information for generic types.
var typeName = type.ToString();

return typeName.SanitizeClassName();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using System;
using System.Reflection;
using Microsoft.OpenApi.CSharpAnnotations.DocumentGeneration.ReferenceRegistries;

namespace Microsoft.OpenApi.CSharpAnnotations.DocumentGeneration
{
/// <summary>
/// Utilized by <see cref="SchemaReferenceRegistry"/> to find information about discriminator
/// </summary>
public interface IDiscriminatorResolver
{
/// <summary>
/// Resolves the discriminator property
/// </summary>
/// <param name="parentType">The parent type.</param>
/// <returns></returns>
PropertyInfo ResolveProperty(Type parentType);

/// <summary>
/// Resolves the mapping key.
/// </summary>
/// <param name="discriminatorProperty">The discriminator property.</param>
/// <param name="childType">The child type.</param>
/// <returns></returns>
string ResolveMappingKey(PropertyInfo discriminatorProperty, Type childType);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System;
using Microsoft.OpenApi.CSharpAnnotations.DocumentGeneration.ReferenceRegistries;

namespace Microsoft.OpenApi.CSharpAnnotations.DocumentGeneration
{
/// <summary>
/// Used by <see cref="SchemaReferenceRegistry"/> to resolve schema id name for a given <see cref="Type"/>.
/// </summary>
public interface ISchemaIdResolver
{
/// <summary>
/// Resolves the schema identifier.
/// </summary>
/// <param name="type">The type.</param>
/// <returns></returns>
string ResolveSchemaId(Type type);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -271,14 +271,8 @@ IDictionary<DocumentVariantInfo, OpenApiDocument> openApiDocuments

try
{
var propertyNameResolverTypeName = _openApiDocumentGenerationSettings.SchemaGenerationSettings
.PropertyNameResolver.GetType().FullName;

var internalGenerationContext = new InternalGenerationContext();
var internalSchemaGenerationSettings = new InternalSchemaGenerationSettings()
{
PropertyNameResolverName = propertyNameResolverTypeName
};

generationDiagnostic = new GenerationDiagnostic();
var documentGenerationDiagnostic = new DocumentGenerationDiagnostic();
Expand Down Expand Up @@ -310,7 +304,7 @@ IDictionary<DocumentVariantInfo, OpenApiDocument> openApiDocuments
serializedOperationElements,
propertyElements.Select(i => i.ToString()).ToList(),
documentVariantElementNames.FirstOrDefault(),
internalSchemaGenerationSettings);
_openApiDocumentGenerationSettings.SchemaGenerationSettings);

internalGenerationContext =
(InternalGenerationContext)JsonConvert.DeserializeObject(
Expand All @@ -325,7 +319,7 @@ IDictionary<DocumentVariantInfo, OpenApiDocument> openApiDocuments
serializedOperationElements,
propertyElements.Select(i => i.ToString()).ToList(),
documentVariantElementNames.FirstOrDefault(),
internalSchemaGenerationSettings);
_openApiDocumentGenerationSettings.SchemaGenerationSettings);

internalGenerationContext =
(InternalGenerationContext)JsonConvert.DeserializeObject(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Xml.Linq;
using System.Xml.Serialization;
using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.CSharpAnnotations.DocumentGeneration.Exceptions;
using Microsoft.OpenApi.CSharpAnnotations.DocumentGeneration.Extensions;
Expand Down Expand Up @@ -194,8 +197,58 @@ internal override OpenApiSchema FindOrAddReference(Type input)
}

var a = input.FullName;

PropertyInfo[] propertyInfos;
if (_schemaGenerationSettings.IncludeInheritanceInformation)
{
propertyInfos = input.GetProperties(BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance);

if (input.BaseType != typeof(object))
{
var baseClassSchema = FindOrAddReference(input.BaseType);

schema.AllOf.Add(baseClassSchema);
}

foreach (var propertyInfo in input.GetProperties())
if (_schemaGenerationSettings.DiscriminatorResolver != null)
{
var xmlIncludeAttributes = input.GetCustomAttributes<XmlIncludeAttribute>(false).ToArray();

if (xmlIncludeAttributes.Length > 0)
{
var discriminatorProperty = _schemaGenerationSettings.DiscriminatorResolver.ResolveProperty(input);

if (discriminatorProperty != null)
{
var openApiDiscriminator = new OpenApiDiscriminator()
{
PropertyName = discriminatorProperty.Name,
Mapping = new Dictionary<string, string>()
};

schema.Discriminator = openApiDiscriminator;

foreach (var xmlIncludeAttribute in xmlIncludeAttributes)
{
var childSchema = FindOrAddReference(xmlIncludeAttribute.Type);

schema.OneOf.Add(childSchema);

var mappingKey = _schemaGenerationSettings.DiscriminatorResolver.ResolveMappingKey(discriminatorProperty, xmlIncludeAttribute.Type);

openApiDiscriminator.Mapping[mappingKey] = childSchema.Reference.ReferenceV3;
}

}
}
}
}
else
{
propertyInfos = input.GetProperties();
}

foreach (var propertyInfo in propertyInfos)
{
var ignoreProperty = false;

Expand Down Expand Up @@ -318,11 +371,7 @@ internal override OpenApiSchema FindOrAddReference(Type input)
/// </remarks>
internal override string GetKey(Type input)
{
// Type.ToString() returns full name for non-generic types and
// returns a full name without unnecessary assembly information for generic types.
var typeName = input.ToString();

return typeName.SanitizeClassName();
return _schemaGenerationSettings.SchemaIdResolver.ResolveSchemaId(input);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,39 @@ namespace Microsoft.OpenApi.CSharpAnnotations.DocumentGeneration
/// <summary>
/// Specifies the settings for schema generation.
/// </summary>
[Serializable]
public class SchemaGenerationSettings
{
/// <summary>
/// Creates an instance of <see cref="SchemaGenerationSettings"/> class.
/// </summary>
/// <param name="propertyNameResolver">The property name resolver.</param>
public SchemaGenerationSettings(IPropertyNameResolver propertyNameResolver)
/// <param name="schemaIdResolver"></param>
public SchemaGenerationSettings(IPropertyNameResolver propertyNameResolver, ISchemaIdResolver schemaIdResolver = null)
{
PropertyNameResolver = propertyNameResolver
?? throw new ArgumentNullException(nameof(propertyNameResolver));
?? throw new ArgumentNullException(nameof(propertyNameResolver));
SchemaIdResolver = schemaIdResolver ?? new DefaultSchemaIdResolver();
}

/// <summary>
/// Gets the property name resolver.
/// </summary>
public IPropertyNameResolver PropertyNameResolver { get; }

/// <summary>
/// Gets the schema identifier resolver.
/// </summary>
public ISchemaIdResolver SchemaIdResolver { get; }

/// <summary>
/// Gets or sets a value indicating whether generator should support inheritance, i.e add allOf and oneOf attributes.
/// </summary>
public bool IncludeInheritanceInformation { get; set; }

/// <summary>
/// Gets or sets the discriminator resolver.
/// </summary>
public IDiscriminatorResolver DiscriminatorResolver { get; set; }
}
}