From b0a464874a3ee5b91d4412636c70bbda7dedca7a Mon Sep 17 00:00:00 2001 From: JMPSequeira Date: Fri, 24 Jun 2022 12:23:22 +0100 Subject: [PATCH] fixes #385 --- ...enMappingToConstructorAndPrivateSetters.cs | 71 +++++++++++++++++++ src/Mapster/Adapters/ClassAdapter.cs | 7 +- 2 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 src/Mapster.Tests/WhenMappingToConstructorAndPrivateSetters.cs diff --git a/src/Mapster.Tests/WhenMappingToConstructorAndPrivateSetters.cs b/src/Mapster.Tests/WhenMappingToConstructorAndPrivateSetters.cs new file mode 100644 index 00000000..518e4b19 --- /dev/null +++ b/src/Mapster.Tests/WhenMappingToConstructorAndPrivateSetters.cs @@ -0,0 +1,71 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Shouldly; + +namespace Mapster.Tests +{ + [TestClass] + public class WhenMappingToConstructorAndPrivateSetters + { + [TestInitialize] + public void Setup() + { + TypeAdapterConfig.GlobalSettings.Clear(); + } + + [TestMethod] + public void MapToConstructor_Auto() + { + TypeAdapterConfig.NewConfig() + .MapToConstructor(true); + + var poco = new Poco { Id = "A", Name = "Test", Prop = "Prop" }; + var dto = poco.Adapt(); + + dto.Id.ShouldBe(poco.Id + "Suffix"); + dto.Name.ShouldBe(poco.Name + "Suffix"); + dto.Age.ShouldBe(-1); + dto.Prop.ShouldBe(poco.Prop); + dto.OtherProp.ShouldBeNull(); + } + + [TestMethod] + public void MapToConstructor_Auto_ReusingSourceProperty() + { + TypeAdapterConfig.NewConfig() + .MapToConstructor(true) + .Map((d)=> d.OtherProp, (s) => s.Id); + + var poco = new Poco { Id = "A", Name = "Test", Prop = "Prop" }; + var dto = poco.Adapt(); + + dto.Id.ShouldBe(poco.Id + "Suffix"); + dto.Name.ShouldBe(poco.Name + "Suffix"); + dto.Age.ShouldBe(-1); + dto.Prop.ShouldBe(poco.Prop); + dto.OtherProp.ShouldBe(poco.Id); + } + + public class Poco + { + public string Id { get; set; } + public string Name { get; set; } + public string Prop { get; set; } + } + + public class Dto + { + public string Id { get; private set; } + public string Name { get; private set; } + public int Age { get; private set; } + public string Prop { get; private set; } + public string OtherProp { get; private set; } + + public Dto(string id, string name, int age = -1) + { + this.Id = id + "Suffix"; + this.Name = name + "Suffix"; + this.Age = age; + } + } + } +} diff --git a/src/Mapster/Adapters/ClassAdapter.cs b/src/Mapster/Adapters/ClassAdapter.cs index 6ff668ab..d1c1febe 100644 --- a/src/Mapster/Adapters/ClassAdapter.cs +++ b/src/Mapster/Adapters/ClassAdapter.cs @@ -176,7 +176,7 @@ protected override Expression CreateBlockExpression(Expression source, Expressio var exp = CreateInstantiationExpression(source, arg); var memberInit = exp as MemberInitExpression; var newInstance = memberInit?.NewExpression ?? (NewExpression)exp; - + var contructorMembers = newInstance.Arguments.OfType().Select(me => me.Member).ToArray(); var classModel = GetSetterModel(arg); var classConverter = CreateClassConverter(source, classModel, arg); var members = classConverter.Members; @@ -188,6 +188,11 @@ protected override Expression CreateBlockExpression(Expression source, Expressio { if (member.UseDestinationValue) return null; + + if (!arg.Settings.Resolvers.Any(r => r.DestinationMemberName == member.DestinationMember.Name) + && member.Getter is MemberExpression memberExp && contructorMembers.Contains(memberExp.Member)) + continue; + if (member.DestinationMember.SetterModifier == AccessModifier.None) continue;