@@ -8,13 +8,14 @@ namespace Microsoft.Extensions.DependencyInjection;
88using Asp . Versioning . ApiExplorer ;
99using Asp . Versioning . OpenApi ;
1010using Asp . Versioning . OpenApi . Configuration ;
11- using Asp . Versioning . OpenApi . Reflection ;
1211using Asp . Versioning . OpenApi . Transformers ;
1312using Microsoft . AspNetCore . Http . Json ;
1413using Microsoft . AspNetCore . OpenApi ;
1514using Microsoft . Extensions . DependencyInjection . Extensions ;
1615using Microsoft . Extensions . Hosting ;
1716using Microsoft . Extensions . Options ;
17+ using System . ComponentModel . Design ;
18+ using System . Diagnostics ;
1819using System . Reflection ;
1920using static Microsoft . Extensions . DependencyInjection . ServiceDescriptor ;
2021using EM = Microsoft . Extensions . DependencyInjection . ServiceProviderServiceExtensions ;
@@ -56,26 +57,22 @@ public IApiVersioningBuilder AddOpenApi( Action<VersionedOpenApiOptions> configu
5657 return builder ;
5758 }
5859 }
59-
60+ #pragma warning disable
6061 [ UnconditionalSuppressMessage ( "ILLink" , "IL2026" ) ]
6162 private static void AddOpenApiServices ( IApiVersioningBuilder builder , Assembly [ ] assemblies )
6263 {
6364 builder . AddApiExplorer ( ) ;
6465
6566 var services = builder . Services ;
6667
67- services . AddTransient ( NewRequestServices ) ;
68- services . Add ( Singleton ( Type . IDocumentProvider , ResolveDocumentProvider ) ) ;
68+ services . AddTransient ( serviceProvider => NewRequestServices ( serviceProvider , services ) ) ;
69+ // services.AddOpenApi();
70+
6971 services . AddSingleton < VersionedOpenApiOptionsFactory > ( ) ;
70- services . TryAddEnumerable ( Transient < IPostConfigureOptions < OpenApiOptions > , ConfigureOpenApiOptions > ( ) ) ;
7172 services . TryAdd ( Singleton < IOptionsFactory < VersionedOpenApiOptions > > ( EM . GetRequiredService < VersionedOpenApiOptionsFactory > ) ) ;
7273 services . AddTransient ( sp => new XmlCommentsFile ( assemblies , sp . GetRequiredService < IHostEnvironment > ( ) ) ) ;
7374 services . TryAddTransient ( sp => new XmlCommentsTransformer ( sp . GetRequiredService < XmlCommentsFile > ( ) ) ) ;
7475
75- if ( GetJsonConfiguration ( ) is { } descriptor )
76- {
77- services . TryAddEnumerable ( descriptor ) ;
78- }
7976 }
8077
8178 // NOTE: The calling assembly must be captured at the call site that invokes AddOpenApi. In 99% of the cases that
@@ -94,53 +91,19 @@ private static Assembly[] GetAssemblies( Assembly callingAssembly )
9491 return [ .. assemblies ] ;
9592 }
9693
97- // HACK: the json configuration is internal; this approach negates the use of reflection
98- // REF: https://github.com/dotnet/aspnetcore/blob/08a9fc2c3864d99759ab3d71cfda868d852bfc4b/src/OpenApi/src/Extensions/OpenApiServiceCollectionExtensions.cs#L121
99- private static ServiceDescriptor ? GetJsonConfiguration ( )
100- {
101- var services = new ServiceCollection ( ) ;
102- services . AddOpenApi ( "*" ) ;
103- return services . SingleOrDefault ( sd => sd . ServiceType == typeof ( IConfigureOptions < JsonOptions > ) ) ;
104- }
105-
106- private static object ResolveDocumentProvider ( IServiceProvider provider ) =>
107- provider . GetRequiredService < KeyedServiceContainer > ( ) . GetRequiredService ( Type . IDocumentProvider ) ;
108-
10994 [ UnconditionalSuppressMessage ( "ILLink" , "IL3050" ) ]
110- private static KeyedServiceContainer NewRequestServices ( IServiceProvider services )
95+ private static AggregateKeyedServiceProvider NewRequestServices ( IServiceProvider services , IServiceCollection parentServiceCollection )
11196 {
11297 var provider = services . GetRequiredService < IApiVersionDescriptionProvider > ( ) ;
113- var container = new KeyedServiceContainer ( services ) ;
114- var type = typeof ( IOpenApiDocumentProvider ) ;
98+ var container = new AggregateKeyedServiceProvider ( services ) ;
11599 var descriptions = provider . ApiVersionDescriptions ;
116- var names = new List < string > ( descriptions . Count ) ;
117100
118101 for ( var i = 0 ; i < descriptions . Count ; i ++ )
119102 {
120103 var description = descriptions [ i ] ;
121-
122- // REF: https://github.com/dotnet/aspnetcore/blob/319e87fd950a99f3baae2aa79db3d4fb68783d85/src/OpenApi/src/Extensions/OpenApiServiceCollectionExtensions.cs#L64
123- #pragma warning disable CA1308 // Normalize strings to uppercase
124- var key = description . GroupName . ToLowerInvariant ( ) ;
125- #pragma warning restore CA1308
126-
127- names . Add ( key ) ;
128- container . AddService ( Type . OpenApiSchemaService , key , Class . OpenApiSchemaService . New ) ;
129- container . AddService ( Type . OpenApiDocumentService , key , Class . OpenApiDocumentService . New ) ;
130- container . AddService ( type , key , ( sp , k ) => sp . GetRequiredKeyedService ( Type . OpenApiDocumentService , k ) ) ;
131- }
132-
133- if ( names . Count > 0 )
134- {
135- var array = Array . CreateInstance ( Type . NamedService , names . Count ) ;
136-
137- for ( var i = 0 ; i < names . Count ; i ++ )
138- {
139- array . SetValue ( Class . NamedService . New ( names [ i ] ) , i ) ;
140- }
141-
142- container . AddService ( Type . IDocumentProvider , Class . OpenApiDocumentProvider . New ) ;
143- container . AddService ( Type . IEnumerableOfNamedService , array ) ;
104+ var serviceCollection = new ServiceCollection ( ) ;
105+ serviceCollection . AddOpenApi ( description . GroupName ) ;
106+ container . Add ( serviceCollection , parentServiceCollection ) ;
144107 }
145108
146109 return container ;
0 commit comments