Created
August 14, 2020 18:33
-
-
Save daniframos/fef3c6ea8c9d3f73d37d423120d86a7a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Concurrent; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Reflection; | |
using GASC.Dados; | |
namespace GASC.Negocio.Util | |
{ | |
public static class Mapeador | |
{ | |
private static readonly ConcurrentDictionary<Type, PropertyInfo[]> CacheDictionary; | |
static Mapeador() | |
{ | |
CacheDictionary = new ConcurrentDictionary<Type, PropertyInfo[]>(); | |
} | |
private static PropertyInfo[] GetPropriedadesDoCache(Type type) | |
{ | |
if (CacheDictionary.ContainsKey(type)) | |
{ | |
return CacheDictionary[type]; | |
} | |
PropertyInfo[] propriedades = type.GetProperties(); | |
CacheDictionary.TryAdd(type, propriedades); | |
return propriedades; | |
} | |
/// <summary> | |
/// Mapea Enumerable. Está com constraint para class | |
/// Refatorar para adicionar isto ao mapeador e ser recursivo | |
/// </summary> | |
/// <typeparam name="TOrigem"></typeparam> | |
/// <typeparam name="TDestino"></typeparam> | |
/// <param name="listaOrigem"></param> | |
/// <returns></returns> | |
public static IEnumerable<TDestino> MapearEnumerable<TOrigem, TDestino>(IEnumerable<TOrigem> listaOrigem) | |
where TDestino : class, new() | |
where TOrigem : class | |
{ | |
return MapearEnumerable<TOrigem, TDestino>(listaOrigem, null); | |
} | |
public static IEnumerable<TDestino> MapearEnumerable<TOrigem, TDestino>(IEnumerable<TOrigem> listaOrigem, | |
Action<TDestino, TOrigem> customMapeador) | |
where TDestino : class, new() | |
where TOrigem : class | |
{ | |
var resultado = new List<TDestino>(); | |
foreach (TOrigem itemOrigem in listaOrigem) | |
{ | |
TDestino tmp = MapearPara<TOrigem, TDestino>(itemOrigem); | |
customMapeador?.Invoke(tmp, itemOrigem); | |
resultado.Add(tmp); | |
} | |
return resultado; | |
} | |
/// <summary> | |
/// Mapea uma lista paginada para uma lista paginada de DTO | |
/// </summary> | |
/// <typeparam name="T"></typeparam> | |
/// <typeparam name="TOrigem"></typeparam> | |
/// <param name="origem"></param> | |
/// <returns></returns> | |
public static ListaPaginada<T> MapearListaPaginadaParaDTO<T, TOrigem>(ListaPaginada<TOrigem> origem) | |
where T : class, new() | |
where TOrigem : class | |
{ | |
ListaPaginada<T> destino = MapearPara<ListaPaginada<TOrigem>, ListaPaginada<T>>(origem); | |
foreach (TOrigem resultado in origem.Resultado) | |
{ | |
T tmp = MapearPara<TOrigem, T>(resultado); | |
destino.Resultado.Add(tmp); | |
} | |
return destino; | |
} | |
public static TResultado MapearPara<TOrigem, TResultado>(TOrigem origem) | |
where TResultado : class, new() | |
where TOrigem : class | |
{ | |
if (origem == null) return null; | |
PropertyInfo[] propriedadesOrigem = GetPropriedadesDoCache(typeof (TOrigem)); | |
PropertyInfo[] propriedadesDestino = GetPropriedadesDoCache(typeof (TResultado)); | |
var resultado = new TResultado(); | |
foreach (PropertyInfo propDestino in propriedadesDestino) | |
{ | |
//#if DEBUG | |
// var isMapeada = false; | |
//#endif | |
PropertyInfo propriedadeEncontradaNaOrigem = | |
propriedadesOrigem.FirstOrDefault( | |
p => string.Compare(p.Name, propDestino.Name, StringComparison.InvariantCultureIgnoreCase) == 0); | |
PropertyInfo propriedadeEncontradaNoDestino = | |
propriedadesDestino.FirstOrDefault( | |
p => string.Compare(p.Name, propDestino.Name, StringComparison.InvariantCultureIgnoreCase) == 0); | |
if (propriedadeEncontradaNoDestino != null && propriedadeEncontradaNaOrigem != null) | |
{ | |
if (!propriedadeEncontradaNoDestino.CanWrite) continue; | |
if (propriedadeEncontradaNaOrigem.PropertyType.IsAssignableFrom(propDestino.PropertyType)) | |
{ | |
object valor = propriedadeEncontradaNaOrigem.GetValue(origem, null); | |
propDestino.SetValue(resultado, valor, null); | |
//#if DEBUG | |
// isMapeada = true; | |
//#endif | |
} | |
else if (propriedadeEncontradaNoDestino.PropertyType.IsGenericType && | |
propriedadeEncontradaNoDestino.PropertyType.GetGenericTypeDefinition() == | |
typeof (Nullable<>)) | |
{ | |
Type nullableType = | |
Nullable.GetUnderlyingType(propriedadeEncontradaNaOrigem.PropertyType) ?? | |
propriedadeEncontradaNaOrigem.PropertyType; | |
if (nullableType == propriedadeEncontradaNaOrigem.PropertyType) | |
{ | |
object valor = propriedadeEncontradaNaOrigem.GetValue(origem, null); | |
propDestino.SetValue(resultado, valor, null); | |
//#if DEBUG | |
// isMapeada = true; | |
//#endif | |
} | |
//#if DEBUG | |
// isMapeada = true; | |
//#endif | |
} | |
} | |
//#if DEBUG | |
// if (!isMapeada) | |
// Debug.WriteLine("ATENÇÃO: Propriedade {0} do tipo {1} não mapeada".ToUpperInvariant(), propDestino.Name, typeof(TResultado).Name); | |
//#endif | |
} | |
return resultado; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment