Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add support for nested properties #587

Closed
wants to merge 1 commit into from
Closed

Conversation

zeidoo
Copy link

@zeidoo zeidoo commented Jul 22, 2023

Adding support for nested properties

Description

(cont of #534)

If you don’t want explicitly name all properties from nested source bean, you can use MapperNestedPropertiesAttribute. This will tell Mapperly to map every property from source proerty to the target object.

Currently a WIP. Please let me know what to add for this to be merge eventually.
Checklist

  • The existing code style is followed
  • The commit message follows our guidelines
  • Performed a self-review of my code
  • Hard-to-understand areas of my code are commented
  • The documentation is updated (as applicable)
  • Unit tests are added/updated
  • Integration tests are added/updated (as applicable, especially if feature/bug depends on roslyn or framework version in use)

Copy link
Contributor

@latonz latonz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for this PR 🚀
Closes #453

I added my feedback 😊 Don't hesitate to comment here to discuss the feedback points 😊

/// Maps all properties from a nested path to the root destination.
/// </summary>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class MapperNestedPropertiesAttribute : Attribute
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you rename according to the issue and other mapping related attributes to MapNestedPropertiesAttribute.

private const char PropertyAccessSeparator = '.';

/// <summary>
/// Maps a specified source property to the specified target property.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment isn't correct, is it? The same for the other ctor.

@@ -0,0 +1,3 @@
namespace Riok.Mapperly.Configuration;

public record NestedPropertyMappingConfiguration(StringMemberPath Source);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rename to MapNestedPropertiesMappingConfiguration to match other namings and attribute name.

public void ShouldFlattedNestedToTargetRootMapping()
{
var mapperBody = """
[MapperNestedProperties(nameof(A.NestedValue)]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you also add a test for deep nested properties. Eg. [MapNestedProperties(new[] { nameof(A.Nested), nameof(A.Nested.Value) })]? I'm not sure, but I think these won't work yet.
And probably also add a test for q required init property, a constructor parameter and a queryable projection mapping.

@@ -443,4 +456,33 @@ public void ShouldIgnoreStaticConstructorAndDiagnostic()
.HaveDiagnostic(DiagnosticDescriptors.CouldNotCreateMapping)
.HaveAssertedAllDiagnostics();
}

[Fact]
public void ShouldFlattedNestedToTargetRootMapping()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you move these tests to ObjectPropertyFlatteningTest as they fit better there as this always flattens the values.

Comment on lines +123 to +132
return BuilderContext.SymbolAccessor
.GetAllAccessibleMappableMembers(Mapping.SourceType)
.Where(i => i.Name == x.Source.Path.Last())
.SelectMany(i => BuilderContext.SymbolAccessor.GetAllAccessibleMappableMembers(i.Type))
.Select(i =>
{
var list = x.Source.Path.ToList();
list.Add(i.Name);
return new PropertyMappingConfiguration(new StringMemberPath(list), new StringMemberPath(new[] { i.Name }));
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think mixing these with the manually configured mappings won't fully work...
IMO this needs to be handled separately. If no matching source member could be found, the member should also be looked up in these MapNestedProperties.

return BuilderContext.SymbolAccessor
.GetAllAccessibleMappableMembers(Mapping.SourceType)
.Where(i => i.Name == x.Source.Path.Last())
.SelectMany(i => BuilderContext.SymbolAccessor.GetAllAccessibleMappableMembers(i.Type))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The members included via MapNestedProperties should also be included in _unmappedSourceMemberNames and should also emit a diagnostic if not mapped. This should also be tested.

@@ -443,4 +456,33 @@ public void ShouldIgnoreStaticConstructorAndDiagnostic()
.HaveDiagnostic(DiagnosticDescriptors.CouldNotCreateMapping)
.HaveAssertedAllDiagnostics();
}

[Fact]
public void ShouldFlattedNestedToTargetRootMapping()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is a complete new feature, an integration test should be added to ensure this works with all supported Roslyn versions.

@latonz latonz linked an issue Jul 27, 2023 that may be closed by this pull request
@latonz latonz added this to the v2.10.0 milestone Jul 27, 2023
@latonz latonz removed this from the v3.1.0 milestone Aug 28, 2023
@latonz
Copy link
Contributor

latonz commented Nov 19, 2023

As there seems to be no updates for several weeks I'm closing this for now. Feel free to reopen / open a new PR with updates 😊

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Include all members from a nested member
2 participants