Skip to content

Commit a14b54e

Browse files
authored
chore: Merge pull request #887 from DocSvartz/restore-v7.4.0-behavior-for-Property-without-setter
Fix: Restore v7.4.0 behavior for property without setter in class
2 parents b4feddb + 58bed37 commit a14b54e

3 files changed

Lines changed: 33 additions & 5 deletions

File tree

src/Mapster.Tests/WhenUsingDestinationValue.cs

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,16 +42,35 @@ public void MapUsingDestinationValue()
4242
public void MappingToReadonlyPropertyWhenPocoDetectRegression()
4343
{
4444
var studentDto = new StudentDtoOrigin { Name = "Marta" };
45-
var student = studentDto.Adapt<StudentOrigin>(); // No exception.
4645

47-
student.Name.ShouldBe("John");
46+
Should.NotThrow(() =>
47+
{
48+
var student = studentDto.Adapt<StudentOrigin>(); // No exception.
49+
});
4850
}
4951

52+
[TestMethod]
53+
public void MappingToReadonlyAutoPropertyPrimitiveOrImmutableType()
54+
{
55+
var studentDto = new StudentDtoOrigin { Name = "Marta" };
56+
var UseDestinationValue = studentDto.Adapt<StudentOrigin>();
57+
var NotUseDestinationValue = studentDto.Adapt<StudentOriginNoUseDestinationValue>();
58+
59+
UseDestinationValue.Name.ShouldBe(studentDto.Name);
60+
NotUseDestinationValue.Name.ShouldBe("John"); // not modified Name == "John" - origin value
61+
}
62+
63+
#region TestClasses
64+
65+
public class StudentOriginNoUseDestinationValue
66+
{
67+
public string Name { get; } = "John"; // readonly primitive type autoproperty
68+
}
5069

5170
public class StudentOrigin
5271
{
5372
[UseDestinationValue]
54-
public string Name { get; } = "John"; // only readonly
73+
public string Name { get; } = "John"; // readonly primitive type autoproperty
5574
}
5675

5776
public class StudentDtoOrigin
@@ -93,5 +112,7 @@ public class InvoiceDto
93112
public IEnumerable<int> Numbers { get; set; }
94113
public ICollection<string> Strings { get; set; }
95114
}
115+
116+
#endregion TestClasses
96117
}
97118
}

src/Mapster/Adapters/ClassAdapter.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,11 @@ protected override Expression CreateBlockExpression(Expression source, Expressio
115115

116116
var adapt = CreateAdaptExpression(member.Getter, member.DestinationMember.Type, arg, member, destMember);
117117

118-
if (!member.UseDestinationValue && member.DestinationMember.SetterModifier == AccessModifier.None)
118+
if (member.UseDestinationValue
119+
&& member.DestinationMember.Type.IsMapsterImmutable()
120+
&& member.DestinationMember.SetterModifier == AccessModifier.None)
119121
{
120-
if (member.DestinationMember is PropertyModel && arg.MapType == MapType.MapToTarget)
122+
if (member.DestinationMember is PropertyModel && arg.MapType != MapType.Projection)
121123
adapt = SetValueTypeAutoPropertyByReflection(member, adapt, classModel);
122124
else
123125
continue;

src/Mapster/Utils/ReflectionUtils.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,5 +448,10 @@ public static bool isDefaultCtor(this Type type)
448448
{
449449
return type.GetConstructor(new Type[] { }) is not null ? true : false;
450450
}
451+
452+
public static bool IsMapsterImmutable(this Type type)
453+
{
454+
return type.IsMapsterPrimitive() || type.IsRecordType();
455+
}
451456
}
452457
}

0 commit comments

Comments
 (0)