mirror of https://github.com/abpframework/abp.git
3 changed files with 87 additions and 59 deletions
@ -0,0 +1,85 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Concurrent; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Collections.ObjectModel; |
||||
|
using System.Linq; |
||||
|
|
||||
|
namespace Volo.Abp.ObjectMapping; |
||||
|
|
||||
|
public static class ObjectMappingHelper |
||||
|
{ |
||||
|
private static readonly ConcurrentDictionary<(Type, Type), (Type sourceArgumentType, Type destinationArgumentType, Type definitionGenericType)?> Cache = new(); |
||||
|
|
||||
|
public static bool IsCollectionGenericType<TSource, TDestination>( |
||||
|
out Type sourceArgumentType, |
||||
|
out Type destinationArgumentType, |
||||
|
out Type definitionGenericType) |
||||
|
{ |
||||
|
var cached = Cache.GetOrAdd((typeof(TSource), typeof(TDestination)), _ => IsCollectionGenericTypeInternal<TSource, TDestination>()); |
||||
|
if (cached == null) |
||||
|
{ |
||||
|
sourceArgumentType = destinationArgumentType = definitionGenericType = null!; |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
(sourceArgumentType, destinationArgumentType, definitionGenericType) = cached.Value; |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
private static (Type, Type, Type)? IsCollectionGenericTypeInternal<TSource, TDestination>() |
||||
|
{ |
||||
|
Type sourceArgumentType = null!; |
||||
|
Type destinationArgumentType = null!; |
||||
|
Type definitionGenericType = null!; |
||||
|
|
||||
|
if ((!typeof(TSource).IsGenericType && !typeof(TSource).IsArray) || |
||||
|
(!typeof(TDestination).IsGenericType && !typeof(TDestination).IsArray)) |
||||
|
{ |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
var supportedCollectionTypes = new[] |
||||
|
{ |
||||
|
typeof(IEnumerable<>), |
||||
|
typeof(ICollection<>), |
||||
|
typeof(Collection<>), |
||||
|
typeof(IList<>), |
||||
|
typeof(List<>) |
||||
|
}; |
||||
|
|
||||
|
if (typeof(TSource).IsGenericType && supportedCollectionTypes.Any(x => x == typeof(TSource).GetGenericTypeDefinition())) |
||||
|
{ |
||||
|
sourceArgumentType = typeof(TSource).GenericTypeArguments[0]; |
||||
|
} |
||||
|
|
||||
|
if (typeof(TSource).IsArray) |
||||
|
{ |
||||
|
sourceArgumentType = typeof(TSource).GetElementType()!; |
||||
|
} |
||||
|
|
||||
|
if (sourceArgumentType == null) |
||||
|
{ |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
definitionGenericType = typeof(List<>); |
||||
|
if (typeof(TDestination).IsGenericType && supportedCollectionTypes.Any(x => x == typeof(TDestination).GetGenericTypeDefinition())) |
||||
|
{ |
||||
|
destinationArgumentType = typeof(TDestination).GenericTypeArguments[0]; |
||||
|
|
||||
|
if (typeof(TDestination).GetGenericTypeDefinition() == typeof(ICollection<>) || |
||||
|
typeof(TDestination).GetGenericTypeDefinition() == typeof(Collection<>)) |
||||
|
{ |
||||
|
definitionGenericType = typeof(Collection<>); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (typeof(TDestination).IsArray) |
||||
|
{ |
||||
|
destinationArgumentType = typeof(TDestination).GetElementType()!; |
||||
|
definitionGenericType = typeof(Array); |
||||
|
} |
||||
|
|
||||
|
return (sourceArgumentType, destinationArgumentType, definitionGenericType); |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue