diff --git a/src/Mapster.Tests/WhenMappingGetterOnlyMapToTargetRegression.cs b/src/Mapster.Tests/WhenMappingGetterOnlyMapToTargetRegression.cs new file mode 100644 index 00000000..2eb45c71 --- /dev/null +++ b/src/Mapster.Tests/WhenMappingGetterOnlyMapToTargetRegression.cs @@ -0,0 +1,75 @@ +using MapsterMapper; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Shouldly; + +namespace Mapster.Tests; + +/// +/// https://github.com/MapsterMapper/Mapster/issues/900 +/// +[TestClass] +public class WhenMappingGetterOnlyMapToTargetRegression +{ + [TestMethod] + public void MapToTarget_WithCustomMap_ShouldReplaceExistingDestinationMemberValue() + { + var config = new TypeAdapterConfig(); + config.NewConfig() + .Map(x => x.Data, x => x.Data == null ? null : new Data900(x.Data.Value)); + + var mapper = new Mapper(config); + + var dto = new Dto900 { Data = new Data900("new") }; + var entity = mapper.Map(dto, new Entity900 { Data = new Data900("old") }); + + entity.Data.ShouldNotBeNull(); + entity.Data!.Value.ShouldBe("new"); + } + + [TestMethod] + public void MapToTarget_WithCustomMap_ShouldStillWorkWhenDestinationMemberIsNull() + { + var config = new TypeAdapterConfig(); + config.NewConfig() + .Map(x => x.Data, x => x.Data == null ? null : new Data900(x.Data.Value)); + + var mapper = new Mapper(config); + + var dto = new Dto900 { Data = new Data900("new") }; + var entity = mapper.Map(dto, new Entity900()); + + entity.Data.ShouldNotBeNull(); + entity.Data!.Value.ShouldBe("new"); + } + + [TestMethod] + public void Map_WithCustomMap_ShouldStillWorkForNewDestination() + { + var config = new TypeAdapterConfig(); + config.NewConfig() + .Map(x => x.Data, x => x.Data == null ? null : new Data900(x.Data.Value)); + + var mapper = new Mapper(config); + + var dto = new Dto900 { Data = new Data900("new") }; + var entity = mapper.Map(dto); + + entity.Data.ShouldNotBeNull(); + entity.Data!.Value.ShouldBe("new"); + } + + private class Dto900 + { + public Data900? Data { get; set; } + } + + private class Entity900 + { + public Data900? Data { get; set; } + } + + private class Data900(string value) + { + public string Value => value; + } +} diff --git a/src/Mapster/Adapters/BaseClassAdapter.cs b/src/Mapster/Adapters/BaseClassAdapter.cs index 6d12a934..79855713 100644 --- a/src/Mapster/Adapters/BaseClassAdapter.cs +++ b/src/Mapster/Adapters/BaseClassAdapter.cs @@ -200,6 +200,13 @@ protected static bool IsCanUsingDestinationValue(CompileArgument arg, IMemberMod return false; } + protected static bool HasCustomMemberMap(CompileArgument arg, IMemberModel destinationMember) + { + return arg.Settings.Resolvers.Any(resolver => + !resolver.IsChildPath && + string.Equals(resolver.DestinationMemberName, destinationMember.Name, StringComparison.InvariantCultureIgnoreCase)); + } + protected static bool ProcessIgnores( CompileArgument arg, IMemberModel destinationMember, diff --git a/src/Mapster/Adapters/ClassAdapter.cs b/src/Mapster/Adapters/ClassAdapter.cs index 27d09d9b..8a8c59e5 100644 --- a/src/Mapster/Adapters/ClassAdapter.cs +++ b/src/Mapster/Adapters/ClassAdapter.cs @@ -110,7 +110,8 @@ protected override Expression CreateBlockExpression(Expression source, Expressio Dictionary, Expression>>? conditions = null; foreach (var member in members) { - var destMember = arg.MapType == MapType.MapToTarget || member.UseDestinationValue + var hasCustomMap = HasCustomMemberMap(arg, member.DestinationMember); + var destMember = (arg.MapType == MapType.MapToTarget || member.UseDestinationValue) && !hasCustomMap ? member.DestinationMember.GetExpression(destination) : null;