Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 24 additions & 3 deletions src/Mapster.Tests/WhenUsingDestinationValue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,35 @@ public void MapUsingDestinationValue()
public void MappingToReadonlyPropertyWhenPocoDetectRegression()
{
var studentDto = new StudentDtoOrigin { Name = "Marta" };
var student = studentDto.Adapt<StudentOrigin>(); // No exception.

student.Name.ShouldBe("John");
Should.NotThrow(() =>
{
var student = studentDto.Adapt<StudentOrigin>(); // No exception.
});
}

[TestMethod]
public void MappingToReadonlyAutoPropertyPrimitiveOrImmutableType()
{
var studentDto = new StudentDtoOrigin { Name = "Marta" };
var UseDestinationValue = studentDto.Adapt<StudentOrigin>();
var NotUseDestinationValue = studentDto.Adapt<StudentOriginNoUseDestinationValue>();

UseDestinationValue.Name.ShouldBe(studentDto.Name);
NotUseDestinationValue.Name.ShouldBe("John"); // not modified Name == "John" - origin value
}

#region TestClasses

public class StudentOriginNoUseDestinationValue
{
public string Name { get; } = "John"; // readonly primitive type autoproperty
}

public class StudentOrigin
{
[UseDestinationValue]
public string Name { get; } = "John"; // only readonly
public string Name { get; } = "John"; // readonly primitive type autoproperty
}

public class StudentDtoOrigin
Expand Down Expand Up @@ -93,5 +112,7 @@ public class InvoiceDto
public IEnumerable<int> Numbers { get; set; }
public ICollection<string> Strings { get; set; }
}

#endregion TestClasses
}
}
6 changes: 4 additions & 2 deletions src/Mapster/Adapters/ClassAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,11 @@ protected override Expression CreateBlockExpression(Expression source, Expressio

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

if (!member.UseDestinationValue && member.DestinationMember.SetterModifier == AccessModifier.None)
if (member.UseDestinationValue
&& member.DestinationMember.Type.IsMapsterImmutable()
&& member.DestinationMember.SetterModifier == AccessModifier.None)
{
if (member.DestinationMember is PropertyModel && arg.MapType == MapType.MapToTarget)
if (member.DestinationMember is PropertyModel && arg.MapType != MapType.Projection)
adapt = SetValueTypeAutoPropertyByReflection(member, adapt, classModel);
else
continue;
Expand Down
5 changes: 5 additions & 0 deletions src/Mapster/Utils/ReflectionUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -448,5 +448,10 @@ public static bool isDefaultCtor(this Type type)
{
return type.GetConstructor(new Type[] { }) is not null ? true : false;
}

public static bool IsMapsterImmutable(this Type type)
{
return type.IsMapsterPrimitive() || type.IsRecordType();
}
}
}
Loading