Skip to content

Commit d1f9552

Browse files
author
OFFICE\yanisimov
committed
bug fixing
1 parent 92c9292 commit d1f9552

8 files changed

Lines changed: 298 additions & 71 deletions

File tree

ExpressMapper NET40/Properties/AssemblyInfo.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,6 @@
3333
// You can specify all the values or you can default the Build and Revision Numbers
3434
// by using the '*' as shown below:
3535
// [assembly: AssemblyVersion("1.0.*")]
36-
[assembly: AssemblyVersion("1.9.0.0")]
37-
[assembly: AssemblyFileVersion("1.9.0.0")]
38-
[assembly: AssemblyInformationalVersion("1.9.0")]
36+
[assembly: AssemblyVersion("1.9.1.0")]
37+
[assembly: AssemblyFileVersion("1.9.1.0")]
38+
[assembly: AssemblyInformationalVersion("1.9.1")]

ExpressMapper NETCORE/Properties/AssemblyInfo.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,6 @@
2020
// The following GUID is for the ID of the typelib if this project is exposed to COM
2121
[assembly: Guid("969e6614-0489-4174-a735-cc66f51d8746")]
2222

23-
[assembly: AssemblyVersion("1.9.0.0")]
24-
[assembly: AssemblyFileVersion("1.9.0.0")]
25-
[assembly: AssemblyInformationalVersion("1.9.0")]
23+
[assembly: AssemblyVersion("1.9.1.0")]
24+
[assembly: AssemblyFileVersion("1.9.1.0")]
25+
[assembly: AssemblyInformationalVersion("1.9.1")]

ExpressMapper NETCORE/TypeMapperBase.cs

Lines changed: 47 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ public void Compile(CompilationTypes compilationType, bool forceByDemand = false
121121
catch (Exception ex)
122122
{
123123
throw new ExpressmapperException(
124-
$"Error error occured trying to compile mapping for: source {typeof (T).FullName}, destination {typeof (TN).FullName}. See the inner exception for details.",
124+
$"Error error occured trying to compile mapping for: source {typeof(T).FullName}, destination {typeof(TN).FullName}. See the inner exception for details.",
125125
ex);
126126
}
127127
}
@@ -179,18 +179,18 @@ public Func<object, object, object> GetNonGenericMapFunc()
179179
var dstAssigned = Expression.Assign(dstTypedExp, dstConverted);
180180

181181
var customGenericType = typeof(ITypeMapper<,>).MakeGenericType(typeof(T), typeof(TN));
182-
var castToCustomGeneric = Expression.Convert(Expression.Constant((ITypeMapper) this), customGenericType);
182+
var castToCustomGeneric = Expression.Convert(Expression.Constant((ITypeMapper)this), customGenericType);
183183
var genVariable = Expression.Variable(customGenericType);
184184
var assignExp = Expression.Assign(genVariable, castToCustomGeneric);
185-
var methodInfo = customGenericType.GetInfo().GetMethod("MapTo", new[] {typeof(T), typeof(TN)});
185+
var methodInfo = customGenericType.GetInfo().GetMethod("MapTo", new[] { typeof(T), typeof(TN) });
186186

187187
var mapCall = Expression.Call(genVariable, methodInfo, srcTypedExp, dstTypedExp);
188188
var resultVarExp = Expression.Variable(typeof(object), "result");
189189
var convertToObj = Expression.Convert(mapCall, typeof(object));
190190
var assignResult = Expression.Assign(resultVarExp, convertToObj);
191191

192-
var blockExpression = Expression.Block(new[] {srcTypedExp, dstTypedExp, genVariable, resultVarExp},
193-
new Expression[] {srcAssigned, dstAssigned, assignExp, assignResult, resultVarExp});
192+
var blockExpression = Expression.Block(new[] { srcTypedExp, dstTypedExp, genVariable, resultVarExp },
193+
new Expression[] { srcAssigned, dstAssigned, assignExp, assignResult, resultVarExp });
194194
var lambda =
195195
Expression.Lambda<Func<object, object, object>>(blockExpression, parameterExpression, destParameterExp);
196196
NonGenericMapFunc = lambda.Compile();
@@ -200,8 +200,8 @@ public Func<object, object, object> GetNonGenericMapFunc()
200200

201201
protected void AutoMapProperty(MemberInfo propertyGet, MemberInfo propertySet)
202202
{
203-
var callSetPropMethod = Expression.PropertyOrField(DestFakeParameter, propertySet.Name);
204-
var callGetPropMethod = Expression.PropertyOrField(SourceParameter, propertyGet.Name);
203+
var callSetPropMethod = propertySet.MemberType == MemberTypes.Field ? Expression.Field(DestFakeParameter, propertySet as FieldInfo) : Expression.Property(DestFakeParameter, propertySet as PropertyInfo);
204+
var callGetPropMethod = propertyGet.MemberType == MemberTypes.Field ? Expression.Field(SourceParameter, propertyGet as FieldInfo) : Expression.Property(SourceParameter, propertyGet as PropertyInfo);
205205

206206
MapMember(callSetPropMethod, callGetPropMethod);
207207
}
@@ -282,6 +282,7 @@ protected void ProcessAutoProperties()
282282
var getProps =
283283
typeof(T).GetInfo()
284284
.GetProperties(BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.Public);
285+
285286
var setProps =
286287
typeof(TN).GetInfo()
287288
.GetProperties(BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.Public);
@@ -293,7 +294,7 @@ protected void ProcessAutoProperties()
293294

294295
var comparer = CultureInfo.CurrentCulture.CompareInfo.GetStringComparer(CompareOptions.OrdinalIgnoreCase);
295296
//var comparer = StringComparer.Create(CultureInfo.CurrentCulture,
296-
// stringComparison == StringComparison.OrdinalIgnoreCase);
297+
// stringComparison == StringComparison.OrdinalIgnoreCase);
297298

298299
foreach (var prop in sourceMembers)
299300
{
@@ -302,18 +303,48 @@ protected void ProcessAutoProperties()
302303
{
303304
continue;
304305
}
305-
var setprop = destMembers.FirstOrDefault(x => string.Equals(x.Name, prop.Name, stringComparison));
306+
307+
var notUniqueDestMembers = destMembers.Where(x => string.Equals(x.Name, prop.Name, stringComparison));
308+
var notUniqueSrcMembers = sourceMembers.Where(x => string.Equals(x.Name, prop.Name, stringComparison));
309+
310+
var getprop = GetTopMostMemberOfHierarchy(notUniqueSrcMembers);
311+
if (AutoMembers.ContainsKey(getprop))
312+
{
313+
continue;
314+
}
315+
316+
var setprop = GetTopMostMemberOfHierarchy(notUniqueDestMembers);
306317

307318
var propertyInfo = setprop as PropertyInfo;
308319
if ((propertyInfo == null && setprop == null) ||
309320
(propertyInfo != null && (!propertyInfo.CanWrite || !propertyInfo.GetSetMethod(true).IsPublic)))
310321
{
311-
IgnoreMemberList.Add(prop.Name);
322+
IgnoreMemberList.Add(getprop.Name);
312323
continue;
313324
}
314-
AutoMembers[prop] = setprop;
315-
AutoMapProperty(prop, setprop);
325+
AutoMembers[getprop] = setprop;
326+
AutoMapProperty(getprop, setprop);
327+
}
328+
}
329+
330+
private static MemberInfo GetTopMostMemberOfHierarchy(IEnumerable<MemberInfo> notUniqueMembers)
331+
{
332+
MemberInfo chosen = null;
333+
334+
foreach (var notUniqueMember in notUniqueMembers)
335+
{
336+
if (chosen == null)
337+
{
338+
chosen = notUniqueMember;
339+
}
340+
else
341+
{
342+
chosen = chosen.DeclaringType.GetInfo().IsAssignableFrom(notUniqueMember.DeclaringType)
343+
? notUniqueMember
344+
: chosen;
345+
}
316346
}
347+
return chosen;
317348
}
318349

319350
internal StringComparison GetStringCase()
@@ -474,8 +505,10 @@ public void ImportMemberConfigParameters(IMemberConfigParameters baseClassConfig
474505

475506
// todo : implement visitor to replace base type to the subclass' type
476507
CustomFunctionMembers =
477-
new List<KeyValuePair<MemberExpression, Expression>>(baseClassConfiguration.CustomFunctionMembers.Count);
478-
CustomMembers = new List<KeyValuePair<MemberExpression, Expression>>(baseClassConfiguration.CustomMembers.Count);
508+
new List<KeyValuePair<MemberExpression, Expression>>(baseClassConfiguration.CustomFunctionMembers
509+
.Count);
510+
CustomMembers =
511+
new List<KeyValuePair<MemberExpression, Expression>>(baseClassConfiguration.CustomMembers.Count);
479512
FlattenMembers =
480513
new List<KeyValuePair<MemberExpression, Expression>>(baseClassConfiguration.FlattenMembers.Count);
481514

ExpressMapper NETCORE/project.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"version": "1.0.0-*",
2+
"version": "1.9.1.0",
33
"buildOptions": {
44
"outputName": "ExpressMapper",
55
"xmlDoc": true

ExpressMapper.Tests NET40/BasicTests.cs

Lines changed: 90 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public void EnumToAnotherEnumMapTest()
3131
};
3232

3333
var unitOfWorkViewModel = unitOfWork.Map<UnitOfWork, UnitOfWorkViewModel>();
34-
Assert.AreEqual((int)unitOfWork.State, (int)unitOfWorkViewModel.State);
34+
Assert.AreEqual((int) unitOfWork.State, (int) unitOfWorkViewModel.State);
3535
Assert.AreEqual(unitOfWork.Id, unitOfWorkViewModel.Id);
3636
}
3737

@@ -60,7 +60,7 @@ public void DefaultPrimitiveTypePropertyToStringTest()
6060
.Member(dest => dest.TestString, src => src.TestDecimal);
6161
Mapper.RegisterCustom<decimal, string>(src => src.ToString("#0.00", CultureInfo.InvariantCulture));
6262
Mapper.Compile();
63-
var test = new TestDefaultDecimal() { TestDecimal = default(decimal) };
63+
var test = new TestDefaultDecimal() {TestDecimal = default(decimal)};
6464
test.TestDecimal = default(decimal);
6565
var result = Mapper.Map<TestDefaultDecimal, TestDefaultDecimalToStringViewModel>(test);
6666
//This is where the mapping fails
@@ -74,9 +74,9 @@ public void MemberMappingsHasHigherPriorityThanCaseSensetiveTest()
7474
.Member(t => t.Enabled, s => s.enabled == "Y");
7575
Mapper.Compile();
7676

77-
var source = new Source { enabled = "N" };
78-
var result = Mapper.Map<Source, TargetViewModel>(source);
79-
Assert.AreEqual(result.Enabled, false);
77+
var source = new Source {enabled = "N"};
78+
var result = Mapper.Map<Source, TargetViewModel>(source);
79+
Assert.AreEqual(result.Enabled, false);
8080
}
8181

8282
[Test]
@@ -293,7 +293,7 @@ public void HiddenInheritedMemberMap()
293293
Assert.AreEqual(result, srcDst.Value);
294294
}
295295

296-
private void MapBaseMember<T, TN>(IMemberConfiguration<T,TN> mapConfig)
296+
private void MapBaseMember<T, TN>(IMemberConfiguration<T, TN> mapConfig)
297297
where T : Gift
298298
where TN : GiftViewModel
299299
{
@@ -421,7 +421,8 @@ public void BeforeMapDuplicateTest()
421421
.Before((src, dest) => dest.Name = src.Name)
422422
.Before((src, dest) => dest.Name = src.Name)
423423
.Ignore(dest => dest.Name));
424-
Assert.That(exception.Message, Is.EqualTo("BeforeMap already registered for ExpressMapper.Tests.Model.Models.Size"));
424+
Assert.That(exception.Message,
425+
Is.EqualTo("BeforeMap already registered for ExpressMapper.Tests.Model.Models.Size"));
425426

426427
var sizeResult = Functional.BeforeMap();
427428
var result = Mapper.Map<Size, SizeViewModel>(sizeResult.Key);
@@ -445,7 +446,8 @@ public void AfterMapDuplicateTest()
445446
var exception = Assert.Throws<InvalidOperationException>(() => Mapper.Register<Size, SizeViewModel>()
446447
.After((src, dest) => dest.Name = "OVERRIDE BY AFTER MAP")
447448
.After((src, dest) => dest.Name = "Duplicate map"));
448-
Assert.That(exception.Message, Is.EqualTo("AfterMap already registered for ExpressMapper.Tests.Model.Models.Size"));
449+
Assert.That(exception.Message,
450+
Is.EqualTo("AfterMap already registered for ExpressMapper.Tests.Model.Models.Size"));
449451
var sizeResult = Functional.AfterMap();
450452
var result = Mapper.Map<Size, SizeViewModel>(sizeResult.Key);
451453
Assert.AreEqual(result, sizeResult.Value);
@@ -754,7 +756,8 @@ public void NonGenericSimpleWithDestinationMap()
754756
var test = Functional.AutoMemberMap();
755757

756758
var resultInstanceHash = test.Value.GetHashCode();
757-
var testViewModel = Mapper.Map(test.Key, test.Value, typeof(TestModel), typeof(TestViewModel)) as TestViewModel;
759+
var testViewModel =
760+
Mapper.Map(test.Key, test.Value, typeof(TestModel), typeof(TestViewModel)) as TestViewModel;
758761

759762
Assert.AreEqual(testViewModel.GetHashCode(), resultInstanceHash);
760763
Assert.AreEqual(testViewModel, test.Value);
@@ -873,7 +876,7 @@ public void ExistingDestCollEqualsWithNullElement()
873876
var testItemHash = testResult.Item2.GetHashCode();
874877
var arrayHash = testResult.Item2.Array.GetHashCode();
875878
var testArr = new List<int?>(testResult.Item2.Array.Length);
876-
testArr.AddRange(testResult.Item2.Array.Select(tc => tc == null ? (int?)null : tc.GetHashCode()));
879+
testArr.AddRange(testResult.Item2.Array.Select(tc => tc == null ? (int?) null : tc.GetHashCode()));
877880

878881
var result = Mapper.Map(testResult.Item1, testResult.Item2);
879882
Assert.AreEqual(result, testResult.Item2);
@@ -950,7 +953,7 @@ public void ExistingSrcCollGreater()
950953
Assert.AreEqual(result.Collection.ElementAt(i), testResult.Item3.Collection.ElementAt(i));
951954
}
952955
}
953-
956+
954957
[Test]
955958
public void ExistingDestDestCollGreater()
956959
{
@@ -1086,15 +1089,20 @@ public void ExistingDestinationComplex()
10861089
for (var i = 0; i < result.SubItems.Length; i++)
10871090
{
10881091
Assert.AreEqual(result.SubItems[i].GetHashCode(), subItemsHashes[i]);
1089-
Assert.AreEqual(result.SubItems[i].Units.GetHashCode(), subItemUnitsCollHashes[result.SubItems[i].GetHashCode()]);
1092+
Assert.AreEqual(result.SubItems[i].Units.GetHashCode(),
1093+
subItemUnitsCollHashes[result.SubItems[i].GetHashCode()]);
10901094

10911095
for (var j = 0; j < 4; j++)
10921096
{
1093-
Assert.AreEqual(result.SubItems[i].Units[j].GetHashCode(), subItemUnitsHashes[result.SubItems[i].GetHashCode()][j]);
1094-
Assert.AreEqual(result.SubItems[i].Units[j].SubUnits.GetHashCode(), subItemUnitSubUnitCollHashes[result.SubItems[i].GetHashCode()][j]);
1097+
Assert.AreEqual(result.SubItems[i].Units[j].GetHashCode(),
1098+
subItemUnitsHashes[result.SubItems[i].GetHashCode()][j]);
1099+
Assert.AreEqual(result.SubItems[i].Units[j].SubUnits.GetHashCode(),
1100+
subItemUnitSubUnitCollHashes[result.SubItems[i].GetHashCode()][j]);
10951101
for (var k = 0; k < 3; k++)
10961102
{
1097-
Assert.AreEqual(result.SubItems[i].Units[j].SubUnits[k].GetHashCode(), subItemUnitSubUnitsHashes[result.SubItems[i].GetHashCode()][result.SubItems[i].Units[j].GetHashCode()][k]);
1103+
Assert.AreEqual(result.SubItems[i].Units[j].SubUnits[k].GetHashCode(),
1104+
subItemUnitSubUnitsHashes[result.SubItems[i].GetHashCode()][
1105+
result.SubItems[i].Units[j].GetHashCode()][k]);
10981106
}
10991107
}
11001108
}
@@ -1144,7 +1152,7 @@ public void EnumMap()
11441152

11451153
Assert.AreEqual(GenderTypes.Men, testViewModel.Gender);
11461154
Assert.AreEqual(GenderTypes.Women.ToString(), testViewModel.NullableGender);
1147-
Assert.AreEqual((int)GenderTypes.Women, testViewModel.GenderIndex);
1155+
Assert.AreEqual((int) GenderTypes.Women, testViewModel.GenderIndex);
11481156
}
11491157

11501158
[Test]
@@ -1203,7 +1211,7 @@ public void MemberCaseSensitivityGlobalMapTest()
12031211
};
12041212

12051213
var typoCaseViewModel = Mapper.Map<TypoCase, TypoCaseViewModel>(typoCase);
1206-
1214+
12071215
Assert.AreEqual(typoCaseViewModel.Id, Guid.Empty);
12081216
Assert.AreEqual(typoCaseViewModel.Name, null);
12091217
Assert.AreEqual(typoCase.TestId, typoCaseViewModel.TestId);
@@ -1416,7 +1424,7 @@ public void NestedInheritanceIncludeTest()
14161424
Assert.AreEqual(uiViewModel.ControlViewModel.Description, textBox.Description);
14171425
Assert.AreEqual(uiViewModel.ControlViewModel.id_ctrl, textBox.Id);
14181426
Assert.AreEqual(uiViewModel.ControlViewModel.name_ctrl, textBox.Name);
1419-
Assert.AreEqual(((TextBoxViewModel)uiViewModel.ControlViewModel).Text, textBox.Text);
1427+
Assert.AreEqual(((TextBoxViewModel) uiViewModel.ControlViewModel).Text, textBox.Text);
14201428
}
14211429

14221430
[Test]
@@ -1426,7 +1434,70 @@ public void MapNullSourceReturnNullDest()
14261434
Mapper.Compile();
14271435

14281436
Assert.IsNull(Mapper.Map<object, object>(null));
1429-
Assert.IsNull(Mapper.Map<object, object>(null, (object)null));
1437+
Assert.IsNull(Mapper.Map<object, object>(null, (object) null));
1438+
}
1439+
1440+
#region Duplicate property names in the class hierarchy
1441+
1442+
[Test]
1443+
public void MapDuplicatePropertyNamesInHierarchyTest()
1444+
{
1445+
Mapper.Register<A, AN>();
1446+
Mapper.Register<AN, A>();
1447+
1448+
Mapper.Register<T, TNT>();
1449+
Mapper.Register<TNT, T>();
1450+
Mapper.Compile();
1451+
1452+
1453+
var tnt = new TNT
1454+
{
1455+
Foo = new AN
1456+
{
1457+
Id = 4
1458+
}
1459+
};
1460+
1461+
var t = new T
1462+
{
1463+
Foo = new A
1464+
{
1465+
Id = 5
1466+
}
1467+
};
1468+
1469+
var tntResult = t.Map<T, TNT>();
1470+
var tResult = tnt.Map<TNT, T>();
1471+
1472+
Assert.AreEqual(tntResult.Foo.Id, 5);
1473+
Assert.AreEqual(tResult.Foo.Id, 4);
1474+
}
1475+
1476+
class A
1477+
{
1478+
public int Id { get; set; }
14301479
}
1480+
1481+
class AN : A
1482+
{
1483+
public new int Id { get; set; }
1484+
}
1485+
1486+
class T
1487+
{
1488+
public A Foo { get; set; }
1489+
}
1490+
1491+
class TN : T
1492+
{
1493+
public new AN Foo { get; set; }
1494+
}
1495+
1496+
class TNT : TN
1497+
{
1498+
public new AN Foo { get; set; }
1499+
}
1500+
1501+
#endregion
14311502
}
14321503
}

0 commit comments

Comments
 (0)