diff --git a/AutoMapProperty/AutoMapProperty.cs b/AutoMapProperty/AutoMapProperty.cs index 805ca14..0d1b9a2 100644 --- a/AutoMapProperty/AutoMapProperty.cs +++ b/AutoMapProperty/AutoMapProperty.cs @@ -521,7 +521,12 @@ namespace AutoMapProperty sb.Append(method.ContainingType.ToDisplayString()).Append(".").Append(method.Name); return sb.ToString(); } - public static string GeneratePropertyFrom(List otherClasses, string Key, ITypeSymbol FromType, ITypeSymbol ToType, bool nullable = true, string prefix = "") + + public static string GetProjectorName(ClassToGenerate cls) + { + return cls.Name.ToLower(); + } + public static string GeneratePropertyFrom(List otherClasses, string Key, ITypeSymbol FromType, ITypeSymbol ToType, bool allowProjectors, List? requiredProjectors, bool nullable = true, string prefix = "") { var sb = new StringBuilder(); sb.Append(Key).Append(@" = "); @@ -538,8 +543,18 @@ namespace AutoMapProperty sb.Append(nullable ? "?" : ""); if (!SymbolEqualityComparer.Default.Equals(concreteToType, concreteFromType)) { - sb.Append(@".Select(x => (").Append(GetFullString(concreteToType)).Append(@")x)"); - sb.Append(nullable ? "?" : ""); + var otherCls = otherClasses.FirstOrDefault(x => x.Name == concreteToType.Name); + if (otherCls != null && allowProjectors) + { + sb.Append(@".Select(x => ").Append(GetProjectorName(otherCls)).Append(@".Invoke(x))"); + sb.Append(nullable ? "?" : ""); + requiredProjectors!.Add(otherCls); + } + else + { + sb.Append(@".Select(x => (").Append(GetFullString(concreteToType)).Append(@")x)"); + sb.Append(nullable ? "?" : ""); + } } //Add the appropriate ToHashSet or ToSet or ToCollection or ToList @@ -568,7 +583,7 @@ namespace AutoMapProperty {"); foreach (var prop in classToGenerate.MappableProperties) { - var property = GenerateCorrectFromProperty(otherClasses, prop.Key, prop.Value, false, prefix + "." + Key); + var property = GenerateCorrectFromProperty(otherClasses, prop.Key, prop.Value, allowProjectors, requiredProjectors, false, prefix + "." + Key); if (property == null) continue; @@ -588,11 +603,11 @@ namespace AutoMapProperty return symbol.ToDisplayString(format: displayFormat); } - public static string? GenerateCorrectFromProperty(List otherClasses, string Key, ClassToGenerate.MappableTypes Value, bool nullable = true, string prefix = "") + public static string? GenerateCorrectFromProperty(List otherClasses, string Key, ClassToGenerate.MappableTypes Value, bool allowProjectors, List? requiredProjectors, bool nullable = true, string prefix = "") { if (!Value.CustomFrom) { - return GeneratePropertyFrom(otherClasses, Key, Value.FromType, Value.ToType, nullable, prefix); + return GeneratePropertyFrom(otherClasses, Key, Value.FromType, Value.ToType, allowProjectors, requiredProjectors, nullable, prefix); } else { @@ -604,6 +619,30 @@ namespace AutoMapProperty return sb.ToString(); } } + + private static (string, List) GenerateFromExpression(List otherClasses, ClassToGenerate classToGenerate, SyntaxToken sourceName) + { + var projectors = new List(); + var exprSb = new StringBuilder(); + exprSb.Append(@"System.Linq.Expressions.Expression> expr = (").Append(sourceName).Append(" source)=>new ").Append(classToGenerate.Name).Append(@"() + {"); + foreach (var prop in classToGenerate.MappableProperties) + { + var property = GenerateCorrectFromProperty(otherClasses, prop.Key, prop.Value, true, projectors, false); + if (property == null) + continue; + + exprSb.Append(@" + ").Append(property).Append(@","); + } + exprSb.Append(@" + }; + return expr.Expand(); + "); + + return (exprSb.ToString(), projectors); + } + public static string? GeneratePropertyTo(List otherClasses, string Key, ITypeSymbol FromType, ITypeSymbol ToType, bool nullable = true) { var sb = new StringBuilder(); @@ -685,6 +724,7 @@ namespace AutoMapProperty retSb.Append(";"); return retSb.ToString(); } + public static string? GenerateEqualityOperator(string name, ClassToGenerate.MappableTypes Value, string? prefix = null) { var prefixedName = prefix == null ? name : prefix + "." + name; @@ -735,6 +775,7 @@ namespace AutoMapProperty } sb.Append(@" +using LinqKit; #nullable enable #pragma warning disable CS8600 @@ -789,7 +830,7 @@ namespace ").Append(classToGenerate.Namespace).Append(@" {"); foreach (var prop in classToGenerate.MappableProperties) { - var property = GenerateCorrectFromProperty(otherClasses, prop.Key, prop.Value); + var property = GenerateCorrectFromProperty(otherClasses, prop.Key, prop.Value, false, null); if (property == null) continue; @@ -801,19 +842,19 @@ namespace ").Append(classToGenerate.Namespace).Append(@" return this; }"); sb.Append(@" - public new System.Linq.Expressions.Expression> GetProjectorFrom(System.IServiceProvider providers) => (source)=>new ").Append(classToGenerate.Name).Append(@"() - {"); - foreach (var prop in classToGenerate.MappableProperties) - { - var property = GenerateCorrectFromProperty(otherClasses, prop.Key, prop.Value, false); - if (property == null) - continue; + public new System.Linq.Expressions.Expression> GetProjectorFrom(System.IServiceProvider providers) { + + "); + var (expr, projectors) = GenerateFromExpression(otherClasses, classToGenerate, classToGenerate.SourceContainer.Identifier); - sb.Append(@" - ").Append(property).Append(@","); + foreach (var projector in projectors.Distinct()) + { + sb.Append("var ").Append(GetProjectorName(projector)).Append(@" = new ").Append(projector.Name).Append(@"().GetProjectorFrom(providers); + "); } + sb.Append(expr); sb.Append(@" - };"); + }"); sb.Append(@" public static new System.Linq.Expressions.Expression> EqualExpression(System.IServiceProvider providers,").Append(classToGenerate.SourceContainer.Identifier).Append(@" item1) => (item2)=>