Skip to content

Commit f441e00

Browse files
committed
Port #2632 AutoMap() is now aware of overridden properties in derived types
1 parent 210501a commit f441e00

File tree

2 files changed

+77
-1
lines changed

2 files changed

+77
-1
lines changed

src/Nest/CommonAbstractions/Extensions/TypeExtensions.cs

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,20 +178,53 @@ internal static IList<PropertyInfo> AllPropertiesCached(this Type t)
178178
}
179179

180180
/// <summary> Returns inherited properties with reflectedType set to base type</summary>
181+
/// <summary>
182+
/// Returns inherited properties with reflectedType set to base type
183+
/// </summary>
181184
private static IEnumerable<PropertyInfo> AllPropertiesNotCached(this Type type)
182185
{
186+
var propertiesByName = new Dictionary<string, PropertyInfo>();
183187
do
184188
{
185189
foreach (var propertyInfo in type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly))
186-
yield return propertyInfo;
190+
{
191+
if (propertiesByName.ContainsKey(propertyInfo.Name))
192+
{
193+
if (IsHidingMember(propertyInfo))
194+
{
195+
propertiesByName[propertyInfo.Name] = propertyInfo;
196+
}
197+
}
198+
else
199+
{
200+
propertiesByName.Add(propertyInfo.Name, propertyInfo);
201+
}
202+
}
187203
#if DOTNETCORE
188204
type = type.GetTypeInfo()?.BaseType;
189205
} while (type?.GetTypeInfo()?.BaseType != null);
190206
#else
191207
type = type.BaseType;
192208
} while (type?.BaseType != null);
193209
#endif
210+
return propertiesByName.Values;
211+
}
194212

213+
/// <summary>
214+
/// Determines if a property is overriding an inherited property of its base class
215+
/// </summary>
216+
private static bool IsHidingMember(PropertyInfo propertyInfo)
217+
{
218+
#if DOTNETCORE
219+
var baseType = propertyInfo.DeclaringType?.GetTypeInfo()?.BaseType;
220+
#else
221+
var baseType = propertyInfo.DeclaringType?.BaseType;
222+
#endif
223+
var baseProperty = baseType?.GetProperty(propertyInfo.Name);
224+
if (baseProperty == null) return false;
225+
var derivedGetMethod = propertyInfo.GetGetMethod().GetBaseDefinition();
226+
return derivedGetMethod?.ReturnType != propertyInfo.PropertyType;
195227
}
196228
}
197229
}
230+

src/Tests/ClientConcepts/HighLevel/Mapping/AutoMap.doc.cs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,49 @@ public void OverridingAutoMappedAttributes()
682682
Expect(expected).WhenSerializing((ICreateIndexRequest)descriptor);
683683
}
684684

685+
public class ParentWithStringId : Parent
686+
{
687+
public new string Id { get; set; }
688+
}
689+
690+
[U]
691+
public void OverridingInheritedProperties()
692+
{
693+
var descriptor = new CreateIndexDescriptor("myindex")
694+
.Mappings(ms => ms
695+
.Map<ParentWithStringId>(m => m
696+
.AutoMap()
697+
)
698+
);
699+
700+
var expected = new
701+
{
702+
mappings = new
703+
{
704+
parent = new
705+
{
706+
properties = new
707+
{
708+
id = new
709+
{
710+
type = "string",
711+
}
712+
}
713+
}
714+
}
715+
};
716+
717+
var settings = WithConnectionSettings(s => s
718+
.InferMappingFor<ParentWithStringId>(m => m
719+
.TypeName("parent")
720+
.Ignore(p => p.Description)
721+
.Ignore(p => p.IgnoreMe)
722+
)
723+
);
724+
725+
settings.Expect(expected).WhenSerializing((ICreateIndexRequest) descriptor);
726+
}
727+
685728
/**[float]
686729
* == Ignoring Properties
687730
* Properties on a POCO can be ignored in a few ways:

0 commit comments

Comments
 (0)