diff --git a/framework/src/Volo.Abp.ObjectMapping/Volo/Abp/ObjectMapping/DefaultObjectMapper.cs b/framework/src/Volo.Abp.ObjectMapping/Volo/Abp/ObjectMapping/DefaultObjectMapper.cs index 63617d2759..e3577bee6e 100644 --- a/framework/src/Volo.Abp.ObjectMapping/Volo/Abp/ObjectMapping/DefaultObjectMapper.cs +++ b/framework/src/Volo.Abp.ObjectMapping/Volo/Abp/ObjectMapping/DefaultObjectMapper.cs @@ -142,20 +142,39 @@ public class DefaultObjectMapper : IObjectMapper, ITransientDependency cacheKey, _ => { - var method = specificMapper + var methods = specificMapper .GetType() .GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) - .FirstOrDefault(x => - x.Name == nameof(IObjectMapper.Map) && - x.GetParameters().Length == (destination == null ? 1 : 2) - ); + .Where(x => x.Name == nameof(IObjectMapper.Map)) + .Where(x => + { + var parameters = x.GetParameters(); + if (destination == null && parameters.Length != 1 || + destination != null && parameters.Length != 2 || + parameters[0].ParameterType != sourceArgumentType) + { + return false; + } + + return destination == null || parameters[1].ParameterType == destinationArgumentType; + }) + .ToList(); + + if (methods.IsNullOrEmpty()) + { + throw new AbpException($"Could not find a method named '{nameof(IObjectMapper.Map)}'" + + $" with parameters({(destination == null ? sourceArgumentType.ToString() : sourceArgumentType + "," + destinationArgumentType)})" + + $" in the type '{mapperType}'."); + } - if (method == null) + if (methods.Count > 1) { - throw new AbpException($"Could not find a method named '{nameof(IObjectMapper.Map)}' with {(destination == null ? "1" : "2")} parameters in the type '{mapperType}'."); + throw new AbpException($"Found more than one method named '{nameof(IObjectMapper.Map)}'" + + $" with parameters({(destination == null ? sourceArgumentType.ToString() : sourceArgumentType + "," + destinationArgumentType)})" + + $" in the type '{mapperType}'."); } - return method; + return methods.First(); } ); diff --git a/framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/AbpAutoMapperModule_Specific_ObjectMapper_Tests.cs b/framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/AbpAutoMapperModule_Specific_ObjectMapper_Tests.cs index 46f028596d..47b684538c 100644 --- a/framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/AbpAutoMapperModule_Specific_ObjectMapper_Tests.cs +++ b/framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/AbpAutoMapperModule_Specific_ObjectMapper_Tests.cs @@ -130,6 +130,27 @@ public class AbpAutoMapperModule_Specific_ObjectMapper_Tests : AbpIntegratedTest ReferenceEquals(returnArray, destinationArray).ShouldBeFalse(); } + [Fact] + public void Specific_Object_Mapper_Should_Support_Multiple_IObjectMapper_Interfaces() + { + var myEntityDto2 = _objectMapper.Map(new MyEntity { Number = 42 }); + myEntityDto2.Number.ShouldBe(43); //MyEntityToMyEntityDto2Mapper adds 1 to number of the source. + + var myEntity = _objectMapper.Map(new MyEntityDto2 { Number = 42 }); + myEntity.Number.ShouldBe(43); //MyEntityToMyEntityDto2Mapper adds 1 to number of the source. + + // IEnumerable + _objectMapper.Map, IEnumerable>(new List() + { + new MyEntity { Number = 42 } + }).First().Number.ShouldBe(43); //MyEntityToMyEntityDto2Mapper adds 1 to number of the source. + + _objectMapper.Map, IEnumerable>(new List() + { + new MyEntityDto2 { Number = 42 } + }).First().Number.ShouldBe(43); //MyEntityToMyEntityDto2Mapper adds 1 to number of the source. + } + [Fact] public void Should_Use_Destination_Object_Constructor_If_Available() { diff --git a/framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/SampleClasses/MyEntityToMyEntityDto2Mapper.cs b/framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/SampleClasses/MyEntityToMyEntityDto2Mapper.cs index 6d06a72db8..6bf16fce8e 100644 --- a/framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/SampleClasses/MyEntityToMyEntityDto2Mapper.cs +++ b/framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/SampleClasses/MyEntityToMyEntityDto2Mapper.cs @@ -3,7 +3,7 @@ using Volo.Abp.ObjectMapping; namespace Volo.Abp.AutoMapper.SampleClasses; -public class MyEntityToMyEntityDto2Mapper : IObjectMapper, ITransientDependency +public class MyEntityToMyEntityDto2Mapper : IObjectMapper, IObjectMapper, ITransientDependency { public MyEntityDto2 Map(MyEntity source) { @@ -20,4 +20,20 @@ public class MyEntityToMyEntityDto2Mapper : IObjectMapper