Browse Source

Add `ObjectMappingHelper` to enhance performance.

pull/23435/head
maliming 6 months ago
parent
commit
b89031b671
No known key found for this signature in database GPG Key ID: A646B9CB645ECEA4
  1. 2
      framework/src/Volo.Abp.Mapperly/Volo/Abp/Mapperly/MapperlyAutoObjectMappingProvider.cs
  2. 59
      framework/src/Volo.Abp.ObjectMapping/Volo/Abp/ObjectMapping/DefaultObjectMapper.cs
  3. 85
      framework/src/Volo.Abp.ObjectMapping/Volo/Abp/ObjectMapping/ObjectMappingHelper.cs

2
framework/src/Volo.Abp.Mapperly/Volo/Abp/Mapperly/MapperlyAutoObjectMappingProvider.cs

@ -98,7 +98,7 @@ public class MapperlyAutoObjectMappingProvider : IAutoObjectMappingProvider
protected virtual bool TryToMapCollection<TSource, TDestination>(TSource source, TDestination? destination, out TDestination collectionResult)
{
if (!DefaultObjectMapper.IsCollectionGenericType<TSource, TDestination>(out var sourceArgumentType, out var destinationArgumentType, out var definitionGenericType))
if (!ObjectMappingHelper.IsCollectionGenericType<TSource, TDestination>(out var sourceArgumentType, out var destinationArgumentType, out var definitionGenericType))
{
collectionResult = default!;
return false;

59
framework/src/Volo.Abp.ObjectMapping/Volo/Abp/ObjectMapping/DefaultObjectMapper.cs

@ -123,7 +123,7 @@ public class DefaultObjectMapper : IObjectMapper, ITransientDependency
protected virtual bool TryToMapCollection<TSource, TDestination>(IServiceScope serviceScope, TSource source, TDestination? destination, out TDestination collectionResult)
{
if (!IsCollectionGenericType<TSource, TDestination>(out var sourceArgumentType, out var destinationArgumentType, out var definitionGenericType))
if (!ObjectMappingHelper.IsCollectionGenericType<TSource, TDestination>(out var sourceArgumentType, out var destinationArgumentType, out var definitionGenericType))
{
collectionResult = default!;
return false;
@ -242,63 +242,6 @@ public class DefaultObjectMapper : IObjectMapper, ITransientDependency
return Expression.Lambda<Func<object, object, object, object?>>(callConvert, instanceParam, sourceParam, destinationParam).Compile();
}
public static bool IsCollectionGenericType<TSource, TDestination>(out Type sourceArgumentType, out Type destinationArgumentType, out Type definitionGenericType)
{
sourceArgumentType = null!;
destinationArgumentType = null!;
definitionGenericType = null!;
if ((!typeof(TSource).IsGenericType && !typeof(TSource).IsArray) ||
(!typeof(TDestination).IsGenericType && !typeof(TDestination).IsArray))
{
return false;
}
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 false;
}
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 destinationArgumentType != null!;
}
protected virtual TDestination AutoMap<TSource, TDestination>(object source)
{
return AutoObjectMappingProvider.Map<TSource, TDestination>(source);

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

@ -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…
Cancel
Save