Add MapProperty attribute.
This commit is contained in:
parent
e9e44b979a
commit
ec21abcf0e
|
@ -35,7 +35,7 @@ namespace MapTo.Extensions
|
|||
|
||||
internal static string GetBuildPropertyName(string propertyName) => $"build_property.{PropertyNameSuffix}{propertyName}";
|
||||
|
||||
internal static void AddSource(this GeneratorExecutionContext context, Source source) =>
|
||||
context.AddSource(source.HintName, source.Code);
|
||||
internal static void AddSource(this GeneratorExecutionContext context, SourceCode sourceCode) =>
|
||||
context.AddSource(sourceCode.HintName, sourceCode.Text);
|
||||
}
|
||||
}
|
|
@ -25,6 +25,7 @@ namespace MapTo
|
|||
context.AddSource(MapFromAttributeSource.Generate(options));
|
||||
context.AddSource(IgnorePropertyAttributeSource.Generate(options));
|
||||
context.AddSource(TypeConverterSource.Generate(options));
|
||||
context.AddSource(MapPropertyAttributeSource.Generate(options));
|
||||
|
||||
if (context.SyntaxReceiver is MapToSyntaxReceiver receiver && receiver.CandidateClasses.Any())
|
||||
{
|
||||
|
|
|
@ -7,7 +7,7 @@ namespace MapTo.Sources
|
|||
{
|
||||
internal const string AttributeName = "IgnoreProperty";
|
||||
|
||||
internal static Source Generate(SourceGenerationOptions options)
|
||||
internal static SourceCode Generate(SourceGenerationOptions options)
|
||||
{
|
||||
var builder = new SourceBuilder()
|
||||
.WriteLine(GeneratedFilesHeader)
|
||||
|
|
|
@ -6,7 +6,7 @@ namespace MapTo.Sources
|
|||
{
|
||||
internal static class MapClassSource
|
||||
{
|
||||
internal static Source Generate(MapModel model)
|
||||
internal static SourceCode Generate(MapModel model)
|
||||
{
|
||||
using var builder = new SourceBuilder()
|
||||
.WriteLine(GeneratedFilesHeader)
|
||||
|
|
|
@ -7,7 +7,7 @@ namespace MapTo.Sources
|
|||
{
|
||||
internal const string AttributeName = "MapFrom";
|
||||
|
||||
internal static Source Generate(SourceGenerationOptions options)
|
||||
internal static SourceCode Generate(SourceGenerationOptions options)
|
||||
{
|
||||
using var builder = new SourceBuilder()
|
||||
.WriteLine(GeneratedFilesHeader)
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
using MapTo.Models;
|
||||
using static MapTo.Sources.Constants;
|
||||
|
||||
namespace MapTo.Sources
|
||||
{
|
||||
internal static class MapPropertyAttributeSource
|
||||
{
|
||||
internal const string AttributeName = "MapProperty";
|
||||
|
||||
internal static SourceCode Generate(SourceGenerationOptions options)
|
||||
{
|
||||
using var builder = new SourceBuilder()
|
||||
.WriteLine(GeneratedFilesHeader)
|
||||
.WriteLine("using System;")
|
||||
.WriteLine()
|
||||
.WriteLine($"namespace {RootNamespace}")
|
||||
.WriteOpeningBracket();
|
||||
|
||||
if (options.GenerateXmlDocument)
|
||||
{
|
||||
builder
|
||||
.WriteLine("/// <summary>")
|
||||
.WriteLine("/// Maps a property to property of another object.")
|
||||
.WriteLine("/// </summary>");
|
||||
}
|
||||
|
||||
builder
|
||||
.WriteLine("[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]")
|
||||
.WriteLine($"public sealed class {AttributeName}Attribute : Attribute")
|
||||
.WriteOpeningBracket();
|
||||
|
||||
if (options.GenerateXmlDocument)
|
||||
{
|
||||
builder
|
||||
.WriteLine("/// <summary>")
|
||||
.WriteLine("/// Initializes a new instance of <see cref=\"MapPropertyAttribute\"/>.")
|
||||
.WriteLine("/// </summary>")
|
||||
.WriteLine("/// <param name=\"converter\">The <see cref=\"ITypeConverter{TSource,TDestination}\" /> to convert the value of the annotated property.</param>");
|
||||
}
|
||||
|
||||
builder
|
||||
.WriteLine($"public {AttributeName}Attribute(Type converter = null)")
|
||||
.WriteOpeningBracket()
|
||||
.WriteLine("Converter = converter;")
|
||||
.WriteClosingBracket()
|
||||
.WriteLine();
|
||||
|
||||
if (options.GenerateXmlDocument)
|
||||
{
|
||||
builder
|
||||
.WriteLine("/// <summary>")
|
||||
.WriteLine("/// Gets the <see cref=\"ITypeConverter{TSource,TDestination}\" /> to convert the value of the annotated property.")
|
||||
.WriteLine("/// </summary>");
|
||||
}
|
||||
|
||||
builder
|
||||
.WriteLine("public Type Converter { get; }")
|
||||
.WriteClosingBracket()
|
||||
.WriteClosingBracket();
|
||||
|
||||
return new(builder.ToString(), $"{AttributeName}Attribute.g.cs");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
namespace MapTo.Sources
|
||||
{
|
||||
internal record Source(string Code, string HintName);
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
namespace MapTo.Sources
|
||||
{
|
||||
internal record SourceCode(string Text, string HintName);
|
||||
}
|
|
@ -7,7 +7,7 @@ namespace MapTo.Sources
|
|||
{
|
||||
internal const string InterfaceName = "ITypeConverter";
|
||||
|
||||
internal static Source Generate(SourceGenerationOptions options)
|
||||
internal static SourceCode Generate(SourceGenerationOptions options)
|
||||
{
|
||||
using var builder = new SourceBuilder()
|
||||
.WriteLine(GeneratedFilesHeader)
|
||||
|
|
|
@ -512,5 +512,37 @@ namespace MapTo
|
|||
diagnostics.ShouldBeSuccessful();
|
||||
compilation.SyntaxTrees.ShouldContainSource(TypeConverterSource.InterfaceName, expectedInterface);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void VerifyMapPropertyAttribute()
|
||||
{
|
||||
// Arrange
|
||||
const string source = "";
|
||||
var expectedInterface = $@"
|
||||
{Constants.GeneratedFilesHeader}
|
||||
using System;
|
||||
|
||||
namespace MapTo
|
||||
{{
|
||||
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
|
||||
public sealed class MapPropertyAttribute : Attribute
|
||||
{{
|
||||
public MapPropertyAttribute(Type converter = null)
|
||||
{{
|
||||
Converter = converter;
|
||||
}}
|
||||
|
||||
public Type Converter {{ get; }}
|
||||
}}
|
||||
}}
|
||||
".Trim();
|
||||
|
||||
// Act
|
||||
var (compilation, diagnostics) = CSharpGenerator.GetOutputCompilation(source, analyzerConfigOptions: DefaultAnalyzerOptions);
|
||||
|
||||
// Assert
|
||||
diagnostics.ShouldBeSuccessful();
|
||||
compilation.SyntaxTrees.ShouldContainSource(MapPropertyAttributeSource.AttributeName, expectedInterface);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,6 +7,10 @@ namespace TestConsoleApp.ViewModels
|
|||
[MapFrom(typeof(Data.Models.User))]
|
||||
public partial class User
|
||||
{
|
||||
public int Id { get; }
|
||||
|
||||
public string FirstName { get; }
|
||||
|
||||
public string LastName { get; }
|
||||
}
|
||||
}
|
|
@ -7,7 +7,16 @@ namespace TestConsoleApp.ViewModels
|
|||
{
|
||||
public string FirstName { get; }
|
||||
|
||||
// [IgnoreProerty]
|
||||
[IgnoreProperty]
|
||||
public string LastName { get; }
|
||||
|
||||
[MapProperty(converter: typeof(LastNameConverter))]
|
||||
public string Key { get; }
|
||||
|
||||
private class LastNameConverter : ITypeConverter<int, string>
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public string Convert(int source) => $"{source} :: With Type Converter";
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue