Ejemplo n.º 1
0
        /// <summary>
        /// Crea un' entita dato un Dto
        /// </summary>
        /// <param name="dtoToConvertInEntity">il dto che deve essere convertito in entita</param>
        /// <param name="ignoreId">indica se durante il mapping di ignorare la proprietà ID. in caso di true, non viene copiato l'id del dto nell' id dell' entità</param>
        /// <param name="convertToEntityTypeAsResult">il tipo di ritorno dell' entità</param>
        /// <param name="objectFromRepositoryToUpdate">Indica l' entità su cui si vuole fare l'update, invece di crearne una nuova.</param>
        /// <returns>Torna l'entità mappata secondo il dto. Se la prop objectFromRepositoryToUpdate è stata specificata,
        ///  allora torna objectFromRepositoryToUpdate con tutte le proprietà aggiornate come indicato nel dto.
        /// </returns>
        private object RecursivelyCreateEntityFromDto(object dtoToConvertInEntity, bool ignoreId, Type convertToEntityTypeAsResult, object objectFromRepositoryToUpdate = null)
        {
            if (dtoToConvertInEntity == null)
            {
                return(null);
            }

            Type dtoType = dtoToConvertInEntity.GetType();

            RegisterKnowMapping(dtoType, convertToEntityTypeAsResult);


            object result;

            if (objectFromRepositoryToUpdate == null)
            {
                result = Activator.CreateInstance(convertToEntityTypeAsResult);
            }
            else
            {
                result = objectFromRepositoryToUpdate;
            }

            foreach (var mapping in GetRegistedMapping(dtoType))
            {
                if (mapping.DtoMapToEntityProperty.EntityPropertyNameToMap.Equals("Id"))
                {
                    if (ignoreId)
                    {
                        continue;
                    }
                }
                if (!mapping.DtoMapToEntityProperty.ConvertToEntity)
                {
                    continue;
                }

                try
                {
                    // prendo l' istanza presente nella proprietà corrente del dto da convertire
                    // entityToConvertInDto.GetType().InvokeMember(mapping.DtoMapToEntityProperty.EntityPropertyNameToMap, BindingFlags.GetProperty, null, entityToConvertInDto, null);
                    var pIstanceDtoPropertyValue = mapping.DtoPropertyInfo.GetValue(dtoToConvertInEntity, null);
                    if (pIstanceDtoPropertyValue == null)
                    {
                        continue;
                    }
                    var pIstanceDtoPropertyValueType = pIstanceDtoPropertyValue.GetType();
                    // se è un IList<T>

                    if (mapping.DtoMapToEntityProperty.HasConvertChildsUsingConcreteClassSpecified())
                    {
                        IList       entityAsList = CreateIstanceFromGenericListType(mapping.EntityPropertyInfo.PropertyType);
                        IEnumerable dtoAsList    = pIstanceDtoPropertyValue as IEnumerable;
                        foreach (var dto in dtoAsList)
                        {
                            var entiityToAddToCollection = RecursivelyCreateEntityFromDto(dto, ignoreId, entityAsList.GetType().GetGenericArguments()[0]);
                            entityAsList.Add(entiityToAddToCollection);
                        }
                        if (mapping.DtoMapToEntityProperty.HasAddChildsToEntityUsingMethodSpecified())
                        {
                            mapping.EntityPropertyInfo.DeclaringType.InvokeMember(mapping.DtoMapToEntityProperty.EntityMethodToInvokeToAddChilds, BindingFlags.InvokeMethod, null, result, new[] { entityAsList });
                        }

                        else
                        {
                            mapping.EntityPropertyInfo.SetValue(result, entityAsList, null);
                        }
                    }
                    else
                    {
                        if (pIstanceDtoPropertyValueType.IsGenericType)
                        {
                            ThrowDtoToEntityMappingException(String.Format("Dto property {0} is a generic type of {1}. Only IList<T> generics are supported.",
                                                                           mapping.DtoMapToEntityProperty.EntityPropertyNameToMap, pIstanceDtoPropertyValueType.Name));
                        }

                        // non ha miolto senso usare i resolvers se ha indicato quelsta prop
                        // deve piuttosto controllare se è presente l' associazione Entity.PropEntity con Dto.PropDto
                        if (_knowEntityResolver.Contains(mapping.EntityRegisterdResolverName) && _knowEntityResolverMappings.ContainsKey(mapping.DtoRegisterdResolverName))
                        //if (mapping.DtoMapToEntityProperty.HasEntityPropertyToInvoke())
                        {
                            var aa = GetEntityUsingKnownResolver(dtoToConvertInEntity, mapping);
                            mapping.EntityPropertyInfo.SetValue(result, aa, null);
                        }
                        else
                        {
                            // vediamo se cè gia un resolver per questa proprietà.
                            // nel caso è presente, salto questo passaggio, perche verra fatto dal resolver
                            if (!_knowEntityResolver.Contains(mapping.EntityRegisterdResolverName))
                            {
                                var pInstanceDto   = mapping.DtoPropertyInfo.GetValue(dtoToConvertInEntity, null);
                                var convertedValue = ConverterManager.ConvertToEntity(pInstanceDto, mapping.DtoMapToEntityProperty.ConvertToDtoMechanism, mapping.EntityPropertyInfo.PropertyType);
                                mapping.EntityPropertyInfo.SetValue(result, convertedValue, null);
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    ThrowDtoToEntityMappingException(String.Format("cannot map DTO {0} into Entity {1}. Check MapToEntityProperty attribute of your Dto. Details: {2}",
                                                                   mapping.DtoPropertyInfo.Name, mapping.DtoMapToEntityProperty.EntityPropertyNameToMap, ex.Message));
                }
            }

            return(result);
        }