diff --git a/src/Mapster.Tests/WhenMappingToInterface.cs b/src/Mapster.Tests/WhenMappingToInterface.cs index 5e6f0358..c1261003 100644 --- a/src/Mapster.Tests/WhenMappingToInterface.cs +++ b/src/Mapster.Tests/WhenMappingToInterface.cs @@ -9,6 +9,8 @@ namespace Mapster.Tests [TestClass] public class WhenMappingToInterface { + + #region Tests [TestInitialize] public void Setup() { @@ -266,6 +268,52 @@ public void MappingToInteraceWithReadonlyProps_AllPropsInitialized() ); } + /// + /// https://github.com/MapsterMapper/Mapster/issues/723 + /// + [TestMethod] + public void MappingToInteraceWithIgnorePrivateSetProperty() + { + TypeAdapterConfig + .NewConfig() + .TwoWays() + .Ignore(dest => dest.Ignore); + + InterfaceSource723 dataSourse = new Data723() { Inter = "IterDataSourse", Ignore = "IgnoreDataSourse" }; + InterfaceDestination723 dataDestination = new Data723() { Inter = "IterDataDestination", Ignore = "IgnoreDataDestination" }; + + var idestination = dataDestination.Adapt(); + var isourse = dataDestination.Adapt(); + + var result = dataSourse.Adapt(dataDestination); + + idestination.Ignore.ShouldBeNull(); // Not create initializer and param in constructor + idestination.Inter.ShouldBe("IterDataDestination"); + + result.Ignore.ShouldBe("IgnoreDataDestination"); + result.Inter.ShouldBe("IterDataSourse"); + } + + #endregion Tests + + #region TestClasses + public interface InterfaceDestination723 : InterfaceSource723 + { + public string Ignore { get; } + } + + public interface InterfaceSource723 + { + public string Inter { get; set; } + } + + private class Data723 : InterfaceDestination723 + { + public string Ignore { get; set; } + + public string Inter { get; set; } + } + public interface IInheritedDtoWithoutProperties : IInheritedDto { } @@ -374,6 +422,6 @@ public class PropertyInitializationTestSource public int Property1 { get; set; } public int Property2 { get; set; } } - + #endregion TestClasses } } diff --git a/src/Mapster/Adapters/ReadOnlyInterfaceAdapter.cs b/src/Mapster/Adapters/ReadOnlyInterfaceAdapter.cs index df4a0f66..160767ca 100644 --- a/src/Mapster/Adapters/ReadOnlyInterfaceAdapter.cs +++ b/src/Mapster/Adapters/ReadOnlyInterfaceAdapter.cs @@ -33,7 +33,7 @@ protected override Expression CreateInstantiationExpression(Expression source, E if (arg.GetConstructUsing() != null) return base.CreateInstantiationExpression(source, destination, arg); - var destType = DynamicTypeGenerator.GetTypeForInterface(arg.DestinationType, arg.Settings.Includes.Count > 0); + var destType = DynamicTypeGenerator.GetTypeForInterface(arg.DestinationType, arg.Settings.Includes.Count > 0, arg.Settings.Ignore); if (destType == null) return base.CreateInstantiationExpression(source, destination, arg); var ctor = destType.GetConstructors()[0]; diff --git a/src/Mapster/Utils/DynamicTypeGenerator.cs b/src/Mapster/Utils/DynamicTypeGenerator.cs index 7e901417..82d693bd 100644 --- a/src/Mapster/Utils/DynamicTypeGenerator.cs +++ b/src/Mapster/Utils/DynamicTypeGenerator.cs @@ -22,6 +22,16 @@ internal static class DynamicTypeGenerator private static readonly ConcurrentDictionary _generated = new ConcurrentDictionary(); private static int _generatedCounter; + private static IgnoreDictionary ignoreMembers; + + public static Type? GetTypeForInterface(Type interfaceType, bool ignoreError, IgnoreDictionary ignorMembers) + { + ignoreMembers = ignorMembers; + + return GetTypeForInterface(interfaceType, ignoreError); + + } + public static Type? GetTypeForInterface(Type interfaceType, bool ignoreError) { try @@ -86,13 +96,14 @@ private static Type CreateTypeForInterface(Type interfaceType) if (hasReadonlyProps) { + var filterargs = DropIgnorMemebers(args); var ctorBuilder = builder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, - args.Select(it => it.FieldType).ToArray()); + filterargs.Select(it => it.FieldType).ToArray()); var ctorIl = ctorBuilder.GetILGenerator(); - for (var i = 0; i < args.Count; i++) + for (var i = 0; i < filterargs.Count; i++) { - var arg = args[i]; + var arg = filterargs[i]; ctorBuilder.DefineParameter(i + 1, ParameterAttributes.None, arg.Name.Substring(1)); ctorIl.Emit(OpCodes.Ldarg_0); ctorIl.Emit(OpCodes.Ldarg_S, i + 1); @@ -175,5 +186,27 @@ private static void CreateMethod(TypeBuilder builder, MethodInfo interfaceMethod builder.DefineMethodOverride(classMethod, interfaceMethod); } + + private static List DropIgnorMemebers(List fields) + { + var ignorFields = ignoreMembers.Select(x => x.Key).ToArray(); + List filtered = new List(); + + if (ignorFields.Length == 0) + return fields; + + foreach (var item in fields) + { + foreach (var check in ignorFields) + { + if (item.Name != $"_{MapsterHelper.CamelCase(check)}") + { + filtered.Add(item); + } + } + } + + return filtered; + } } }