From ce45a00718771bd3ecb53bfff2246edff76c3668 Mon Sep 17 00:00:00 2001 From: maliming Date: Thu, 19 Sep 2024 11:15:50 +0800 Subject: [PATCH] Add unit test. --- .../Abp/ObjectMapping/DefaultObjectMapper.cs | 35 ++++++++++++++----- ...apperModule_Specific_ObjectMapper_Tests.cs | 21 +++++++++++ .../MyEntityToMyEntityDto2Mapper.cs | 18 +++++++++- 3 files changed, 65 insertions(+), 9 deletions(-) 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 63617d27592..e3577bee6ef 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 virtual TDestination Map(TSource source, TDestinat 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 46f028596d4..47b684538cb 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 void Specific_Object_Mapper_Should_Be_Used_For_Collections_If_Registered( 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 6d06a72db8a..6bf16fce8ef 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 @@ 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 MyEntityDto2 Map(MyEntity source, MyEntityDto2 destination) destination.Number = source.Number + 1; return destination; } + + public MyEntity Map(MyEntityDto2 source) + { + return new MyEntity + { + Id = source.Id, + Number = source.Number + 1 + }; + } + + public MyEntity Map(MyEntityDto2 source, MyEntity destination) + { + destination.Id = source.Id; + destination.Number = source.Number + 1; + return destination; + } }