diff --git a/src/MapTo/MapTo.csproj b/src/MapTo/MapTo.csproj index c229ebf..21d8219 100644 --- a/src/MapTo/MapTo.csproj +++ b/src/MapTo/MapTo.csproj @@ -43,5 +43,9 @@ + + + + diff --git a/src/MapTo/Sources/MapClassSource.cs b/src/MapTo/Sources/MapClassSource.cs index edde823..21c94de 100644 --- a/src/MapTo/Sources/MapClassSource.cs +++ b/src/MapTo/Sources/MapClassSource.cs @@ -33,6 +33,7 @@ namespace MapTo.Sources .GeneratePrivateConstructor(model) .WriteLine() .GenerateFactoryMethod(model) + .GenerateUpdateMethod(model) // End class declaration .WriteClosingBracket() @@ -80,19 +81,29 @@ namespace MapTo.Sources .WriteLine($"if ({sourceClassParameterName} == null) throw new ArgumentNullException(nameof({sourceClassParameterName}));") .WriteLine() .WriteLine($"{mappingContextParameterName}.{MappingContextSource.RegisterMethodName}({sourceClassParameterName}, this);") - .WriteLine(); + .WriteLine(). + WriteProperties( model, sourceClassParameterName, mappingContextParameterName); + + // End constructor declaration + return builder.WriteClosingBracket(); + } + + private static SourceBuilder WriteProperties(this SourceBuilder builder, MappingModel model, + string? sourceClassParameterName, string mappingContextParameterName) + { foreach (var property in model.MappedProperties) { if (property.TypeConverter is null) { if (property.IsEnumerable) { - builder.WriteLine($"{property.Name} = {sourceClassParameterName}.{property.SourcePropertyName}.Select({mappingContextParameterName}.{MappingContextSource.MapMethodName}<{property.MappedSourcePropertyTypeName}, {property.EnumerableTypeArgument}>).ToList();"); + builder.WriteLine( + $"{property.Name} = {sourceClassParameterName}.{property.SourcePropertyName}.Select({mappingContextParameterName}.{MappingContextSource.MapMethodName}<{property.MappedSourcePropertyTypeName}, {property.EnumerableTypeArgument}>).ToList();"); } else { - builder.WriteLine(property.MappedSourcePropertyTypeName is null + builder.WriteLine(property.MappedSourcePropertyTypeName is null ? $"{property.Name} = {sourceClassParameterName}.{property.SourcePropertyName};" : $"{property.Name} = {mappingContextParameterName}.{MappingContextSource.MapMethodName}<{property.MappedSourcePropertyTypeName}, {property.Type}>({sourceClassParameterName}.{property.SourcePropertyName});"); } @@ -103,14 +114,15 @@ namespace MapTo.Sources ? "null" : $"new object[] {{ {string.Join(", ", property.TypeConverterParameters)} }}"; - builder.WriteLine($"{property.Name} = new {property.TypeConverter}().Convert({sourceClassParameterName}.{property.SourcePropertyName}, {parameters});"); + builder.WriteLine( + $"{property.Name} = new {property.TypeConverter}().Convert({sourceClassParameterName}.{property.SourcePropertyName}, {parameters});"); } - } - // End constructor declaration - return builder.WriteClosingBracket(); + } + return builder; + } - + private static SourceBuilder GenerateFactoryMethod(this SourceBuilder builder, MappingModel model) { var sourceClassParameterName = model.SourceTypeIdentifierName.ToCamelCase(); @@ -124,6 +136,20 @@ namespace MapTo.Sources .WriteClosingBracket(); } + private static SourceBuilder GenerateUpdateMethod(this SourceBuilder builder, MappingModel model) + { + var sourceClassParameterName = model.SourceTypeIdentifierName.ToCamelCase(); + + builder + .GenerateUpdaterMethodsXmlDocs(model, sourceClassParameterName) + .WriteLine($"public void {model.Options.NullableReferenceSyntax}Update({model.SourceType}{model.Options.NullableReferenceSyntax} {sourceClassParameterName})") + .WriteOpeningBracket() + .WriteProperties( model, sourceClassParameterName,"context" ) + .WriteClosingBracket(); + + return builder; + } + private static SourceBuilder GenerateConvertorMethodsXmlDocs(this SourceBuilder builder, MappingModel model, string sourceClassParameterName) { if (!model.Options.GenerateXmlDocument) @@ -139,6 +165,21 @@ namespace MapTo.Sources .WriteLine($"/// The instance of to use as source.") .WriteLine($"/// A new instance of -or- null if is null."); } + + private static SourceBuilder GenerateUpdaterMethodsXmlDocs(this SourceBuilder builder, MappingModel model, string sourceClassParameterName) + { + if (!model.Options.GenerateXmlDocument) + { + return builder; + } + + return builder + .WriteLine("/// ") + .WriteLine($"/// Updates and sets its participating properties") + .WriteLine($"/// using the property values from .") + .WriteLine("/// ") + .WriteLine($"/// The instance of to use as source."); + } private static SourceBuilder GenerateSourceTypeExtensionClass(this SourceBuilder builder, MappingModel model) { diff --git a/src/MapTo/Sources/MapRecordSource.cs b/src/MapTo/Sources/MapRecordSource.cs index c2988c0..3605000 100644 --- a/src/MapTo/Sources/MapRecordSource.cs +++ b/src/MapTo/Sources/MapRecordSource.cs @@ -32,6 +32,7 @@ namespace MapTo.Sources builder .GeneratePrivateConstructor(model) + .WriteLine() .GenerateFactoryMethod(model) @@ -41,6 +42,7 @@ namespace MapTo.Sources // Extension class declaration .GenerateSourceTypeExtensionClass(model) + // End namespace declaration .WriteClosingBracket(); @@ -75,8 +77,25 @@ namespace MapTo.Sources builder .WriteLine($"private protected {model.TypeIdentifierName}({MappingContextSource.ClassName} {mappingContextParameterName}, {model.SourceType} {sourceClassParameterName})") .Indent() - .Write(": this("); + .Write(": this("). + WriteProperties(model, sourceClassParameterName, mappingContextParameterName) + + .WriteLine(")") + .Unindent() + .WriteOpeningBracket() + .WriteLine($"if ({mappingContextParameterName} == null) throw new ArgumentNullException(nameof({mappingContextParameterName}));") + .WriteLine($"if ({sourceClassParameterName} == null) throw new ArgumentNullException(nameof({sourceClassParameterName}));") + .WriteLine() + .WriteLine($"{mappingContextParameterName}.{MappingContextSource.RegisterMethodName}({sourceClassParameterName}, this);"); + + // End constructor declaration + return builder.WriteClosingBracket(); + } + + private static SourceBuilder WriteProperties(this SourceBuilder builder, MappingModel model, string sourceClassParameterName, + string mappingContextParameterName) + { for (var i = 0; i < model.MappedProperties.Length; i++) { var property = model.MappedProperties[i]; @@ -100,7 +119,8 @@ namespace MapTo.Sources ? "null" : $"new object[] {{ {string.Join(", ", property.TypeConverterParameters)} }}"; - builder.Write($"{property.Name}: new {property.TypeConverter}().Convert({sourceClassParameterName}.{property.SourcePropertyName}, {parameters})"); + builder.Write( + $"{property.Name}: new {property.TypeConverter}().Convert({sourceClassParameterName}.{property.SourcePropertyName}, {parameters})"); } if (i < model.MappedProperties.Length - 1) @@ -109,16 +129,7 @@ namespace MapTo.Sources } } - builder.WriteLine(")") - .Unindent() - .WriteOpeningBracket() - .WriteLine($"if ({mappingContextParameterName} == null) throw new ArgumentNullException(nameof({mappingContextParameterName}));") - .WriteLine($"if ({sourceClassParameterName} == null) throw new ArgumentNullException(nameof({sourceClassParameterName}));") - .WriteLine() - .WriteLine($"{mappingContextParameterName}.{MappingContextSource.RegisterMethodName}({sourceClassParameterName}, this);"); - - // End constructor declaration - return builder.WriteClosingBracket(); + return builder; } private static SourceBuilder GenerateFactoryMethod(this SourceBuilder builder, MappingModel model) diff --git a/version.json b/version.json index 1d0f172..48fd80f 100644 --- a/version.json +++ b/version.json @@ -1,6 +1,6 @@ { "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", - "version": "0.7", + "version": "0.8", "semVer1NumericIdentifierPadding": 1, "publicReleaseRefSpec": [ "^refs/heads/master$",