Skip to content

Commit

Permalink
Add XML docs descriptions
Browse files Browse the repository at this point in the history
Add OpenAPI descriptions for schemas from XML documentation.
  • Loading branch information
martincostello committed Jul 19, 2024
1 parent 1b624c5 commit 12237af
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/API/API.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<InvariantGlobalization>true</InvariantGlobalization>
<OutputType>Exe</OutputType>
<PreserveCompilationContext>true</PreserveCompilationContext>
<PublishAot>true</PublishAot>
<PublishAot>false</PublishAot>
<PublishSelfContained>true</PublishSelfContained>
<RootNamespace>MartinCostello.Api</RootNamespace>
<TargetFramework>net9.0</TargetFramework>
Expand Down
1 change: 1 addition & 0 deletions src/API/Extensions/IServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public static IServiceCollection AddOpenApiDocumentation(this IServiceCollection
options.AddOperationTransformer<AddResponseDescriptionTransformer>();
options.AddOperationTransformer<RemoveStyleCopPrefixesTransformer>();
options.AddSchemaTransformer<AddExamplesTransformer>();
options.AddSchemaTransformer<AddSchemaDescriptionsTransformer>();
options.AddSchemaTransformer<RemoveStyleCopPrefixesTransformer>();
});

Expand Down
61 changes: 61 additions & 0 deletions src/API/OpenApi/AddSchemaDescriptionsTransformer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Copyright (c) Martin Costello, 2016. All rights reserved.
// Licensed under the MIT license. See the LICENSE file in the project root for full license information.

using System.Xml;
using System.Xml.XPath;
using Microsoft.AspNetCore.OpenApi;
using Microsoft.OpenApi.Models;

namespace MartinCostello.Api.OpenApi;

/// <summary>
/// A class that adds descriptions to the schemas of OpenAPI documents. This class cannot be inherited.
/// </summary>
public sealed class AddSchemaDescriptionsTransformer : IOpenApiSchemaTransformer
{
/// <inheritdoc/>
public Task TransformAsync(OpenApiSchema schema, OpenApiSchemaTransformerContext context, CancellationToken cancellationToken)
{
if (schema.Description != null)
{
return Task.CompletedTask;
}

var thisAssembly = GetType().Assembly;

if (context.JsonTypeInfo.Type.Assembly == thisAssembly)
{
var navigator = CreateNavigator();
var description = navigator.SelectSingleNode($"/doc/members/member[@name='T:{context.JsonTypeInfo.Type.FullName}']/summary");

if (!string.IsNullOrEmpty(description?.InnerXml))
{
schema.Description = description.Value.Trim();
}
}
else if (context.JsonPropertyInfo?.DeclaringType.Assembly == thisAssembly)
{
var navigator = CreateNavigator();

var typeName = context.JsonPropertyInfo.DeclaringType.FullName;
var propertyName = $"{char.ToUpperInvariant(context.JsonPropertyInfo.Name[0])}{context.JsonPropertyInfo.Name[1..]}";

var description = navigator.SelectSingleNode(
$"/doc/members/member[@name='P:{typeName}{Type.Delimiter}{propertyName}']/summary");

if (!string.IsNullOrEmpty(description?.InnerXml))
{
schema.Description = description.Value.Trim();
}
}

return Task.CompletedTask;
}

private static XPathNavigator CreateNavigator()
{
var path = Path.Combine(AppContext.BaseDirectory, "API.xml");
using var reader = XmlReader.Create(path);
return new XPathDocument(reader).CreateNavigator();
}
}

0 comments on commit 12237af

Please sign in to comment.