1- // Copyright (C) 2009-2020 Xtensive LLC.
1+ // Copyright (C) 2009-2021 Xtensive LLC.
22// This code is distributed under MIT license terms.
33// See the License.txt file in the project root for more information.
44// Created by: Dmitri Maximov
@@ -151,12 +151,12 @@ public void ProcessProperties(TypeDef typeDef, HierarchyDef hierarchyDef)
151151 }
152152
153153 // FieldAttribute presence is required
154- var fieldAttributes = GetFieldAttributes < FieldAttribute > ( propertyInfo ) ;
155- if ( fieldAttributes . Length == 0 ) {
154+ var reversedFieldAttributes = GetReversedFieldAttributes < FieldAttribute > ( propertyInfo ) ;
155+ if ( reversedFieldAttributes . Count == 0 ) {
156156 continue ;
157157 }
158158
159- var field = DefineField ( propertyInfo , fieldAttributes ) ;
159+ var field = DefineField ( propertyInfo , reversedFieldAttributes ) ;
160160
161161 // Declared & inherited fields must be processed for hierarchy root
162162 if ( hierarchyDef != null ) {
@@ -284,9 +284,9 @@ public HierarchyDef DefineHierarchy(TypeDef typeDef, HierarchyRootAttribute attr
284284 }
285285
286286 public FieldDef DefineField ( PropertyInfo propertyInfo ) =>
287- DefineField ( propertyInfo , GetFieldAttributes < FieldAttribute > ( propertyInfo ) ) ;
287+ DefineField ( propertyInfo , GetReversedFieldAttributes < FieldAttribute > ( propertyInfo ) ) ;
288288
289- public FieldDef DefineField ( PropertyInfo propertyInfo , FieldAttribute [ ] fieldAttributes )
289+ public FieldDef DefineField ( PropertyInfo propertyInfo , IReadOnlyList < FieldAttribute > reversedFieldAttributes )
290290 {
291291 // Persistent indexers are not supported
292292 var indexParameters = propertyInfo . GetIndexParameters ( ) ;
@@ -297,21 +297,21 @@ public FieldDef DefineField(PropertyInfo propertyInfo, FieldAttribute[] fieldAtt
297297 var fieldDef = new FieldDef ( propertyInfo , context . Validator ) ;
298298 fieldDef . Name = context . NameBuilder . BuildFieldName ( fieldDef ) ;
299299
300- if ( fieldAttributes . Length > 0 ) {
301- foreach ( var attribute in fieldAttributes ) {
302- attributeProcessor . Process ( fieldDef , attribute ) ;
300+ if ( reversedFieldAttributes . Count > 0 ) {
301+ for ( int i = reversedFieldAttributes . Count ; i -- > 0 ; ) {
302+ attributeProcessor . Process ( fieldDef , reversedFieldAttributes [ i ] ) ;
303303 }
304304
305305 // Association
306- var associationAttributes = GetFieldAttributes < AssociationAttribute > ( propertyInfo ) ;
307- foreach ( var attribute in associationAttributes ) {
308- attributeProcessor . Process ( fieldDef , attribute ) ;
306+ var reversedAssociationAttributes = GetReversedFieldAttributes < AssociationAttribute > ( propertyInfo ) ;
307+ for ( int i = reversedAssociationAttributes . Count ; i -- > 0 ; ) {
308+ attributeProcessor . Process ( fieldDef , reversedAssociationAttributes [ i ] ) ;
309309 }
310310
311311 // Mapping name
312- var mappingAttributes = GetFieldAttributes < FieldMappingAttribute > ( propertyInfo ) ;
313- foreach ( var attribute in mappingAttributes ) {
314- attributeProcessor . Process ( fieldDef , attribute ) ;
312+ var reversedMappingAttributes = GetReversedFieldAttributes < FieldMappingAttribute > ( propertyInfo ) ;
313+ for ( int i = reversedMappingAttributes . Count ; i -- > 0 ; ) {
314+ attributeProcessor . Process ( fieldDef , reversedMappingAttributes [ i ] ) ;
315315 }
316316
317317 // Type discriminator
@@ -370,16 +370,11 @@ private bool ShouldSkipFulltextIndex(TypeDef typeDef)
370370 return hierarchy == null && ! typeDef . IsStructure ;
371371 }
372372
373- private static T [ ] GetFieldAttributes < T > ( PropertyInfo property )
374- where T : Attribute
375- {
376- var attributes = property . GetAttributes < T > ( AttributeSearchOptions . InheritAll ) ;
377- // Attributes will contain attributes from all inheritance chain
378- // with the most specific type first.
379- // Reverse them for correct processing (i.e. descendants override settings from base).
380- Array . Reverse ( attributes ) ;
381- return attributes ;
382- }
373+ // Attributes will contain attributes from all inheritance chain
374+ // with the most specific type first.
375+ // Should be enumerated in reversed order for correct processing (i.e. descendants override settings from base).
376+ private static IReadOnlyList < T > GetReversedFieldAttributes < T > ( PropertyInfo property ) where T : Attribute =>
377+ property . GetAttributes < T > ( AttributeSearchOptions . InheritAll ) ;
383378
384379 private bool IsTypeAvailable ( Type type ) =>
385380 context . BuilderConfiguration . ModelFilter . IsTypeAvailable ( type )
0 commit comments