3
3
4
4
using System ;
5
5
using System . Collections . Generic ;
6
+ using System . Linq ;
6
7
using Microsoft . OpenApi . Exceptions ;
7
8
using Microsoft . OpenApi . Models ;
8
9
using Microsoft . OpenApi . Properties ;
10
+ using Microsoft . OpenApi . Interfaces ;
9
11
10
12
namespace Microsoft . OpenApi . Validations . Visitors
11
13
{
@@ -14,39 +16,23 @@ namespace Microsoft.OpenApi.Validations.Visitors
14
16
/// </summary>
15
17
internal static class OpenApiVisitorSet
16
18
{
17
- private static IDictionary < Type , IVisitor > _visitorCache = new Dictionary < Type , IVisitor >
19
+ private static IDictionary < Type , IVisitor > _visitors ;
20
+
21
+ /// <summary>
22
+ /// Gets the visitors
23
+ /// </summary>
24
+ public static IDictionary < Type , IVisitor > Visitors
18
25
{
19
- { typeof ( OpenApiCallback ) , new CallbackVisitor ( ) } ,
20
- { typeof ( OpenApiComponents ) , new ComponentsVisitor ( ) } ,
21
- { typeof ( OpenApiContact ) , new ContactVisitor ( ) } ,
22
- { typeof ( OpenApiDiscriminator ) , new DiscriminatorVisitor ( ) } ,
23
- { typeof ( OpenApiDocument ) , new DocumentVisitor ( ) } ,
24
- { typeof ( OpenApiEncoding ) , new EncodingVisitor ( ) } ,
25
- { typeof ( OpenApiExample ) , new ExampleVisitor ( ) } ,
26
- { typeof ( OpenApiExternalDocs ) , new ExternalDocsVisitor ( ) } ,
27
- { typeof ( OpenApiHeader ) , new HeaderVisitor ( ) } ,
28
- { typeof ( OpenApiInfo ) , new InfoVisitor ( ) } ,
29
- { typeof ( OpenApiLicense ) , new LicenseVisitor ( ) } ,
30
- { typeof ( OpenApiLink ) , new LinkVisitor ( ) } ,
31
- { typeof ( OpenApiMediaType ) , new MediaTypeVisitor ( ) } ,
32
- { typeof ( OpenApiOAuthFlows ) , new OAuthFlowsVisitor ( ) } ,
33
- { typeof ( OpenApiOAuthFlow ) , new OAuthFlowVisitor ( ) } ,
34
- { typeof ( OpenApiOperation ) , new OperationVisitor ( ) } ,
35
- { typeof ( OpenApiParameter ) , new ParameterVisitor ( ) } ,
36
- { typeof ( OpenApiPathItem ) , new PathItemVisitor ( ) } ,
37
- { typeof ( OpenApiPaths ) , new PathsVisitor ( ) } ,
38
- { typeof ( OpenApiRequestBody ) , new RequestBodyVisitor ( ) } ,
39
- { typeof ( OpenApiResponses ) , new ResponsesVisitor ( ) } ,
40
- { typeof ( OpenApiResponse ) , new ResponseVisitor ( ) } ,
41
- { typeof ( OpenApiSchema ) , new SchemaVisitor ( ) } ,
42
- { typeof ( OpenApiSecurityRequirement ) , new SecurityRequirementVisitor ( ) } ,
43
- { typeof ( OpenApiSecurityScheme ) , new SecuritySchemeVisitor ( ) } ,
44
- { typeof ( OpenApiServerVariable ) , new ServerVariableVisitor ( ) } ,
45
- { typeof ( OpenApiServer ) , new ServerVisitor ( ) } ,
46
- { typeof ( OpenApiTag ) , new TagVisitor ( ) } ,
47
- { typeof ( OpenApiXml ) , new XmlVisitor ( ) }
48
- } ;
26
+ get
27
+ {
28
+ if ( _visitors == null )
29
+ {
30
+ _visitors = new Lazy < IDictionary < Type , IVisitor > > ( ( ) => BuildVisitorSet ( ) , isThreadSafe : false ) . Value ;
31
+ }
49
32
33
+ return _visitors ;
34
+ }
35
+ }
50
36
/// <summary>
51
37
/// Get the element visitor.
52
38
/// </summary>
@@ -55,12 +41,51 @@ internal static class OpenApiVisitorSet
55
41
public static IVisitor GetVisitor ( Type elementType )
56
42
{
57
43
IVisitor visitor ;
58
- if ( _visitorCache . TryGetValue ( elementType , out visitor ) )
44
+ if ( Visitors . TryGetValue ( elementType , out visitor ) )
59
45
{
60
46
return visitor ;
61
47
}
62
48
63
49
throw new OpenApiException ( String . Format ( SRResource . UnknownVisitorType , elementType . FullName ) ) ;
64
50
}
51
+
52
+ private static IDictionary < Type , IVisitor > BuildVisitorSet ( )
53
+ {
54
+ IDictionary < Type , IVisitor > visitors = new Dictionary < Type , IVisitor > ( ) ;
55
+
56
+ IEnumerable < Type > allTypes = typeof ( OpenApiVisitorSet ) . Assembly . GetTypes ( ) . Where ( t => t . IsClass && ! t . IsAbstract && t != typeof ( object ) ) ;
57
+
58
+ Type visitorInterfaceType = typeof ( IVisitor ) ;
59
+ Type elementType = typeof ( IOpenApiElement ) ;
60
+ foreach ( Type type in allTypes )
61
+ {
62
+ if ( ! visitorInterfaceType . IsAssignableFrom ( type ) )
63
+ {
64
+ continue ;
65
+ }
66
+
67
+ Type baseType = type . BaseType ;
68
+ if ( baseType == null || ! baseType . IsGenericType ||
69
+ baseType . GetGenericTypeDefinition ( ) != typeof ( VisitorBase < > ) )
70
+ {
71
+ continue ;
72
+ }
73
+
74
+ Type validationType = baseType . GetGenericArguments ( ) [ 0 ] ;
75
+ if ( ! elementType . IsAssignableFrom ( validationType ) )
76
+ {
77
+ continue ;
78
+ }
79
+
80
+ object instance = Activator . CreateInstance ( type ) ;
81
+ IVisitor visitor = instance as IVisitor ;
82
+ if ( visitor != null )
83
+ {
84
+ visitors [ validationType ] = visitor ;
85
+ }
86
+ }
87
+
88
+ return visitors ;
89
+ }
65
90
}
66
91
}
0 commit comments