1
- using System . Reflection ;
2
- using System . Text . Json ;
3
- using JsonApiDotNetCore . Configuration ;
4
1
using JsonApiDotNetCore . Middleware ;
5
2
using JsonApiDotNetCore . OpenApi . SwaggerComponents ;
3
+ using Microsoft . AspNetCore . Mvc ;
6
4
using Microsoft . AspNetCore . Mvc . ApiExplorer ;
7
5
using Microsoft . AspNetCore . Mvc . Infrastructure ;
8
6
using Microsoft . Extensions . DependencyInjection ;
9
7
using Microsoft . Extensions . DependencyInjection . Extensions ;
10
- using Swashbuckle . AspNetCore . Swagger ;
8
+ using Microsoft . Extensions . Options ;
11
9
using Swashbuckle . AspNetCore . SwaggerGen ;
12
10
13
11
namespace JsonApiDotNetCore . OpenApi ;
@@ -23,14 +21,15 @@ public static void AddOpenApi(this IServiceCollection services, IMvcCoreBuilder
23
21
ArgumentGuard . NotNull ( mvcBuilder ) ;
24
22
25
23
AddCustomApiExplorer ( services , mvcBuilder ) ;
26
-
27
24
AddCustomSwaggerComponents ( services ) ;
25
+ AddSwaggerGenerator ( services ) ;
26
+
27
+ services . AddTransient < IConfigureOptions < MvcOptions > , ConfigureMvcOptions > ( ) ;
28
28
29
- using ServiceProvider provider = services . BuildServiceProvider ( ) ;
30
- using IServiceScope scope = provider . CreateScope ( ) ;
31
- AddSwaggerGenerator ( scope , services , setupSwaggerGenAction ) ;
32
- AddSwashbuckleCliCompatibility ( scope , mvcBuilder ) ;
33
- AddOpenApiEndpointConvention ( scope , mvcBuilder ) ;
29
+ if ( setupSwaggerGenAction != null )
30
+ {
31
+ services . Configure ( setupSwaggerGenAction ) ;
32
+ }
34
33
}
35
34
36
35
private static void AddCustomApiExplorer ( IServiceCollection services , IMvcCoreBuilder mvcBuilder )
@@ -44,96 +43,41 @@ private static void AddCustomApiExplorer(IServiceCollection services, IMvcCoreBu
44
43
var apiDescriptionProviders = provider . GetRequiredService < IEnumerable < IApiDescriptionProvider > > ( ) ;
45
44
var resourceFieldValidationMetadataProvider = provider . GetRequiredService < ResourceFieldValidationMetadataProvider > ( ) ;
46
45
47
- JsonApiActionDescriptorCollectionProvider descriptorCollectionProviderWrapper =
46
+ JsonApiActionDescriptorCollectionProvider jsonApiActionDescriptorCollectionProvider =
48
47
new ( controllerResourceMapping , actionDescriptorCollectionProvider , resourceFieldValidationMetadataProvider ) ;
49
48
50
- return new ApiDescriptionGroupCollectionProvider ( descriptorCollectionProviderWrapper , apiDescriptionProviders ) ;
49
+ return new ApiDescriptionGroupCollectionProvider ( jsonApiActionDescriptorCollectionProvider , apiDescriptionProviders ) ;
51
50
} ) ;
52
51
53
52
mvcBuilder . AddApiExplorer ( ) ;
54
53
55
54
mvcBuilder . AddMvcOptions ( options => options . InputFormatters . Add ( new JsonApiRequestFormatMetadataProvider ( ) ) ) ;
56
55
}
57
56
58
- private static void AddSwaggerGenerator ( IServiceScope scope , IServiceCollection services , Action < SwaggerGenOptions > ? setupSwaggerGenAction )
59
- {
60
- var controllerResourceMapping = scope . ServiceProvider . GetRequiredService < IControllerResourceMapping > ( ) ;
61
- var resourceGraph = scope . ServiceProvider . GetRequiredService < IResourceGraph > ( ) ;
62
- var jsonApiOptions = scope . ServiceProvider . GetRequiredService < IJsonApiOptions > ( ) ;
63
- JsonNamingPolicy ? namingPolicy = jsonApiOptions . SerializerOptions . PropertyNamingPolicy ;
64
-
65
- AddSchemaGenerator ( services ) ;
66
-
67
- services . AddSwaggerGen ( swaggerGenOptions =>
68
- {
69
- swaggerGenOptions . SupportNonNullableReferenceTypes ( ) ;
70
- SetOperationInfo ( swaggerGenOptions , controllerResourceMapping , namingPolicy ) ;
71
- SetSchemaIdSelector ( swaggerGenOptions , resourceGraph , namingPolicy ) ;
72
- swaggerGenOptions . DocumentFilter < EndpointOrderingFilter > ( ) ;
73
- swaggerGenOptions . UseAllOfToExtendReferenceSchemas ( ) ;
74
- swaggerGenOptions . OperationFilter < JsonApiOperationDocumentationFilter > ( ) ;
75
-
76
- setupSwaggerGenAction ? . Invoke ( swaggerGenOptions ) ;
77
- } ) ;
78
- }
79
-
80
- private static void AddSchemaGenerator ( IServiceCollection services )
81
- {
82
- services . TryAddSingleton < SchemaGenerator > ( ) ;
83
- services . TryAddSingleton < ISchemaGenerator , JsonApiSchemaGenerator > ( ) ;
84
- }
85
-
86
- private static void SetOperationInfo ( SwaggerGenOptions swaggerGenOptions , IControllerResourceMapping controllerResourceMapping ,
87
- JsonNamingPolicy ? namingPolicy )
88
- {
89
- swaggerGenOptions . TagActionsBy ( description => GetOperationTags ( description , controllerResourceMapping ) ) ;
90
-
91
- JsonApiOperationIdSelector jsonApiOperationIdSelector = new ( controllerResourceMapping , namingPolicy ) ;
92
- swaggerGenOptions . CustomOperationIds ( jsonApiOperationIdSelector . GetOperationId ) ;
93
- }
94
-
95
- private static IList < string > GetOperationTags ( ApiDescription description , IControllerResourceMapping controllerResourceMapping )
96
- {
97
- MethodInfo actionMethod = description . ActionDescriptor . GetActionMethod ( ) ;
98
- ResourceType ? resourceType = controllerResourceMapping . GetResourceTypeForController ( actionMethod . ReflectedType ) ;
99
-
100
- if ( resourceType == null )
101
- {
102
- throw new NotSupportedException ( "Only JsonApiDotNetCore endpoints are supported." ) ;
103
- }
104
-
105
- return new [ ]
106
- {
107
- resourceType . PublicName
108
- } ;
109
- }
110
-
111
- private static void SetSchemaIdSelector ( SwaggerGenOptions swaggerGenOptions , IResourceGraph resourceGraph , JsonNamingPolicy ? namingPolicy )
112
- {
113
- JsonApiSchemaIdSelector jsonApiSchemaIdSelector = new ( namingPolicy , resourceGraph ) ;
114
-
115
- swaggerGenOptions . CustomSchemaIds ( type => jsonApiSchemaIdSelector . GetSchemaId ( type ) ) ;
116
- }
117
-
118
57
private static void AddCustomSwaggerComponents ( IServiceCollection services )
119
58
{
120
- services . TryAddSingleton < SwaggerGenerator > ( ) ;
121
- services . TryAddSingleton < ISwaggerProvider , CachingSwaggerProvider > ( ) ;
122
-
123
59
services . TryAddSingleton < ISerializerDataContractResolver , JsonApiDataContractResolver > ( ) ;
60
+ services . TryAddSingleton < ResourceDocumentationReader > ( ) ;
61
+ services . TryAddSingleton < JsonApiOperationIdSelector > ( ) ;
62
+ services . TryAddSingleton < JsonApiSchemaIdSelector > ( ) ;
124
63
}
125
64
126
- private static void AddSwashbuckleCliCompatibility ( IServiceScope scope , IMvcCoreBuilder mvcBuilder )
65
+ private static void AddSwaggerGenerator ( IServiceCollection services )
127
66
{
128
- // See https://github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/1957 for why this is needed.
129
- var routingConvention = scope . ServiceProvider . GetRequiredService < IJsonApiRoutingConvention > ( ) ;
130
- mvcBuilder . AddMvcOptions ( options => options . Conventions . Insert ( 0 , routingConvention ) ) ;
67
+ AddSchemaGenerators ( services ) ;
68
+
69
+ services . AddSwaggerGen ( ) ;
70
+ services . AddSingleton < IConfigureOptions < SwaggerGenOptions > , ConfigureSwaggerGenOptions > ( ) ;
131
71
}
132
72
133
- private static void AddOpenApiEndpointConvention ( IServiceScope scope , IMvcCoreBuilder mvcBuilder )
73
+ private static void AddSchemaGenerators ( IServiceCollection services )
134
74
{
135
- var controllerResourceMapping = scope . ServiceProvider . GetRequiredService < IControllerResourceMapping > ( ) ;
75
+ services . TryAddSingleton < SchemaGenerator > ( ) ;
76
+ services . TryAddSingleton < ISchemaGenerator , JsonApiSchemaGenerator > ( ) ;
136
77
137
- mvcBuilder . AddMvcOptions ( options => options . Conventions . Add ( new OpenApiEndpointConvention ( controllerResourceMapping ) ) ) ;
78
+ services . TryAddSingleton < DocumentSchemaGenerator > ( ) ;
79
+ services . TryAddSingleton < ResourceTypeSchemaGenerator > ( ) ;
80
+ services . TryAddSingleton < ResourceIdentifierSchemaGenerator > ( ) ;
81
+ services . TryAddSingleton < ResourceDataSchemaGenerator > ( ) ;
138
82
}
139
83
}
0 commit comments