diff --git a/framework/src/Volo.Abp.Mapperly/Volo/Abp/Mapperly/AbpMapperlyConventionalRegistrar.cs b/framework/src/Volo.Abp.Mapperly/Volo/Abp/Mapperly/AbpMapperlyConventionalRegistrar.cs index a4af516425..5c1627b0a2 100644 --- a/framework/src/Volo.Abp.Mapperly/Volo/Abp/Mapperly/AbpMapperlyConventionalRegistrar.cs +++ b/framework/src/Volo.Abp.Mapperly/Volo/Abp/Mapperly/AbpMapperlyConventionalRegistrar.cs @@ -16,9 +16,9 @@ public class AbpMapperlyConventionalRegistrar : DefaultConventionalRegistrar protected override List GetExposedServiceTypes(Type type) { var exposedServiceTypes = base.GetExposedServiceTypes(type); - var mapperlyInterfaces = type.GetInterfaces() - .Where(x => x.IsGenericType && typeof(IAbpMapperly<,>) == x.GetGenericTypeDefinition() || - x.IsGenericType && typeof(IAbpReverseMapperly<,>) == x.GetGenericTypeDefinition()).ToList(); + var mapperlyInterfaces = type.GetInterfaces().Where(x => + x.IsGenericType && (typeof(IAbpMapperly<,>) == x.GetGenericTypeDefinition() || + typeof(IAbpReverseMapperly<,>) == x.GetGenericTypeDefinition())); return exposedServiceTypes .Union(mapperlyInterfaces) .Distinct() diff --git a/framework/src/Volo.Abp.Mapperly/Volo/Abp/Mapperly/IAbpMapperly.cs b/framework/src/Volo.Abp.Mapperly/Volo/Abp/Mapperly/IAbpMapperly.cs index e64bc38e85..5132fc980e 100644 --- a/framework/src/Volo.Abp.Mapperly/Volo/Abp/Mapperly/IAbpMapperly.cs +++ b/framework/src/Volo.Abp.Mapperly/Volo/Abp/Mapperly/IAbpMapperly.cs @@ -1,6 +1,6 @@ namespace Volo.Abp.Mapperly; -public interface IAbpMapperly +public interface IAbpMapperly { TDestination Map(TSource source); diff --git a/framework/src/Volo.Abp.Mapperly/Volo/Abp/Mapperly/MapperlyAutoObjectMappingProvider.cs b/framework/src/Volo.Abp.Mapperly/Volo/Abp/Mapperly/MapperlyAutoObjectMappingProvider.cs index 289f5d2c68..28385da5f5 100644 --- a/framework/src/Volo.Abp.Mapperly/Volo/Abp/Mapperly/MapperlyAutoObjectMappingProvider.cs +++ b/framework/src/Volo.Abp.Mapperly/Volo/Abp/Mapperly/MapperlyAutoObjectMappingProvider.cs @@ -5,6 +5,7 @@ using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Data; using Volo.Abp.ObjectExtending; using Volo.Abp.ObjectMapping; +using Volo.Abp.Reflection; namespace Volo.Abp.Mapperly; @@ -47,7 +48,8 @@ public class MapperlyAutoObjectMappingProvider : IAutoObjectMappingProvider return destination; } - throw new AbpException($"No {nameof(IAbpMapperly)} mapper found for {typeof(TSource).FullName} to {typeof(TDestination).FullName}"); + throw new AbpException($"No {TypeHelper.GetFullNameHandlingNullableAndGenerics(typeof(IAbpMapperly))} or" + + $" {TypeHelper.GetFullNameHandlingNullableAndGenerics(typeof(IAbpReverseMapperly))} was found"); } public virtual TDestination Map(TSource source, TDestination destination) @@ -63,7 +65,19 @@ public class MapperlyAutoObjectMappingProvider : IAutoObjectMappingProvider return destination; } - throw new AbpException($"No {nameof(IAbpMapperly)} mapper found for {typeof(TSource).FullName} to {typeof(TDestination).FullName}"); + var reverseMapper = ServiceProvider.GetService>(); + if (reverseMapper != null) + { + reverseMapper.BeforeReverseMap(source); + var destinationExtraProperties = GetExtraProperties(destination); + reverseMapper.ReverseMap(source, destination); + TryMapExtraProperties(reverseMapper.As>(), source, destination, destinationExtraProperties); + reverseMapper.AfterReverseMap(source, destination); + return destination; + } + + throw new AbpException($"No {TypeHelper.GetFullNameHandlingNullableAndGenerics(typeof(IAbpMapperly))} or" + + $" {TypeHelper.GetFullNameHandlingNullableAndGenerics(typeof(IAbpReverseMapperly))} was found"); } protected virtual ExtraPropertyDictionary GetExtraProperties(TDestination destination) diff --git a/framework/test/Volo.Abp.Mapperly.Tests/Volo/Abp/Mapperly/AbpMapperlyModule_Basic_Tests.cs b/framework/test/Volo.Abp.Mapperly.Tests/Volo/Abp/Mapperly/AbpMapperlyModule_Basic_Tests.cs index 5edad59b1b..96573fca52 100644 --- a/framework/test/Volo.Abp.Mapperly.Tests/Volo/Abp/Mapperly/AbpMapperlyModule_Basic_Tests.cs +++ b/framework/test/Volo.Abp.Mapperly.Tests/Volo/Abp/Mapperly/AbpMapperlyModule_Basic_Tests.cs @@ -1,4 +1,5 @@ -using Microsoft.Extensions.DependencyInjection; +using System; +using Microsoft.Extensions.DependencyInjection; using Shouldly; using Volo.Abp.Mapperly.SampleClasses; using Volo.Abp.ObjectMapping; @@ -29,10 +30,31 @@ public class AbpMapperlyModule_Basic_Tests : AbpIntegratedTest(new MyEntity { Id = Guid.NewGuid(), Number = 43 }, dto); + + dto.Number.ShouldBe(43); + dto.Id.ShouldNotBe(Guid.Empty); + } + [Fact] public void Should_Map_Enum() { var dto = _objectMapper.Map(MyEnum.Value3); dto.ShouldBe(MyEnumDto.Value2); //Value2 is same as Value3 } + + [Fact] + public void Should_Throw_Exception_If_Mapper_Is_Not_Found() + { + var exception = Assert.Throws(() =>_objectMapper.Map(new MyEntity())); + exception.Message.ShouldBe("No " + + "Volo.Abp.Mapperly.IAbpMapperly or " + + "Volo.Abp.Mapperly.IAbpReverseMapperly" + + " was found"); + } } diff --git a/framework/test/Volo.Abp.Mapperly.Tests/Volo/Abp/Mapperly/AbpAutoMapperModule_Specific_ObjectMapper_Tests.cs b/framework/test/Volo.Abp.Mapperly.Tests/Volo/Abp/Mapperly/AbpMapperlyModule_Specific_ObjectMapper_Tests.cs similarity index 97% rename from framework/test/Volo.Abp.Mapperly.Tests/Volo/Abp/Mapperly/AbpAutoMapperModule_Specific_ObjectMapper_Tests.cs rename to framework/test/Volo.Abp.Mapperly.Tests/Volo/Abp/Mapperly/AbpMapperlyModule_Specific_ObjectMapper_Tests.cs index 0080517c36..60f4294aeb 100644 --- a/framework/test/Volo.Abp.Mapperly.Tests/Volo/Abp/Mapperly/AbpAutoMapperModule_Specific_ObjectMapper_Tests.cs +++ b/framework/test/Volo.Abp.Mapperly.Tests/Volo/Abp/Mapperly/AbpMapperlyModule_Specific_ObjectMapper_Tests.cs @@ -11,11 +11,11 @@ using Xunit; namespace Volo.Abp.Mapperly; -public class AbpAutoMapperModule_Specific_ObjectMapper_Tests : AbpIntegratedTest +public class AbpMapperlyModule_Specific_ObjectMapper_Tests : AbpIntegratedTest { private readonly IObjectMapper _objectMapper; - public AbpAutoMapperModule_Specific_ObjectMapper_Tests() + public AbpMapperlyModule_Specific_ObjectMapper_Tests() { _objectMapper = ServiceProvider.GetRequiredService(); } diff --git a/framework/test/Volo.Abp.Mapperly.Tests/Volo/Abp/Mapperly/ObjectMapperExtensions_Tests.cs b/framework/test/Volo.Abp.Mapperly.Tests/Volo/Abp/Mapperly/ObjectMapperExtensions_Tests.cs deleted file mode 100644 index 4cfd58a760..0000000000 --- a/framework/test/Volo.Abp.Mapperly.Tests/Volo/Abp/Mapperly/ObjectMapperExtensions_Tests.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; -using Microsoft.Extensions.DependencyInjection; -using Shouldly; -using Volo.Abp.Mapperly.SampleClasses; -using Volo.Abp.ObjectMapping; -using Volo.Abp.Testing; -using Xunit; - -namespace Volo.Abp.Mapperly; - -public class ObjectMapperExtensions_Tests : AbpIntegratedTest -{ - private readonly IObjectMapper _objectMapper; - - public ObjectMapperExtensions_Tests() - { - _objectMapper = ServiceProvider.GetRequiredService(); - } - - [Fact] - public void Should_Map_Objects_With_AutoMap_Attributes() - { - var dto = _objectMapper.Map( - new MyEntity - { - Number = 42 - } - ); - - dto.As().Number.ShouldBe(42); - } -}