private object RecursivelyCreateDtoFromEntity(object entityToConvertInDto, bool ignoreId, Type convertToDtoTypeAsResult) { if (entityToConvertInDto == null) { return(null); } RegisterKnowMapping(convertToDtoTypeAsResult, entityToConvertInDto.GetType()); var result = Activator.CreateInstance(convertToDtoTypeAsResult); foreach (var mapping in GetRegistedMapping(convertToDtoTypeAsResult)) { if (mapping.DtoMapToEntityProperty.EntityPropertyNameToMap.Equals("Id")) { if (ignoreId) { continue; } } if (!mapping.DtoMapToEntityProperty.ConvertToDto) { continue; } try { // prendo l' istanza presente nella proprietà corrente dell' entità da convertire var pIstanceEntityPropertyValue = mapping.EntityPropertyInfo.GetValue(entityToConvertInDto, null); //var pIstancePropertyValue = entityToConvertInDto.GetType().InvokeMember(mapping.DtoMapToEntityProperty.EntityPropertyNameToMap, BindingFlags.GetProperty, null, entityToConvertInDto, null); if (pIstanceEntityPropertyValue == null) { continue; } var pIstanceEntityPropertyValueType = pIstanceEntityPropertyValue.GetType(); //... se è un generic... ed IList<IDto> che indica una relazione padre figlio 1;n ... vediamo se IList<T> oppure semplicmente un generic if (IsAnIListOfGenericSpecification(pIstanceEntityPropertyValueType)) { var dtoAsList = CreateIstanceFromGenericListType(mapping.DtoPropertyInfo.PropertyType); // e ci aggiungo i figli var istanceAsList = pIstanceEntityPropertyValue as IEnumerable; foreach (var item in istanceAsList) { var dtoToAddToCollection = RecursivelyCreateDtoFromEntity(item, ignoreId, mapping.DtoMapToEntityProperty.GetTypeToUseFromMapToEntityProperty(convertToDtoTypeAsResult.Assembly)); dtoAsList.Add(dtoToAddToCollection); } mapping.DtoPropertyInfo.SetValue(result, dtoAsList, null); } else { if (pIstanceEntityPropertyValueType.IsGenericType) { ThrowEntityToDtoMappingException(String.Format("Entity property {0} is a generic type of {1}. Only IList<T> generics are supported.", mapping.DtoMapToEntityProperty.EntityPropertyNameToMap, pIstanceEntityPropertyValueType.Name)); } if (mapping.DtoMapToEntityProperty.HasEntityPropertyToInvoke()) { object propertyValue = pIstanceEntityPropertyValueType.InvokeMember(mapping.DtoMapToEntityProperty.EntityPropertyToInvoke, BindingFlags.GetProperty, null, pIstanceEntityPropertyValue, null); mapping.DtoPropertyInfo.SetValue(result, propertyValue, null); } else { var convertedValue = ConverterManager.ConvertToDto(pIstanceEntityPropertyValue, mapping.DtoMapToEntityProperty.ConvertToDtoMechanism, mapping.DtoPropertyInfo.PropertyType); mapping.DtoPropertyInfo.SetValue(result, convertedValue, null); } } } catch (Exception ex) { ThrowEntityToDtoMappingException(String.Format("cannot map Entity {0} into DTO {1}. A generic error occured!. Check MapToEntityProperty attribute of your Dto. Details: {2}", mapping.DtoMapToEntityProperty.EntityPropertyNameToMap, mapping.DtoPropertyInfo.Name, ex.Message)); } } return(result); }