Пример #1
0
        private void AppendPropertyAssign(string sourceRefrenceName, string targetRefrenceName, string lineSplitChar, ConvertContext convertContext)
        {
            var mappingInfo = convertContext.MappingInfo;
            var codeBuilder = convertContext.CodeBuilder;
            var targetProps = mappingInfo.TargetType.GetAllMembers()
                              .OfType <IPropertySymbol>()
                              .Where(p => !p.IsReadOnly && p.CanBeReferencedByName && !p.IsStatic && !p.IsIndexer)
                              .Select(p => new { p.Name, Type = p.Type })
                              .ToLookup(p => p.Name)
                              .ToDictionary(p => p.Key, p => p.First().Type);
            var sourceProps = mappingInfo.SourceType.GetAllMembers()
                              .OfType <IPropertySymbol>()
                              .Where(p => p.CanBeReferencedByName && !p.IsStatic && !p.IsIndexer && !p.IsWriteOnly)
                              .Select(p => new { p.Name, Type = p.Type })
                              .ToLookup(p => p.Name)
                              .ToDictionary(p => p.Key, p => p.First().Type);

            foreach (var prop in targetProps)
            {
                if (mappingInfo.IgnoreTargetProperties != null && mappingInfo.IgnoreTargetProperties.Contains(prop.Key))
                {
                    continue;
                }
                if (mappingInfo.CustomerMappings != null && mappingInfo.CustomerMappings.TryGetValue(prop.Key, out var sourceExpression))
                {
                    var actualSourceExpression = sourceExpression.Replace("$", sourceRefrenceName);
                    codeBuilder.AppendCodeLines($"{FormatRefrence(targetRefrenceName, prop.Key)} = {actualSourceExpression}{lineSplitChar}");
                }
                else if (sourceProps.TryGetValue(prop.Key, out var sourcePropType))
                {
                    if (CanAssign(sourcePropType, prop.Value, convertContext))
                    {
                        // default
                        codeBuilder.AppendCodeLines($"{FormatRefrence(targetRefrenceName, prop.Key)} = {FormatRefrence(sourceRefrenceName, prop.Key)}{lineSplitChar}");
                    }
                    else if (CanMappingCollectionProperty(sourcePropType, prop.Value, convertContext))
                    {
                        // collection
                        var newConvertContext = convertContext.Fork(sourcePropType, prop.Value);
                        MappingCollectionProperty(newConvertContext, sourceRefrenceName, targetRefrenceName, prop.Key, lineSplitChar);
                    }
                    else if (CanMappingSubObjectProperty(sourcePropType, prop.Value, convertContext))
                    {
                        // sub object
                        var newConvertContext = convertContext.Fork(sourcePropType, prop.Value);
                        MappingSubObjectProperty(newConvertContext, sourceRefrenceName, targetRefrenceName, prop.Key, lineSplitChar);
                    }
                }
            }
        }
Пример #2
0
        private void MappingCollectionProperty(ConvertContext convertContext,
                                               string sourceRefrenceName, string targetRefrenceName, string propertyName, string lineSplitChar)
        {
            var codeBuilder        = convertContext.CodeBuilder;
            var targetPropertyType = convertContext.MappingInfo.TargetType;
            var sourcePropertyType = convertContext.MappingInfo.SourceType;
            var targetItemType     = GetItemType(targetPropertyType);
            var sourceItemType     = GetItemType(sourcePropertyType);
            var targetItemTypeText = targetItemType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);

            var targetPropertyExpression = FormatRefrence(targetRefrenceName, propertyName);
            var sourcePropertyExpression = FormatRefrence(sourceRefrenceName, propertyName);

            if (sourceItemType.SafeEquals(targetItemType))
            {
                codeBuilder.AppendCodeLines($"{targetPropertyExpression} = {sourcePropertyExpression} == null ? null : {sourcePropertyExpression}.{ToTargetMethodName()}(){lineSplitChar}");
            }
            else if (CanAssign(sourceItemType, targetItemType, convertContext))
            {
                codeBuilder.AppendCodeLines($"{targetPropertyExpression} = {sourcePropertyExpression} == null ? null : {sourcePropertyExpression}.Cast<{targetItemTypeText}>().{ToTargetMethodName()}(){lineSplitChar}");
            }
            else
            {
                if (sourceItemType.IsValueType)
                {
                    codeBuilder.AppendCodeLines($"{targetPropertyExpression} = {sourcePropertyExpression} == null ? null : {sourcePropertyExpression}.Select(p => new {targetItemTypeText}");
                }
                else
                {
                    codeBuilder.AppendCodeLines($"{targetPropertyExpression} = {sourcePropertyExpression} == null ? null : {sourcePropertyExpression}.Select(p => p == null ? default({targetItemTypeText}) : new {targetItemTypeText}");
                }
                codeBuilder.BeginSegment();
                var newConvertContext = convertContext.Fork(sourceItemType, targetItemType);
                AppendPropertyAssign("p", null, ",", newConvertContext);
                codeBuilder.EndSegment("})." + $"{ToTargetMethodName()}(){lineSplitChar}");
            }

            string ToTargetMethodName()
            {
                if (targetPropertyType is IArrayTypeSymbol arrayTypeSymbol)
                {
                    return(nameof(Enumerable.ToArray));
                }

                if ((targetPropertyType as INamedTypeSymbol).ConstructUnboundGenericType()
                    .SafeEquals(typeof(IQueryable <>)))
                {
                    return(nameof(Queryable.AsQueryable));
                }

                return(nameof(Enumerable.ToList));
            }
        }