public async Task <IEnumerable <TTargetDto> > LoadListAsync <TTargetDto, TKeyProvider>(IEnumerable <TTargetDto> targetDtos, IEnumerable <TKeyProvider> keyProviders)
            where TTargetDto : class
            where TKeyProvider : class
        {
            var targetDtoType = typeof(TTargetDto);

            var relatedDtoProperties = _profile.GetRelatedDtoProperties(targetDtoType);

            if (relatedDtoProperties == null)
            {
                throw new UnsupportedTargetTypeException(targetDtoType);
            }

            var keyProviderType       = typeof(TKeyProvider);
            var isKeyProviderSameType = targetDtoType == keyProviderType;
            var arrTargetDtos         = targetDtos.ToArray();
            var arrKeyProviders       = keyProviders.ToArray();

            foreach (var relatedDtoProperty in relatedDtoProperties)
            {
                var dtoProperty = relatedDtoProperty.DtoProperty;
                var attribute   = relatedDtoProperty.Attribute;

                var idProperty = isKeyProviderSameType
                    ? relatedDtoProperty.DtoIdProperty
                    : keyProviderType.GetProperty(attribute.IdPropertyName ?? dtoProperty.Name + "Id", BindingFlags.Public | BindingFlags.Instance);

                if (idProperty == null)
                {
                    continue;
                }

                var loaderRule = _profile.GetRule(dtoProperty.PropertyType);

                if (loaderRule == null)
                {
                    continue;
                }

                var keyProviderWithIds = arrKeyProviders.ToDictionary(x => x, dto => idProperty.GetValue(dto));
                var idsToLoad          = keyProviderWithIds.Values.Where(x => x != null).ToArray();

                Dictionary <object, object> dictLoadedDtos = null;

                if (idsToLoad.Any())
                {
                    object[] relatedDtos = (await loaderRule.LoadAsObjectAsync(idsToLoad).ConfigureAwait(false)).ToArray();
                    dictLoadedDtos = relatedDtos.ToDictionary(x => loaderRule.GetKey(x), x => x);
                }

                for (var index = 0; index < arrTargetDtos.Length; index++)
                {
                    var targetDto   = arrTargetDtos[index];
                    var keyProvider = arrKeyProviders[index];

                    object propValue = null;

                    var desiredDtoKey = keyProviderWithIds[keyProvider];

                    if (desiredDtoKey != null)
                    {
                        propValue = GetDesiredDto(desiredDtoKey, dictLoadedDtos);
                    }

                    dtoProperty.SetValue(targetDto, propValue);
                }
            }

            return(arrTargetDtos);
        }
Пример #2
0
        public async Task <IEnumerable <TTargetDto> > LoadListAsync <TTargetDto, TKeyProvider>(IEnumerable <TTargetDto> targetDtos, IEnumerable <TKeyProvider> keyProviders)
            where TTargetDto : class
            where TKeyProvider : class
        {
            var targetDtoType = typeof(TTargetDto);

            var relatedDtoProperties = _profile.GetRelatedDtoProperties(targetDtoType);

            if (relatedDtoProperties == null)
            {
                throw new UnsupportedTargetTypeException(targetDtoType);
            }

            var keyProviderType       = typeof(TKeyProvider);
            var isKeyProviderSameType = targetDtoType == keyProviderType;
            var arrTargetDtos         = targetDtos.ToArray();
            var arrKeyProviders       = keyProviders.ToArray();

            foreach (var relatedProperty in relatedDtoProperties)
            {
                var dtoType     = relatedProperty.DtoType;
                var dtoProperty = dtoType.Property;
                var attribute   = relatedProperty.Attribute;

                RelatedValueType idType = null;

                if (isKeyProviderSameType)
                {
                    idType = relatedProperty.IdType;
                }
                else
                {
                    if (dtoType.GenericType != null || dtoType.IsArray)
                    {
                        throw new MissingIdPropertyNameException(targetDtoType.Name, dtoProperty.Name);
                    }

                    var idProp = keyProviderType.GetProperty(attribute.IdPropertyName ?? dtoProperty.Name + "Id", BindingFlags.Public | BindingFlags.Instance);

                    if (idProp != null)
                    {
                        idType = new RelatedValueType(idProp);
                    }
                }

                if (idType == null)
                {
                    continue;
                }

                var loaderRule = _profile.GetRule(dtoType.ElementType);

                if (loaderRule == null)
                {
                    continue;
                }

                if (dtoType.GenericType != null)
                {
                    await InternalLoadDtoEnumerableAsync(relatedProperty, idType, loaderRule, arrTargetDtos, arrKeyProviders);
                }
                else if (dtoType.IsArray)
                {
                    await InternalLoadDtoArrayAsync(relatedProperty, idType, loaderRule, arrTargetDtos, arrKeyProviders);
                }
                else
                {
                    await InternalLoadDtoAsync(relatedProperty, idType, loaderRule, arrTargetDtos, arrKeyProviders);
                }
            }

            return(arrTargetDtos);
        }