@@ -44,7 +44,7 @@ public GeneratedValidatablePropertyInfo(
4444 internal string Name { get ; }
4545
4646 protected override global ::System . ComponentModel . DataAnnotations . ValidationAttribute [ ] GetValidationAttributes ( )
47- => ValidationAttributeCache . GetValidationAttributes ( ContainingType , Name ) ;
47+ => ValidationAttributeCache . GetPropertyValidationAttributes ( ContainingType , Name ) ;
4848 }
4949
5050 [ global ::System . CodeDom . Compiler . GeneratedCodeAttribute ( "Microsoft.Extensions.Validation.ValidationsGenerator, Version=42.42.42.42, Culture=neutral, PublicKeyToken=adb9793829ddae60" , "42.42.42.42" ) ]
@@ -62,7 +62,7 @@ public GeneratedValidatableTypeInfo(
6262 internal global ::System . Type Type { get ; }
6363
6464 protected override global ::System . ComponentModel . DataAnnotations . ValidationAttribute [ ] GetValidationAttributes ( )
65- => ValidationAttributeCache . GetValidationAttributes ( Type , null ) ;
65+ => ValidationAttributeCache . GetTypeValidationAttributes ( Type ) ;
6666 }
6767
6868 [ global ::System . CodeDom . Compiler . GeneratedCodeAttribute ( "Microsoft.Extensions.Validation.ValidationsGenerator, Version=42.42.42.42, Culture=neutral, PublicKeyToken=adb9793829ddae60" , "42.42.42.42" ) ]
@@ -130,59 +130,70 @@ private sealed record CacheKey(
130130 [ property: global ::System . Diagnostics . CodeAnalysis . DynamicallyAccessedMembers ( global ::System . Diagnostics . CodeAnalysis . DynamicallyAccessedMemberTypes . PublicProperties | global ::System . Diagnostics . CodeAnalysis . DynamicallyAccessedMemberTypes . PublicConstructors ) ]
131131 global ::System . Type ContainingType ,
132132 string ? PropertyName ) ;
133- private static readonly global ::System . Collections . Concurrent . ConcurrentDictionary < CacheKey , global ::System . ComponentModel . DataAnnotations . ValidationAttribute [ ] > _cache = new ( ) ;
133+ private static readonly global ::System . Collections . Concurrent . ConcurrentDictionary < CacheKey , global ::System . ComponentModel . DataAnnotations . ValidationAttribute [ ] > _propertyCache = new ( ) ;
134+ private static readonly global ::System . Lazy < global ::System . Collections . Concurrent . ConcurrentDictionary < global ::System . Type , global ::System . ComponentModel . DataAnnotations . ValidationAttribute [ ] > > _lazyTypeCache = new ( ( ) => new ( ) ) ;
135+ private static global ::System . Collections . Concurrent . ConcurrentDictionary < global ::System . Type , global ::System . ComponentModel . DataAnnotations . ValidationAttribute [ ] > TypeCache => _lazyTypeCache . Value ;
134136
135- public static global ::System . ComponentModel . DataAnnotations . ValidationAttribute [ ] GetValidationAttributes (
137+ public static global ::System . ComponentModel . DataAnnotations . ValidationAttribute [ ] GetPropertyValidationAttributes (
136138 [ global ::System . Diagnostics . CodeAnalysis . DynamicallyAccessedMembers ( global ::System . Diagnostics . CodeAnalysis . DynamicallyAccessedMemberTypes . PublicProperties | global ::System . Diagnostics . CodeAnalysis . DynamicallyAccessedMemberTypes . PublicConstructors ) ]
137139 global ::System . Type containingType ,
138140 string ? propertyName )
139141 {
140142 var key = new CacheKey ( containingType , propertyName ) ;
141- return _cache . GetOrAdd ( key , static k =>
143+ return _propertyCache . GetOrAdd ( key , static k =>
142144 {
143145 var results = new global ::System . Collections . Generic . List < global ::System . ComponentModel . DataAnnotations . ValidationAttribute > ( ) ;
144146
145- if ( k . PropertyName is not null )
147+ // Get attributes from the property
148+ var property = k . ContainingType . GetProperty ( k . PropertyName ) ;
149+ if ( property != null )
146150 {
147- // Get attributes from the property
148- var property = k . ContainingType . GetProperty ( k . PropertyName ) ;
149- if ( property != null )
150- {
151- var propertyAttributes = global ::System . Reflection . CustomAttributeExtensions
152- . GetCustomAttributes < global ::System . ComponentModel . DataAnnotations . ValidationAttribute > ( property , inherit : true ) ;
151+ var propertyAttributes = global ::System . Reflection . CustomAttributeExtensions
152+ . GetCustomAttributes < global ::System . ComponentModel . DataAnnotations . ValidationAttribute > ( property , inherit : true ) ;
153153
154- results . AddRange ( propertyAttributes ) ;
155- }
154+ results . AddRange ( propertyAttributes ) ;
155+ }
156156
157- // Check constructors for parameters that match the property name
158- // to handle record scenarios
159- foreach ( var constructor in k . ContainingType . GetConstructors ( ) )
160- {
161- // Look for parameter with matching name (case insensitive)
162- var parameter = global ::System . Linq . Enumerable . FirstOrDefault (
163- constructor . GetParameters ( ) ,
164- p => string . Equals ( p . Name , k . PropertyName , global ::System . StringComparison . OrdinalIgnoreCase ) ) ;
157+ // Check constructors for parameters that match the property name
158+ // to handle record scenarios
159+ foreach ( var constructor in k . ContainingType . GetConstructors ( ) )
160+ {
161+ // Look for parameter with matching name (case insensitive)
162+ var parameter = global ::System . Linq . Enumerable . FirstOrDefault (
163+ constructor . GetParameters ( ) ,
164+ p => string . Equals ( p . Name , k . PropertyName , global ::System . StringComparison . OrdinalIgnoreCase ) ) ;
165165
166- if ( parameter != null )
167- {
168- var paramAttributes = global ::System . Reflection . CustomAttributeExtensions
169- . GetCustomAttributes < global ::System . ComponentModel . DataAnnotations . ValidationAttribute > ( parameter , inherit : true ) ;
166+ if ( parameter != null )
167+ {
168+ var paramAttributes = global ::System . Reflection . CustomAttributeExtensions
169+ . GetCustomAttributes < global ::System . ComponentModel . DataAnnotations . ValidationAttribute > ( parameter , inherit : true ) ;
170170
171- results . AddRange ( paramAttributes ) ;
171+ results . AddRange ( paramAttributes ) ;
172172
173- break ;
174- }
173+ break ;
175174 }
176175 }
177- else
176+
177+ return results . ToArray ( ) ;
178+ } ) ;
179+ }
180+
181+
182+ public static global ::System . ComponentModel . DataAnnotations . ValidationAttribute [ ] GetTypeValidationAttributes (
183+ [ global ::System . Diagnostics . CodeAnalysis . DynamicallyAccessedMembers ( global ::System . Diagnostics . CodeAnalysis . DynamicallyAccessedMemberTypes . Interfaces ) ]
184+ global ::System . Type type
185+ )
186+ {
187+ return TypeCache . GetOrAdd ( type , static t =>
188+ {
189+ var results = new global ::System . Collections . Generic . List < global ::System . ComponentModel . DataAnnotations . ValidationAttribute > ( ) ;
190+
191+ // Get attributes from the type itself and its super types
192+ foreach ( var attr in t . GetCustomAttributes ( typeof ( global ::System . ComponentModel . DataAnnotations . ValidationAttribute ) , true ) )
178193 {
179- // Get attributes from the type itself and its super types
180- foreach ( var attr in k . ContainingType . GetCustomAttributes ( typeof ( global ::System . ComponentModel . DataAnnotations . ValidationAttribute ) , true ) )
194+ if ( attr is global ::System . ComponentModel . DataAnnotations . ValidationAttribute validationAttribute )
181195 {
182- if ( attr is global ::System . ComponentModel . DataAnnotations . ValidationAttribute validationAttribute )
183- {
184- results . Add ( validationAttribute ) ;
185- }
196+ results . Add ( validationAttribute ) ;
186197 }
187198 }
188199
0 commit comments