Closed mateubo closed 7 years ago
Hi Yuriy, Please consider the following scenario (v1.9.0 used):
class A { } class AN : A { } class T { public A Foo { get; set; } } class TN : T { public new AN Foo { get; set; } }
It fails with "Ambiguous match found" exception when trying to compile these registrations
Mapper.Register<T, TN>(); Mapper.Register<TN, T>(); Mapper.Compile();
The issue is caused by the usage of Expression.PropertyOrField(...)that throws this exception.
Expression.PropertyOrField(...)
Making these modifications could help:
TypeMapperBase.AutoMapProperty:
TypeMapperBase.AutoMapProperty
var callSetPropMethod = propertySet is PropertyInfo ? Expression.Property(DestFakeParameter, (PropertyInfo)propertySet) : propertyGet is FieldInfo ? Expression.Field(DestFakeParameter, (FieldInfo)propertySet) : Expression.PropertyOrField(DestFakeParameter, propertySet.Name); var callGetPropMethod = propertyGet is PropertyInfo ? Expression.Property(SourceParameter, (PropertyInfo)propertyGet) : propertyGet is FieldInfo ? Expression.Field(SourceParameter, (FieldInfo)propertyGet) : Expression.PropertyOrField(SourceParameter, propertyGet.Name);
TypeMapperBase.ProcessAutoProperties:
TypeMapperBase.ProcessAutoProperties
foreach (var prop in sourceMembers.GroupBy(x => x.Name).Select(y => y.FirstOrDefault(z => z.DeclaringType == typeof(T)) ?? y.First())) { if (IgnoreMemberList.Contains(prop.Name, comparer) || CustomPropertyCache.Keys.Contains(prop.Name, comparer)) { continue; } var setpropCandidates = destMembers.Where(x => string.Equals(x.Name, prop.Name, stringComparison)); var setprop = setpropCandidates.FirstOrDefault(x => x.DeclaringType == typeof(TN)) ?? setpropCandidates.FirstOrDefault();
SourceTypeMapper.CreateQueryableProjection
var destination = autoMember.Value as PropertyInfo; var fieldsdWithMatchingName = SourceParameter.Type.GetFields().Where(x => x.Name == autoMember.Key.Name); var propertiesWithMatchingName = SourceParameter.Type.GetProperties().Where(x => x.Name == autoMember.Key.Name); var fieldInfoFromDeclaringType = fieldsdWithMatchingName.FirstOrDefault(x => x.DeclaringType == SourceParameter.Type); var propertyInfoFromDeclaringType = propertiesWithMatchingName.FirstOrDefault(x => x.DeclaringType == SourceParameter.Type); var propertyOrField = propertyInfoFromDeclaringType != null ? Expression.Property(SourceParameter, propertyInfoFromDeclaringType) : propertiesWithMatchingName.Any() ? Expression.Property(SourceParameter, propertiesWithMatchingName.First()) : fieldInfoFromDeclaringType != null ? Expression.Field(SourceParameter, fieldInfoFromDeclaringType) : fieldsdWithMatchingName.Any() ? Expression.Field(SourceParameter, fieldsdWithMatchingName.First()) : Expression.PropertyOrField(SourceParameter, autoMember.Key.Name); ProcessProjectingMember(propertyOrField, destination);
Thanks!
Hi @mateubo ,
Thanks and really appreciate your contribution! Let me do a hot-fix!
Fixed and will be included in 1.9.1 release!
Hi Yuriy, Please consider the following scenario (v1.9.0 used):
It fails with "Ambiguous match found" exception when trying to compile these registrations
The issue is caused by the usage of
Expression.PropertyOrField(...)
that throws this exception.Making these modifications could help:
TypeMapperBase.AutoMapProperty
:TypeMapperBase.ProcessAutoProperties
:SourceTypeMapper.CreateQueryableProjection
Thanks!