All checks were successful
CI/CD Pipeline / Build and Deploy with Docker Compose (push) Successful in 5m4s
93 lines
3.9 KiB
C#
93 lines
3.9 KiB
C#
using System.Collections;
|
|
using System.Reflection;
|
|
|
|
namespace Models.Helpers
|
|
{
|
|
public static class EntityMapper
|
|
{
|
|
public static TDestination MapEntity<TSource, TDestination>(TSource source)
|
|
where TDestination : new()
|
|
{
|
|
var destination = new TDestination();
|
|
var sourceProps = typeof(TSource).GetProperties();
|
|
var destProps = typeof(TDestination).GetProperties();
|
|
|
|
foreach (var sourceProp in sourceProps)
|
|
{
|
|
var destProp = destProps.FirstOrDefault(p => p.Name == sourceProp.Name);
|
|
if (destProp == null || !destProp.CanWrite) continue;
|
|
|
|
var sourceValue = sourceProp.GetValue(source);
|
|
|
|
if (sourceValue == null)
|
|
{
|
|
destProp.SetValue(destination, null);
|
|
continue;
|
|
}
|
|
|
|
if (IsGenericCollection(destProp.PropertyType) &&
|
|
IsGenericCollection(sourceProp.PropertyType))
|
|
{
|
|
var sourceElementType = sourceProp.PropertyType.GenericTypeArguments[0];
|
|
var destElementType = destProp.PropertyType.GenericTypeArguments[0];
|
|
|
|
var mappedList = (IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(destElementType))!;
|
|
|
|
foreach (var item in (IEnumerable)sourceValue)
|
|
{
|
|
var mapMethod = typeof(EntityMapper)
|
|
.GetMethod(nameof(MapEntity), BindingFlags.Public | BindingFlags.Static)!
|
|
.MakeGenericMethod(sourceElementType, destElementType);
|
|
|
|
var mappedItem = mapMethod.Invoke(null, new[] { item });
|
|
mappedList.Add(mappedItem);
|
|
}
|
|
|
|
destProp.SetValue(destination, mappedList);
|
|
}
|
|
else if (destProp.PropertyType.IsAssignableFrom(sourceProp.PropertyType))
|
|
{
|
|
destProp.SetValue(destination, sourceValue);
|
|
}
|
|
else if (!destProp.PropertyType.IsPrimitive &&
|
|
destProp.PropertyType != typeof(string) &&
|
|
destProp.PropertyType.GetConstructor(Type.EmptyTypes) != null)
|
|
{
|
|
// Mapeo de objetos anidados
|
|
var mapMethod = typeof(EntityMapper)
|
|
.GetMethod(nameof(MapEntity), BindingFlags.Public | BindingFlags.Static)!
|
|
.MakeGenericMethod(sourceProp.PropertyType, destProp.PropertyType);
|
|
|
|
var mappedValue = mapMethod.Invoke(null, new[] { sourceValue });
|
|
destProp.SetValue(destination, mappedValue);
|
|
}
|
|
}
|
|
|
|
return destination;
|
|
}
|
|
public static void MapEntityToExisting<TSource, TTarget>(TSource source, TTarget target)
|
|
{
|
|
var sourceProps = typeof(TSource).GetProperties();
|
|
var targetProps = typeof(TTarget).GetProperties();
|
|
|
|
foreach (var sourceProp in sourceProps)
|
|
{
|
|
var targetProp = targetProps.FirstOrDefault(p => p.Name == sourceProp.Name && p.PropertyType == sourceProp.PropertyType);
|
|
if (targetProp != null && targetProp.CanWrite)
|
|
{
|
|
var value = sourceProp.GetValue(source);
|
|
targetProp.SetValue(target, value);
|
|
}
|
|
}
|
|
}
|
|
private static bool IsGenericCollection(Type type)
|
|
{
|
|
if (!type.IsGenericType) return false;
|
|
var genericDef = type.GetGenericTypeDefinition();
|
|
return typeof(IEnumerable<>).IsAssignableFrom(genericDef) ||
|
|
type.GetInterfaces().Any(i => i.IsGenericType &&
|
|
i.GetGenericTypeDefinition() == typeof(IEnumerable<>));
|
|
}
|
|
}
|
|
}
|