diff --git a/src/Mapster.Tests/WhenMappingToInterface.cs b/src/Mapster.Tests/WhenMappingToInterface.cs index 00af210..0f5b5cc 100644 --- a/src/Mapster.Tests/WhenMappingToInterface.cs +++ b/src/Mapster.Tests/WhenMappingToInterface.cs @@ -289,6 +289,46 @@ public void MappingToInterface_VerifyReadonlyPropsInterfaceRule() ); } + /// + /// https://github.com/MapsterMapper/Mapster/issues/723 + /// + [TestMethod] + public void MappingToIntefaceWithIgnorePrivateSetProperty() + { + TypeAdapterConfig + .NewConfig() + .TwoWays() + .Ignore(dest => dest.Ignore); + + InterfaceDestination723 dataDestination = new Data723() { Inter = "IterDataDestination", Ignore = "IgnoreDataDestination" }; + + Should.NotThrow(() => + { + var isourse = dataDestination.Adapt(); + var idestination = dataDestination.Adapt(); + }); + + } + + public interface InterfaceDestination723 + { + public string Inter { get; set; } + public string Ignore { get; } + } + + public interface InterfaceSource723 + { + public string Inter { get; set; } + } + + private class Data723 : InterfaceSource723, InterfaceDestination723 + { + public string Ignore { get; set; } + + public string Inter { get; set; } + } + + public interface IInheritedDtoWithoutProperties : IInheritedDto { } diff --git a/src/Mapster/Adapters/ReadOnlyInterfaceAdapter.cs b/src/Mapster/Adapters/ReadOnlyInterfaceAdapter.cs index 3703c28..3b22f8d 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 7e90141..7257282 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 ctorBuilder = builder.DefineConstructor(MethodAttributes.Public, + var filteredArgs = DropIgnoredMemebers(args); + var ctorBuilder = builder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, - args.Select(it => it.FieldType).ToArray()); + filteredArgs.Select(it => it.FieldType).ToArray()); var ctorIl = ctorBuilder.GetILGenerator(); - for (var i = 0; i < args.Count; i++) + for (var i = 0; i < filteredArgs.Count; i++) { - var arg = args[i]; + var arg = filteredArgs[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,25 @@ private static void CreateMethod(TypeBuilder builder, MethodInfo interfaceMethod builder.DefineMethodOverride(classMethod, interfaceMethod); } + + private static List DropIgnoredMemebers(List fields) + { + if (ignoreMembers == null || ignoreMembers.Count == 0) + return fields; + + var ignoreFields = ignoreMembers.Select(x => x.Key).ToArray(); + var filtered = new List(); + + foreach (var item in fields) + { + foreach (var check in ignoreFields) + { + if (item.Name != $"_{MapsterHelper.CamelCase(check)}") + filtered.Add(item); + } + } + + return filtered; + } } -} +} \ No newline at end of file