Browse Source

Refactor collection type handling in ObjectMappingHelper and enhance tests for mapping collections

pull/23443/head
maliming 1 year ago
parent
commit
bf7349ba3c
No known key found for this signature in database GPG Key ID: A646B9CB645ECEA4
  1. 56
      framework/src/Volo.Abp.ObjectMapping/Volo/Abp/ObjectMapping/ObjectMappingHelper.cs
  2. 25
      framework/test/Volo.Abp.Mapperly.Tests/Volo/Abp/Mapperly/AbpMapperlyModule_Basic_Tests.cs

56
framework/src/Volo.Abp.ObjectMapping/Volo/Abp/ObjectMapping/ObjectMappingHelper.cs

@ -28,16 +28,17 @@ public static class ObjectMappingHelper
private static (Type, Type, Type)? IsCollectionGenericTypeInternal<TSource, TDestination>() private static (Type, Type, Type)? IsCollectionGenericTypeInternal<TSource, TDestination>()
{ {
Type sourceArgumentType = null!; if (!IsCollectionGenericTypeInternal(typeof(TSource), out var sourceArgumentType, out _) ||
Type destinationArgumentType = null!; !IsCollectionGenericTypeInternal(typeof(TDestination), out var destinationArgumentType, out var definitionGenericType))
Type definitionGenericType = null!;
if ((!typeof(TSource).IsGenericType && !typeof(TSource).IsArray) ||
(!typeof(TDestination).IsGenericType && !typeof(TDestination).IsArray))
{ {
return null; return null;
} }
return (sourceArgumentType, destinationArgumentType, definitionGenericType);
}
private static bool IsCollectionGenericTypeInternal(Type type, out Type elementType, out Type definitionGenericType)
{
var supportedCollectionTypes = new[] var supportedCollectionTypes = new[]
{ {
typeof(IEnumerable<>), typeof(IEnumerable<>),
@ -47,39 +48,34 @@ public static class ObjectMappingHelper
typeof(List<>) typeof(List<>)
}; };
if (typeof(TSource).IsGenericType && supportedCollectionTypes.Any(x => x == typeof(TSource).GetGenericTypeDefinition())) if (type.IsArray)
{
sourceArgumentType = typeof(TSource).GenericTypeArguments[0];
}
if (typeof(TSource).IsArray)
{
sourceArgumentType = typeof(TSource).GetElementType()!;
}
if (sourceArgumentType == null)
{ {
return null; elementType = type.GetElementType()!;
definitionGenericType = type;
return true;
} }
definitionGenericType = typeof(List<>); if (type.IsGenericType &&
if (typeof(TDestination).IsGenericType && supportedCollectionTypes.Any(x => x == typeof(TDestination).GetGenericTypeDefinition())) supportedCollectionTypes.Contains(type.GetGenericTypeDefinition()) ||
type.GetInterfaces().Any(i => i.IsGenericType && supportedCollectionTypes.Contains(i.GetGenericTypeDefinition())))
{ {
destinationArgumentType = typeof(TDestination).GenericTypeArguments[0]; elementType = type.GetGenericArguments()[0];
definitionGenericType = type.GetGenericTypeDefinition();
if (definitionGenericType == typeof(IEnumerable<>) ||
definitionGenericType == typeof(IList<>))
{
definitionGenericType = typeof(List<>);
}
if (typeof(TDestination).GetGenericTypeDefinition() == typeof(ICollection<>) || if (definitionGenericType == typeof(ICollection<>))
typeof(TDestination).GetGenericTypeDefinition() == typeof(Collection<>))
{ {
definitionGenericType = typeof(Collection<>); definitionGenericType = typeof(Collection<>);
} }
return true;
} }
if (typeof(TDestination).IsArray) elementType = null!;
{ definitionGenericType = null!;
destinationArgumentType = typeof(TDestination).GetElementType()!; return false;
definitionGenericType = typeof(Array);
}
return (sourceArgumentType, destinationArgumentType, definitionGenericType);
} }
} }

25
framework/test/Volo.Abp.Mapperly.Tests/Volo/Abp/Mapperly/AbpMapperlyModule_Basic_Tests.cs

@ -1,5 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices.JavaScript;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Shouldly; using Shouldly;
using Volo.Abp.Mapperly.SampleClasses; using Volo.Abp.Mapperly.SampleClasses;
@ -55,13 +57,23 @@ public class AbpMapperlyModule_Basic_Tests : AbpIntegratedTest<MapperlyTestModul
dto[0].Number.ShouldBe(42); dto[0].Number.ShouldBe(42);
dto[1].Number.ShouldBe(43); dto[1].Number.ShouldBe(43);
var dto2 = _objectMapper.Map<IReadOnlyList<MyEntity>, MyEntityDto[]>(new List<MyEntity>
{
new MyEntity { Number = 42 },
new MyEntity { Number = 43 }
}.AsReadOnly());
dto2.Length.ShouldBe(2);
dto2[0].Number.ShouldBe(42);
dto2[1].Number.ShouldBe(43);
var dtoList = new List<MyEntityDto>(); var dtoList = new List<MyEntityDto>();
{ {
new MyEntityDto() { Number = 44 }; new MyEntityDto() { Number = 44 };
new MyEntityDto() { Number = 45 }; new MyEntityDto() { Number = 45 };
} }
dto = _objectMapper.Map<List<MyEntity>, List<MyEntityDto>>(new List<MyEntity> _objectMapper.Map<List<MyEntity>, List<MyEntityDto>>(new List<MyEntity>
{ {
new MyEntity { Number = 42 }, new MyEntity { Number = 42 },
new MyEntity { Number = 43 } new MyEntity { Number = 43 }
@ -70,6 +82,17 @@ public class AbpMapperlyModule_Basic_Tests : AbpIntegratedTest<MapperlyTestModul
dtoList.Count.ShouldBe(2); dtoList.Count.ShouldBe(2);
dtoList[0].Number.ShouldBe(42); dtoList[0].Number.ShouldBe(42);
dtoList[1].Number.ShouldBe(43); dtoList[1].Number.ShouldBe(43);
var dtoArray = dtoList.ToArray();
_objectMapper.Map<IReadOnlyList<MyEntity>, MyEntityDto[]>(new List<MyEntity>
{
new MyEntity { Number = 42 },
new MyEntity { Number = 43 }
}.AsReadOnly(), dtoArray);
dtoArray.Length.ShouldBe(2);
dtoArray[0].Number.ShouldBe(42);
dtoArray[1].Number.ShouldBe(43);
} }
[Fact] [Fact]

Loading…
Cancel
Save