@@ -51,14 +51,38 @@ public void Apply(OpenApiDocument document, DocumentFilterContext context)
5151 if ( TryGetTableEntityType ( controller , out Type ? entityType ) )
5252 {
5353 string ? routePath = GetRoutePathFromContext ( context , controller ) ;
54- if ( routePath != null )
54+ if ( routePath is not null )
5555 {
5656 ProcessController ( entityType ! , routePath , document , context ) ;
5757 }
5858 }
5959 }
6060 }
6161
62+ /// <summary>
63+ /// Adds the schema reference for the entity type if it hasn't already been processed.
64+ /// </summary>
65+ /// <param name="context">The document filter context.</param>
66+ /// <param name="document">The OpenApi document.</param>
67+ /// <param name="entityType">The entity type</param>
68+ internal void AddSchemaReferenceForEntity ( DocumentFilterContext context , OpenApiDocument document , Type entityType )
69+ {
70+ if ( this . processedEntityNames . Contains ( entityType . Name ) )
71+ {
72+ return ;
73+ }
74+
75+ // Generate a schema for the entity if it doesn't exist.
76+ if ( context . SchemaRepository . Schemas . GetValueOrDefault ( entityType . Name ) is null )
77+ {
78+ _ = context . SchemaGenerator . GenerateSchema ( entityType , context . SchemaRepository ) ;
79+ }
80+
81+ context . SchemaRepository . Schemas [ entityType . Name ] . MakeSystemPropertiesReadonly ( ) ;
82+ _ = document . AddComponent ( entityType . Name , context . SchemaRepository . Schemas [ entityType . Name ] ) ;
83+ this . processedEntityNames . Add ( entityType . Name ) ;
84+ }
85+
6286 /// <summary>
6387 /// Applies the necessary changes to the <see cref="OpenApiDocument"/> for a single controller.
6488 /// </summary>
@@ -80,44 +104,31 @@ internal void ProcessController(Type entityType, string routePath, OpenApiDocume
80104 AddOperationIfPresent ( operations , OpType . List , document , allEntitiesPath , HttpMethod . Get ) ;
81105 AddOperationIfPresent ( operations , OpType . Replace , document , singleEntityPath , HttpMethod . Put ) ;
82106
83- // Make the system properties in the entity read-only
84- if ( ! this . processedEntityNames . Contains ( entityType . Name ) )
85- {
86- // Generate a schema for the entity if it doesn't exist.
87- if ( context . SchemaRepository . Schemas . GetValueOrDefault ( entityType . Name ) == null )
88- {
89- _ = context . SchemaGenerator . GenerateSchema ( entityType , context . SchemaRepository ) ;
90- }
91-
92- // This is a Datasync schema, so update the schema for the datasync attributes.
93- context . SchemaRepository . Schemas [ entityType . Name ] . MakeSystemPropertiesReadonly ( ) ;
94- context . SchemaRepository . Schemas [ entityType . Name ] . UnresolvedReference = false ;
95- context . SchemaRepository . Schemas [ entityType . Name ] . Reference = new OpenApiReference
96- {
97- Id = entityType . Name ,
98- Type = ReferenceType . Schema
99- } ;
100- this . processedEntityNames . Add ( entityType . Name ) ;
101- }
107+ // Add the schema for the entity type if it doesn't already exist.
108+ AddSchemaReferenceForEntity ( context , document , entityType ) ;
109+ IOpenApiSchema schema = new OpenApiSchemaReference ( entityType . Name , document ) ;
102110
111+ // Create the schema for a list of entities.
103112 Type listEntityType = typeof ( Page < > ) . MakeGenericType ( entityType ) ;
104- OpenApiSchema listSchemaRef = context . SchemaRepository . Schemas . GetValueOrDefault ( listEntityType . Name )
113+ IOpenApiSchema listSchemaRef = context . SchemaRepository . Schemas . GetValueOrDefault ( listEntityType . Name )
105114 ?? context . SchemaGenerator . GenerateSchema ( listEntityType , context . SchemaRepository ) ;
106115
107116 foreach ( KeyValuePair < OpType , OpenApiOperation > operation in operations )
108117 {
118+ operation . Value . Responses ??= [ ] ;
119+
109120 // Each operation also has certain modifications.
110121 switch ( operation . Key )
111122 {
112123 case OpType . Create :
113124 // Request Edits
114125 operation . Value . AddConditionalHeader ( true ) ;
115- operation . Value . AddRequestWithContent ( context . SchemaRepository . Schemas [ entityType . Name ] ) ;
126+ operation . Value . AddRequestWithContent ( schema ) ;
116127
117128 // Response Edits
118- operation . Value . AddResponseWithContent ( "201" , "Created" , context . SchemaRepository . Schemas [ entityType . Name ] ) ;
129+ operation . Value . AddResponseWithContent ( "201" , "Created" , schema ) ;
119130 operation . Value . Responses [ "400" ] = new OpenApiResponse { Description = "Bad Request" } ;
120- operation . Value . AddConflictResponse ( context . SchemaRepository . Schemas [ entityType . Name ] ) ;
131+ operation . Value . AddConflictResponse ( schema ) ;
121132 break ;
122133
123134 case OpType . Delete :
@@ -128,15 +139,15 @@ internal void ProcessController(Type entityType, string routePath, OpenApiDocume
128139 operation . Value . Responses [ "204" ] = new OpenApiResponse { Description = "No Content" } ;
129140 operation . Value . Responses [ "404" ] = new OpenApiResponse { Description = "Not Found" } ;
130141 operation . Value . Responses [ "410" ] = new OpenApiResponse { Description = "Gone" } ;
131- operation . Value . AddConflictResponse ( context . SchemaRepository . Schemas [ entityType . Name ] ) ;
142+ operation . Value . AddConflictResponse ( schema ) ;
132143 break ;
133144
134145 case OpType . GetById :
135146 // Request Edits
136147 operation . Value . AddConditionalHeader ( true ) ;
137148
138149 // Response Edits
139- operation . Value . AddResponseWithContent ( "200" , "OK" , context . SchemaRepository . Schemas [ entityType . Name ] ) ;
150+ operation . Value . AddResponseWithContent ( "200" , "OK" , schema ) ;
140151 operation . Value . Responses [ "304" ] = new OpenApiResponse { Description = "Not Modified" } ;
141152 operation . Value . Responses [ "404" ] = new OpenApiResponse { Description = "Not Found" } ;
142153 break ;
@@ -153,14 +164,14 @@ internal void ProcessController(Type entityType, string routePath, OpenApiDocume
153164 case OpType . Replace :
154165 // Request Edits
155166 operation . Value . AddConditionalHeader ( ) ;
156- operation . Value . AddRequestWithContent ( context . SchemaRepository . Schemas [ entityType . Name ] ) ;
167+ operation . Value . AddRequestWithContent ( schema ) ;
157168
158169 // Response Edits
159- operation . Value . AddResponseWithContent ( "200" , "OK" , context . SchemaRepository . Schemas [ entityType . Name ] ) ;
170+ operation . Value . AddResponseWithContent ( "200" , "OK" , schema ) ;
160171 operation . Value . Responses [ "400" ] = new OpenApiResponse { Description = "Bad Request" } ;
161172 operation . Value . Responses [ "404" ] = new OpenApiResponse { Description = "Not Found" } ;
162173 operation . Value . Responses [ "410" ] = new OpenApiResponse { Description = "Gone" } ;
163- operation . Value . AddConflictResponse ( context . SchemaRepository . Schemas [ entityType . Name ] ) ;
174+ operation . Value . AddConflictResponse ( schema ) ;
164175 break ;
165176 }
166177 }
@@ -227,7 +238,7 @@ internal static bool IsApiDescriptionForController(ApiDescription description, T
227238 /// <param name="assembly">The assembly to query. Be default, the calling assembly is queried.</param>
228239 /// <returns>The list of table controllers in the assembly.</returns>
229240 internal static List < Type > GetAllTableControllers ( Assembly ? assembly )
230- => ( assembly ?? Assembly . GetCallingAssembly ( ) ) . GetTypes ( ) . Where ( IsTableController ) . ToList ( ) ;
241+ => [ .. ( assembly ?? Assembly . GetCallingAssembly ( ) ) . GetTypes ( ) . Where ( IsTableController ) ] ;
231242
232243 /// <summary>
233244 /// Determines if the controller type provided is a datasync table controller.
@@ -236,9 +247,9 @@ internal static List<Type> GetAllTableControllers(Assembly? assembly)
236247 /// <returns><c>true</c> if the type is a datasync table controller.</returns>
237248 internal static bool IsTableController ( Type type )
238249 {
239- if ( ! type . IsAbstract && type . BaseType != null && type . BaseType . IsGenericType == true )
250+ if ( ! type . IsAbstract && type . BaseType is not null && type . BaseType . IsGenericType == true )
240251 {
241- if ( type . GetCustomAttribute < DatasyncControllerAttribute > ( ) != null )
252+ if ( type . GetCustomAttribute < DatasyncControllerAttribute > ( ) is not null )
242253 {
243254 return true ;
244255 }
0 commit comments