From ee3a76ce3fd5a37677e20ae6758b6f3a526e51f8 Mon Sep 17 00:00:00 2001 From: Leandro Hernan Rojas Date: Fri, 4 Apr 2025 00:45:23 -0300 Subject: [PATCH] Update MapEntity Helper in API --- Domain/Entities/EDocumentType.cs | 8 +-- Models/Helpers/EntityMapper.cs | 66 +++++++++++++++++++ Models/Interfaces/IGenericRepository.cs | 11 ---- Models/Models/PhSDocumentType.cs | 5 +- .../Repositories/PhSAccountTypeRepository.cs | 17 +---- .../Repositories/PhSDocumentTypeRepository.cs | 19 ++---- 6 files changed, 75 insertions(+), 51 deletions(-) create mode 100644 Models/Helpers/EntityMapper.cs delete mode 100644 Models/Interfaces/IGenericRepository.cs diff --git a/Domain/Entities/EDocumentType.cs b/Domain/Entities/EDocumentType.cs index d8c72cd..c72f0ce 100644 --- a/Domain/Entities/EDocumentType.cs +++ b/Domain/Entities/EDocumentType.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Domain.Entities +namespace Domain.Entities { public class EDocumentType { diff --git a/Models/Helpers/EntityMapper.cs b/Models/Helpers/EntityMapper.cs new file mode 100644 index 0000000..f085f39 --- /dev/null +++ b/Models/Helpers/EntityMapper.cs @@ -0,0 +1,66 @@ +using System.Collections; +using System.Reflection; + +namespace Models.Helpers +{ + public static class EntityMapper + { + public static TDestination MapEntity(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); + } + } + + return destination; + } + + 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<>)); + } + } +} diff --git a/Models/Interfaces/IGenericRepository.cs b/Models/Interfaces/IGenericRepository.cs deleted file mode 100644 index 0504645..0000000 --- a/Models/Interfaces/IGenericRepository.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Models.Interfaces -{ - public interface IGenericRepository where T : class - { - Task GetByIdAsync(int id); - Task> GetAllAsync(); - Task AddAsync(T entity); - void Update(T entity); - void Delete(T entity); - } -} diff --git a/Models/Models/PhSDocumentType.cs b/Models/Models/PhSDocumentType.cs index 511ea3f..ae03306 100644 --- a/Models/Models/PhSDocumentType.cs +++ b/Models/Models/PhSDocumentType.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections.Generic; - -namespace Models.Models; +namespace Models.Models; public partial class PhSDocumentType { diff --git a/Models/Repositories/PhSAccountTypeRepository.cs b/Models/Repositories/PhSAccountTypeRepository.cs index 30fd3f5..09c6e34 100644 --- a/Models/Repositories/PhSAccountTypeRepository.cs +++ b/Models/Repositories/PhSAccountTypeRepository.cs @@ -1,5 +1,6 @@ using Domain.Entities; using Microsoft.EntityFrameworkCore; +using Models.Helpers; using Models.Interfaces; using Models.Models; @@ -14,25 +15,13 @@ namespace Models.Repositories public async Task> GetAllAsync() { var accountTypes = await _context.PhSAccountTypes.ToListAsync(); - return accountTypes.Select(at => MapEntity(at)); + return accountTypes.Select(EntityMapper.MapEntity); } public async Task GetByNameAsync(string name) { var accountType = await _context.PhSAccountTypes.FirstOrDefaultAsync(a => a.Name.Contains(name)); - return accountType != null ? MapEntity(accountType) : null; - } - #endregion - #region Métodos Auxiliares - private static TDestination MapEntity(TSource source) where TDestination : new() - { - var destination = new TDestination(); - foreach (var propertyInfo in typeof(TSource).GetProperties()) - { - var value = propertyInfo.GetValue(source); - typeof(TDestination).GetProperty(propertyInfo.Name)?.SetValue(destination, value); - } - return destination; + return accountType != null ? EntityMapper.MapEntity(accountType) : null; } #endregion } diff --git a/Models/Repositories/PhSDocumentTypeRepository.cs b/Models/Repositories/PhSDocumentTypeRepository.cs index c4d5e29..1564617 100644 --- a/Models/Repositories/PhSDocumentTypeRepository.cs +++ b/Models/Repositories/PhSDocumentTypeRepository.cs @@ -1,5 +1,6 @@ using Domain.Entities; using Microsoft.EntityFrameworkCore; +using Models.Helpers; using Models.Interfaces; using Models.Models; @@ -14,26 +15,14 @@ namespace Models.Repositories public async Task> GetAllAsync() { var documentTypes = await _context.PhSDocumentTypes.ToListAsync(); - return documentTypes.Select(at => MapEntity(at)); + return documentTypes.Select(EntityMapper.MapEntity); } - public async Task GetByNameAsync(string name) { var documentType = await _context.PhSDocumentTypes.FirstOrDefaultAsync(a => a.Name.Contains(name)); - return documentType != null ? MapEntity(documentType) : null; - } - #endregion - #region Métodos Auxiliares - private static TDestination MapEntity(TSource source) where TDestination : new() - { - var destination = new TDestination(); - foreach (var propertyInfo in typeof(TSource).GetProperties()) - { - var value = propertyInfo.GetValue(source); - typeof(TDestination).GetProperty(propertyInfo.Name)?.SetValue(destination, value); - } - return destination; + return documentType != null ? EntityMapper.MapEntity(documentType) : null; } #endregion + } }