Skip to content

Commit cef4c2d

Browse files
committed
react to feedback
1 parent 803ae9c commit cef4c2d

File tree

1 file changed

+46
-135
lines changed

1 file changed

+46
-135
lines changed

aspnetcore/fundamentals/openapi/openapi-comments.md

Lines changed: 46 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ uid: fundamentals/openapi/aspnet-openapi-xml
1313

1414
OpenAPI XML documentation extracts code comments automatically to populate API documentation, ensuring the code and documentation remain synchronized. Metadata from XML documentation comments is included in the generated OpenAPI document without requiring changes to the app code, as long as the project is configured to generate the XML documentation file. XML documentation comments are automatically detected in the application assembly and referenced assemblies with XML documentation enabled.
1515

16+
XML documentation processing doesn't impact runtime performance. The source generator processes XML documentation at compile time and caches the results, with minimal runtime overhead when rendering the OpenAPI documentation. Furthermore, the OpenAPI document can be cached at runtime using [output-caching](/aspnet/core/performance/caching/overview#output-caching) to further optimize performance.
17+
1618
ASP.NET Core processes [XML documentation tags](https://learn.microsoft.com/dotnet/csharp/language-reference/xmldoc/recommended-tags) like: `<c>`, `<code>`, `<list>`, `<para>`, `<paramref>`, `<typeparamref>`, `<see>`, and `<seealso>`.
1719
For XML documentation tags that use references to other elements, like `<see cref="SomeOtherType">`, the implementation strips out the XML tag and maps the reference to plain text for inclusion in the OpenAPI document.
1820

@@ -24,6 +26,38 @@ This article includes a [sample app](#download10) that demonstrates the [`Micros
2426

2527
The following sections describe how to enable and customize XML documentation support.
2628

29+
### Enable XML documentation in an ASP.NET Core API project
30+
31+
1. Enable XML documentation in the project file:
32+
33+
:::code language="xml" source="~/fundamentals/openapi/samples/10.x/aspnet-openapi-xml/models/Models.csproj" highlight="7":::
34+
35+
2. Use the [AddOpenApi](xref:Microsoft.Extensions.DependencyInjection.OpenApiServiceCollectionExtensions.AddOpenApi*) method in the service configuration. No configuration is needed, the source generator handles the rest.
36+
37+
:::code language="csharp" source="~/fundamentals/openapi/samples/10.x/aspnet-openapi-xml/api/Program.cs" highlight="6":::
38+
39+
To include XML documentation files from referenced assemblies, add them as `AdditionalFiles` in the project:
40+
41+
```xml
42+
<ItemGroup>
43+
<AdditionalFiles Include="Path/To/AssemblyDoc.xml" />
44+
</ItemGroup>
45+
```
46+
47+
The source generator detects all standard overloads:
48+
49+
* [`AddOpenApi()`](xref:Microsoft.Extensions.DependencyInjection.OpenApiServiceCollectionExtensions.AddOpenApi(Microsoft.Extensions.DependencyInjection.IServiceCollection))
50+
* [`AddOpenApi("v1")`](xref:Microsoft.Extensions.DependencyInjection.OpenApiServiceCollectionExtensions.AddOpenApi(Microsoft.Extensions.DependencyInjection.IServiceCollection,System.String))
51+
* [`AddOpenApi(options => {})`](xref:Microsoft.Extensions.DependencyInjection.OpenApiServiceCollectionExtensions.AddOpenApi(Microsoft.Extensions.DependencyInjection.IServiceCollection,System.Action{Microsoft.AspNetCore.OpenApi.OpenApiOptions}))
52+
* [`AddOpenApi("v1", options => {})`](xref:Microsoft.Extensions.DependencyInjection.OpenApiServiceCollectionExtensions.AddOpenApi(Microsoft.Extensions.DependencyInjection.IServiceCollection,System.String,System.Action{Microsoft.AspNetCore.OpenApi.OpenApiOptions}))
53+
54+
Each overload is intercepted to automatically include the XML documentation transformers. The source generator doesn't handle overloads where the `documentName` parameter isn't a literal string expression. For example, the transformer isn't registered in the following scenarios:
55+
56+
```csharp
57+
var documentName = "v1";
58+
builder.Services.AddOpenApi(documentName); // No XML support
59+
```
60+
2761
### Adding XML documentation sources
2862

2963
The [`Microsoft.AspNetCore.OpenApi`](https://www.nuget.org/packages/Microsoft.AspNetCore.OpenApi) NuGet package automatically resolves XML documentation comments from:
@@ -50,9 +84,7 @@ To turn off XML documentation integration, remove the source generator from the
5084

5185
<!-- review setting <GenerateDocumentationFile>false</GenerateDocumentationFile> prevents the XML file from being generated. Explain the difference between GenerateDocumentationFile = true and <Analyzer Remove -->
5286

53-
## Source generator implementation notes
54-
55-
87+
## Source generator implementation
5688

5789
The XML documentation feature is implemented as a source generator. The source generator analyzes XML documentation comments at compile time and injects code that translates these comments into OpenAPI metadata. The [`XmlCommentGenerator`](https://source.dot.net/#Microsoft.AspNetCore.OpenApi.SourceGenerators/XmlCommentGenerator.cs,30eb0aa73ef6306a) extracts XML comments from two sources:
5890

@@ -89,119 +121,29 @@ The automatic resolution behavior is currently available for XML documentation c
89121
* Associating the text content to compilation symbols.
90122
* Developing an understanding of the inheritance hierarchy associated with the types.
91123

92-
<!-- ### Member identification - `MemberKey` removed in preview 3.
93-
94-
The source generator discovers XML comments statically and emits code that applies them to the document dynamically at runtime. The [`MemberKey`](https://source.dot.net/#Microsoft.AspNetCore.OpenApi.SourceGenerators/XmlComments/MemberKey.cs,d182ed147edb11d2) class acts as a bridge between compile-time and runtime representations of the same concept. It's a unique identifier for types, methods, and properties that works across:
95-
96-
* Different compilation environments.
97-
* Generic types with proper handling of open generics.
98-
* Method overloads with parameter signature matching.
99-
100-
The `MemberKey` definition attempts to encode as much information as possible to map a compile-time symbol to its runtime counterpart.
101-
102-
```csharp
103-
internal sealed record MemberKey(
104-
string? DeclaringType,
105-
MemberType MemberKind,
106-
string? Name,
107-
string? ReturnType,
108-
string[]? Parameters) : IEquatable<MemberKey>
109-
``` -->
110-
111-
### Code Generation
112-
113-
The generator emits code that contains:
114-
115-
* A cache of XML comments mapped to member identifiers:
116-
* OpenAPI transformer implementations:
117-
* [`XmlCommentOperationTransformer`](https://github.com/dotnet/aspnetcore/blob/main/src/OpenApi/gen/XmlCommentGenerator.Emitter.cs#L229): Applies comments to API operations (methods).
118-
* [`XmlCommentSchemaTransformer`](https://github.com/dotnet/aspnetcore/blob/main/src/OpenApi/gen/XmlCommentGenerator.Emitter.cs#L308): Applies comments to data models (types).
119-
* Extension methods that intercept <xref:Microsoft.Extensions.DependencyInjection.OpenApiServiceCollectionExtensions.AddOpenApi*> calls to inject the transformers:
120-
121-
```csharp
122-
public static IServiceCollection AddOpenApi(this IServiceCollection services)
123-
{
124-
return services.AddOpenApi("v1", options =>
125-
{
126-
options.AddSchemaTransformer(new XmlCommentSchemaTransformer());
127-
options.AddOperationTransformer(new XmlCommentOperationTransformer());
128-
});
129-
}
130-
```
131-
132-
### Interception mechanism
133-
134-
The generator uses the C# compiler's interceptor feature to intercept calls to the `<xref:Microsoft.Extensions.DependencyInjection.OpenApiServiceCollectionExtensions.AddOpenApi*> method. The generator:
135-
136-
1. Detects different `AddOpenApi` overloads.
137-
2. Generates appropriate interceptor methods for each overload.
138-
3. Adds the XML comment transformers to the OpenAPI options.
139-
140-
When the interceptor runs, it:
141-
142-
1. Adds the XML-specific transformers.
143-
1. Applies any transformers the user has registered in their application code. This allows user transformers to inspect metadata that has been automatically set by the source generated transformer implementations.
144-
145-
### Runtime behavior
146-
147-
When the generated code runs:
148-
149-
1. The XML comment cache is populated on first use with structured comment data.
150-
2. The intercepted `AddOpenApi` methods add the transformers to the OpenAPI options.
151-
3. During API documentation generation, the transformers:
152-
* Look up documentation for API methods and apply summaries, descriptions, etc.
153-
* Apply parameter documentation to OpenAPI parameters.
154-
* Set response descriptions based on XML documentation.
155-
* Include [examples](#add-examples) when provided in the XML.
156-
157-
The generator processes standard XML code comments and adds them to the generated OpenAPI documentation.
158124

159125
<!-- ## Frequently Asked Questions
160126
161127
Moved to intro ### What is the OpenAPI XML documentation support feature?
162128
163129
The feature automatically extracts XML documentation comments from code and uses them to populate OpenAPI documentation. API documentation is generated directly from code comments, keeping them in sync. -->
164130

165-
### How does the XML documentation support work?
166-
167-
It uses a C# source generator, [`XmlCommentGenerator`](https://source.dot.net/#Microsoft.AspNetCore.OpenApi.SourceGenerators/XmlCommentGenerator.cs,30eb0aa73ef6306a), that analyzes XML documentation at compile time and injects code that translates those comments into OpenAPI specification metadata.
168-
169-
### Why is this implemented as a source generator?
170-
171-
Source generators allow us to implement [AOT](/aspnet/core/fundamentals/native-aot) compatible resolution of [`inheritdoc`](/dotnet/csharp/language-reference/xmldoc/recommended-tags) references in XML comments.
172-
173-
### How do I enable XML documentation in my ASP.NET Core API project?
174131

175-
1. Enable XML documentation in your project file:
176132

177-
:::code language="xml" source="~/fundamentals/openapi/samples/10.x/aspnet-openapi-xml/models/Models.csproj" highlight="7":::
178-
179-
2. Use the `AddOpenApi` method in your service configuration. No configuration is needed, the source generator handles the rest.
180-
181-
:::code language="csharp" source="~/fundamentals/openapi/samples/10.x/aspnet-openapi-xml/api/Program.cs" highlight="6":::
182-
183-
### Do I need to include XML documentation files from referenced assemblies?
184133

185-
Yes, for referenced assemblies with API types. Add them as `AdditionalFiles` in the project:
186-
187-
```xml
188-
<ItemGroup>
189-
<AdditionalFiles Include="Path/To/AssemblyDoc.xml" />
190-
</ItemGroup>
191-
```
192134

193135
XML documentation comments from `ProjectReferences` are automatically resolved and don't require additional configuration.
194136

195137
### Supported XML documentation tags
196-
<!-- review: removing defns for links, can revert -->
197-
* [`<summary>`](/dotnet/csharp/language-reference/xmldoc/recommended-tags#summary) <!-- - Used for operation and type descriptions -->
198-
* [`<remarks>`](/dotnet/csharp/language-reference/xmldoc/recommended-tags#remarks) <!-- - Used for additional operation details -->
199-
* [`<param>`](/dotnet/csharp/language-reference/xmldoc/recommended-tags#param) <!-- - Used for parameter descriptions -->
200-
* [`<returns>`](/dotnet/csharp/language-reference/xmldoc/recommended-tags#returns) <!-- - Used for return value descriptions -->
201-
* [`<response>`](/dotnet/csharp/language-reference/xmldoc/recommended-tags#response) <!-- - Used for HTTP response documentation -->
202-
* [`<example>`](/dotnet/csharp/language-reference/xmldoc/recommended-tags#example) <!-- - Used for examples in documentation -->
203-
* [`<deprecated>`](/dotnet/csharp/language-reference/xmldoc/recommended-tags#deprecated) <!-- - Marks operations as deprecated -->
204-
* [`<inheritdoc>`](/dotnet/csharp/language-reference/xmldoc/recommended-tags#inheritdoc) <!-- - Inherits documentation from base classes/interfaces -->
138+
139+
* [`<summary>`](/dotnet/csharp/language-reference/xmldoc/recommended-tags#summary)
140+
* [`<remarks>`](/dotnet/csharp/language-reference/xmldoc/recommended-tags#remarks)
141+
* [`<param>`](/dotnet/csharp/language-reference/xmldoc/recommended-tags#param)
142+
* [`<returns>`](/dotnet/csharp/language-reference/xmldoc/recommended-tags#returns)
143+
* [`<response>`](/dotnet/csharp/language-reference/xmldoc/recommended-tags#response)
144+
* [`<example>`](/dotnet/csharp/language-reference/xmldoc/recommended-tags#example)
145+
* [`<deprecated>`](/dotnet/csharp/language-reference/xmldoc/recommended-tags#deprecated)
146+
* [`<inheritdoc>`](/dotnet/csharp/language-reference/xmldoc/recommended-tags#inheritdoc)
205147

206148
### Document HTTP responses
207149

@@ -223,40 +165,9 @@ To add examples to documentation, use the [`<example>`](/dotnet/csharp/language-
223165
/// <param name="id" example="42">The unique identifier</param>
224166
```
225167

226-
<!-- move FAQ to topic -->
227-
228-
### How does the source generator identify and track API members? zzz move to impl
229-
230-
The source generator uses an [`XmlComment Cache`](https://github.com/dotnet/aspnetcore/blob/main/src/OpenApi/gen/XmlCommentGenerator.Emitter.cs#L84-L96) class to identify and track API members. It create a unique identifier for each API member that encodes:
231-
232-
* Declaring and property types.
233-
* Method names.
234-
* Generic types with proper handling of open generics.
235-
* Method overloads with parameter signature matching.
236-
237-
### XML documentation processing and runtime performance
238-
239-
XML documentation processing doesn't impact runtime performance. The source generator processes XML documentation at compile time and caches the results, with minimal runtime overhead when rendering the OpenAPI documentation. Furthermore, the OpenAPI document can be cached at runtime using [output-caching](/aspnet/core/performance/caching/overview#output-caching) to further optimize performance.
240-
241-
### Source generator and interception of `AddOpenApi` calls
242-
243-
The source generator uses the [C# compiler's interceptor ](/dotnet/csharp/whats-new/csharp-12#interceptors)feature to detect calls to `AddOpenApi` and automatically injects the XML documentation transformers.
168+
<!-- move FAQ to topic --> zzz
244169

245-
### What happens when I use different overloads of `AddOpenApi`?
246170

247-
The source generator detects all standard overloads:
248-
249-
* `AddOpenApi()`
250-
* `AddOpenApi("v1")`
251-
* `AddOpenApi(options => {})`
252-
* `AddOpenApi("v1", options => {})`
253-
254-
Each overload is intercepted to automatically include the XML documentation transformers. The source generator doesn't handle overloads where the `documentName` parameter isn't a literal string expression. For example, the transformer isn't registered in the following scenarios:
255-
256-
```csharp
257-
var documentName = "v1";
258-
builder.Services.AddOpenApi(documentName); // No XML support
259-
```
260171

261172
<a name="download10"></a>
262173

@@ -290,8 +201,8 @@ Navigate to [http://localhost:5052/](http://localhost:5052/) to view the Scalar
290201

291202
## Additional resources
292203

204+
* [Source generator implementation notes](https://github.com/captainsafia/aspnet-openapi-xml#implementation-notes)
293205
* The source generator implementation can be found in the [ASP.NET Core repository](https://github.com/dotnet/aspnetcore/tree/main/src/OpenApi/gen).
294-
[Source generator implementation notes](https://github.com/captainsafia/aspnet-openapi-xml#implementation-notes)
295206
* <xref:fundamentals/openapi/aspnetcore-openapi>
296207
* <xref:fundamentals/openapi/using-openapi-documents>
297208
* <xref:fundamentals/openapi/openapi-tools>

0 commit comments

Comments
 (0)