Browse Source

test

salihozkara/mapperly-test
SALİH ÖZKARA 6 months ago
parent
commit
d6f58c39f3
  1. 122
      framework/src/Volo.Abp.Mapperly/Volo/Abp/Mapperly/MapExtraPropertiesAttribute.cs
  2. 122
      framework/src/Volo.Abp.Mapperly/Volo/Abp/Mapperly/MapperlyAutoObjectMappingProvider.cs

122
framework/src/Volo.Abp.Mapperly/Volo/Abp/Mapperly/MapExtraPropertiesAttribute.cs

@ -1,14 +1,132 @@
using System; using System;
using System.Collections.Generic;
using System.Reflection;
using Volo.Abp.Data;
using Volo.Abp.ObjectExtending; using Volo.Abp.ObjectExtending;
namespace Volo.Abp.Mapperly; namespace Volo.Abp.Mapperly;
// [AttributeUsage(AttributeTargets.Class)]
// public class MapExtraPropertiesAttribute : Attribute
// {
// public MappingPropertyDefinitionChecks DefinitionChecks { get; set; } = MappingPropertyDefinitionChecks.Null;
//
// public string[]? IgnoredProperties { get; set; }
//
// public bool MapToRegularProperties { get; set; }
// }
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public abstract class BeforeMap<TSource> : Attribute
{
public abstract void Execute(TSource source);
public Type GetSourceType()
{
return typeof(TSource);
}
}
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public abstract class AfterMap<TSource, TDestination> : Attribute
{
public abstract void Execute(TSource source, TDestination destination);
public Type GetSourceType()
{
return typeof(TSource);
}
public Type GetDestinationType()
{
return typeof(TDestination);
}
}
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public abstract class AfterMap<TSource, TDestination, TContext> : Attribute
{
public abstract TContext CreateContext(TSource source);
public abstract TContext CreateContextWithDestination(TSource source, TDestination destination);
public abstract void Execute(TSource source, TDestination destination, TContext context);
}
[AttributeUsage(AttributeTargets.Class)] [AttributeUsage(AttributeTargets.Class)]
public class MapExtraPropertiesAttribute : Attribute public class MapExtraPropertiesAttribute : AfterMap<IHasExtraProperties, IHasExtraProperties, ExtraPropertyDictionary>
{ {
public MappingPropertyDefinitionChecks DefinitionChecks { get; set; } = MappingPropertyDefinitionChecks.Null; public MappingPropertyDefinitionChecks DefinitionChecks { get; set; } = MappingPropertyDefinitionChecks.Null;
public string[]? IgnoredProperties { get; set; } public string[]? IgnoredProperties { get; set; }
public bool MapToRegularProperties { get; set; } public bool MapToRegularProperties { get; set; }
}
protected virtual void MapExtraProperties<TSource, TDestination>(
IHasExtraProperties source,
IHasExtraProperties destination,
ExtraPropertyDictionary destinationExtraProperty,
MappingPropertyDefinitionChecks? definitionChecks = null,
string[]? ignoredProperties = null,
bool mapToRegularProperties = false)
{
var result = destinationExtraProperty.IsNullOrEmpty()
? new Dictionary<string, object?>()
: new Dictionary<string, object?>(destinationExtraProperty);
if (source.ExtraProperties != null && destination.ExtraProperties != null)
{
ExtensibleObjectMapper
.MapExtraPropertiesTo(
typeof(TSource),
typeof(TDestination),
source.ExtraProperties,
result,
definitionChecks,
ignoredProperties
);
}
ObjectHelper.TrySetProperty(destination, x => x.ExtraProperties, () => new ExtraPropertyDictionary(result));
if (mapToRegularProperties)
{
destination.SetExtraPropertiesToRegularProperties();
}
}
protected virtual ExtraPropertyDictionary GetExtraProperties<TDestination>(TDestination destination)
{
var extraProperties = new ExtraPropertyDictionary();
if (destination is not IHasExtraProperties hasExtraProperties)
{
return extraProperties;
}
foreach (var property in hasExtraProperties.ExtraProperties)
{
extraProperties.Add(property.Key, property.Value);
}
return extraProperties;
}
public override ExtraPropertyDictionary CreateContext(IHasExtraProperties source)
{
return new ExtraPropertyDictionary();
}
public override ExtraPropertyDictionary CreateContextWithDestination(IHasExtraProperties source, IHasExtraProperties destination)
{
return GetExtraProperties(destination);
}
public override void Execute(IHasExtraProperties source, IHasExtraProperties destination, ExtraPropertyDictionary context)
{
MapExtraProperties<IHasExtraProperties, IHasExtraProperties>(
source,
destination,
context,
DefinitionChecks,
IgnoredProperties,
MapToRegularProperties
);
}
}

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

@ -34,18 +34,69 @@ public class MapperlyAutoObjectMappingProvider : IAutoObjectMappingProvider
public virtual TDestination Map<TSource, TDestination>(object source) public virtual TDestination Map<TSource, TDestination>(object source)
{ {
if (TryToMapCollection<TSource, TDestination>((TSource)source, default, out var collectionResult))
{
return collectionResult;
}
var mapper = ServiceProvider.GetService<IAbpMapperlyMapper<TSource, TDestination>>(); var mapper = ServiceProvider.GetService<IAbpMapperlyMapper<TSource, TDestination>>();
if (mapper != null) if (mapper != null)
{ {
var beforeMapAttributes = mapper.GetType().GetCustomAttributes(typeof(BeforeMap<>)).Where(x => typeof(TSource).IsAssignableFrom(x.GetType().GetGenericArguments().FirstOrDefault()))
.ToList();
var beforeMapAttributeExecuteMethod = typeof(BeforeMap<>).GetMethod(nameof(BeforeMap<object>.Execute),
BindingFlags.Instance | BindingFlags.Public);
if (beforeMapAttributeExecuteMethod != null)
{
foreach (var beforeMapAttribute in beforeMapAttributes)
{
var executeMethod = beforeMapAttributeExecuteMethod.MakeGenericMethod(typeof(TSource));
executeMethod.Invoke(beforeMapAttribute, [source]);
}
}
mapper.BeforeMap((TSource)source); mapper.BeforeMap((TSource)source);
var afterMapAttributes = mapper.GetType().GetCustomAttributes(typeof(AfterMap<,>)).Where(x => typeof(TSource).IsAssignableFrom(x.GetType().GetGenericArguments().FirstOrDefault()) &&
typeof(TDestination).IsAssignableFrom(x.GetType().GetGenericArguments().LastOrDefault())).ToArray();
var afterMapAttributesWithContext = afterMapAttributes
.Where(x => typeof(AfterMap<, ,>).IsInstanceOfType(x))
.ToList();
var contexts = new List<object?>();
var createContextMethod = typeof(AfterMap<, ,>).GetMethod(nameof(AfterMap<object, object, object>.CreateContext),
BindingFlags.Instance | BindingFlags.Public);
if (createContextMethod != null)
{
foreach (var afterMapAttribute in afterMapAttributesWithContext)
{
var context = createContextMethod.Invoke(afterMapAttribute, [source]);
contexts.Add(context);
}
}
var destination = mapper.Map((TSource)source); var destination = mapper.Map((TSource)source);
TryMapExtraProperties(mapper.GetType().GetSingleAttributeOrNull<MapExtraPropertiesAttribute>(), (TSource)source, destination, new ExtraPropertyDictionary()); TryMapExtraProperties(mapper.GetType().GetSingleAttributeOrNull<MapExtraPropertiesAttribute>(), (TSource)source, destination, new ExtraPropertyDictionary());
mapper.AfterMap((TSource)source, destination); mapper.AfterMap((TSource)source, destination);
var afterMapExecuteMethod = typeof(AfterMap<, ,>).GetMethod(nameof(AfterMap<object, object, object>.Execute),
BindingFlags.Instance | BindingFlags.Public);
if (afterMapExecuteMethod != null)
{
for (var i = 0; i < afterMapAttributesWithContext.Count; i++)
{
var afterMapAttribute = afterMapAttributesWithContext[i];
var executeMethod = afterMapExecuteMethod.MakeGenericMethod(typeof(TSource), typeof(TDestination));
executeMethod.Invoke(afterMapAttribute, [source, destination, contexts[i]]);
}
}
var afterMapAttributesWithoutContext = afterMapAttributes
.Where(x => !typeof(AfterMap<, ,>).IsInstanceOfType(x))
.ToList();
var afterMapExecuteMethodWithoutContext = typeof(AfterMap<,>).GetMethod(nameof(AfterMap<object, object>.Execute),
BindingFlags.Instance | BindingFlags.Public);
if (afterMapExecuteMethodWithoutContext != null)
{
foreach (var afterMapAttribute in afterMapAttributesWithoutContext)
{
var executeMethod = afterMapExecuteMethodWithoutContext.MakeGenericMethod(typeof(TSource), typeof(TDestination));
executeMethod.Invoke(afterMapAttribute, [source, destination]);
}
}
return destination; return destination;
} }
@ -58,6 +109,11 @@ public class MapperlyAutoObjectMappingProvider : IAutoObjectMappingProvider
reverseMapper.AfterReverseMap((TSource)source, destination); reverseMapper.AfterReverseMap((TSource)source, destination);
return destination; return destination;
} }
if (TryToMapCollection<TSource, TDestination>((TSource)source, default, out var collectionResult))
{
return collectionResult;
}
throw new AbpException($"No {TypeHelper.GetFullNameHandlingNullableAndGenerics(typeof(IAbpMapperlyMapper<TSource, TDestination>))} or" + throw new AbpException($"No {TypeHelper.GetFullNameHandlingNullableAndGenerics(typeof(IAbpMapperlyMapper<TSource, TDestination>))} or" +
$" {TypeHelper.GetFullNameHandlingNullableAndGenerics(typeof(IAbpReverseMapperlyMapper<TSource, TDestination>))} was found"); $" {TypeHelper.GetFullNameHandlingNullableAndGenerics(typeof(IAbpReverseMapperlyMapper<TSource, TDestination>))} was found");
@ -65,11 +121,6 @@ public class MapperlyAutoObjectMappingProvider : IAutoObjectMappingProvider
public virtual TDestination Map<TSource, TDestination>(TSource source, TDestination destination) public virtual TDestination Map<TSource, TDestination>(TSource source, TDestination destination)
{ {
if (TryToMapCollection<TSource, TDestination>(source, destination, out var collectionResult))
{
return collectionResult;
}
var mapper = ServiceProvider.GetService<IAbpMapperlyMapper<TSource, TDestination>>(); var mapper = ServiceProvider.GetService<IAbpMapperlyMapper<TSource, TDestination>>();
if (mapper != null) if (mapper != null)
{ {
@ -91,6 +142,11 @@ public class MapperlyAutoObjectMappingProvider : IAutoObjectMappingProvider
reverseMapper.AfterReverseMap(source, destination); reverseMapper.AfterReverseMap(source, destination);
return destination; return destination;
} }
if (TryToMapCollection<TSource, TDestination>(source, destination, out var collectionResult))
{
return collectionResult;
}
throw new AbpException($"No {TypeHelper.GetFullNameHandlingNullableAndGenerics(typeof(IAbpMapperlyMapper<TSource, TDestination>))} or" + throw new AbpException($"No {TypeHelper.GetFullNameHandlingNullableAndGenerics(typeof(IAbpMapperlyMapper<TSource, TDestination>))} or" +
$" {TypeHelper.GetFullNameHandlingNullableAndGenerics(typeof(IAbpReverseMapperlyMapper<TSource, TDestination>))} was found"); $" {TypeHelper.GetFullNameHandlingNullableAndGenerics(typeof(IAbpReverseMapperlyMapper<TSource, TDestination>))} was found");
@ -216,21 +272,6 @@ public class MapperlyAutoObjectMappingProvider : IAutoObjectMappingProvider
return Expression.Lambda<Func<object, object, object, object?>>(callConvert, instanceParam, sourceParam, destinationParam).Compile(); return Expression.Lambda<Func<object, object, object, object?>>(callConvert, instanceParam, sourceParam, destinationParam).Compile();
} }
protected virtual ExtraPropertyDictionary GetExtraProperties<TDestination>(TDestination destination)
{
var extraProperties = new ExtraPropertyDictionary();
if (destination is not IHasExtraProperties hasExtraProperties)
{
return extraProperties;
}
foreach (var property in hasExtraProperties.ExtraProperties)
{
extraProperties.Add(property.Key, property.Value);
}
return extraProperties;
}
protected virtual void TryMapExtraProperties<TSource, TDestination>(MapExtraPropertiesAttribute? mapExtraPropertiesAttribute, TSource source, TDestination destination, ExtraPropertyDictionary destinationExtraProperty) protected virtual void TryMapExtraProperties<TSource, TDestination>(MapExtraPropertiesAttribute? mapExtraPropertiesAttribute, TSource source, TDestination destination, ExtraPropertyDictionary destinationExtraProperty)
{ {
if (mapExtraPropertiesAttribute != null && if (mapExtraPropertiesAttribute != null &&
@ -247,35 +288,4 @@ public class MapperlyAutoObjectMappingProvider : IAutoObjectMappingProvider
); );
} }
} }
protected virtual void MapExtraProperties<TSource, TDestination>(
IHasExtraProperties source,
IHasExtraProperties destination,
ExtraPropertyDictionary destinationExtraProperty,
MappingPropertyDefinitionChecks? definitionChecks = null,
string[]? ignoredProperties = null,
bool mapToRegularProperties = false)
{
var result = destinationExtraProperty.IsNullOrEmpty()
? new Dictionary<string, object?>()
: new Dictionary<string, object?>(destinationExtraProperty);
if (source.ExtraProperties != null && destination.ExtraProperties != null)
{
ExtensibleObjectMapper
.MapExtraPropertiesTo(
typeof(TSource),
typeof(TDestination),
source.ExtraProperties,
result,
definitionChecks,
ignoredProperties
);
}
ObjectHelper.TrySetProperty(destination, x => x.ExtraProperties, () => new ExtraPropertyDictionary(result));
if (mapToRegularProperties)
{
destination.SetExtraPropertiesToRegularProperties();
}
}
} }

Loading…
Cancel
Save