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

Allow something like "IgnorePrefix" on properties #619

Open
pilotMike opened this issue Aug 2, 2023 · 9 comments
Open

Allow something like "IgnorePrefix" on properties #619

pilotMike opened this issue Aug 2, 2023 · 9 comments
Labels
enhancement New feature or request

Comments

@pilotMike
Copy link

pilotMike commented Aug 2, 2023

Is your feature request related to a problem? Please describe.
I was trying to do a mapping and ran into an issue where I couldn't get the mapper to do it because the source and destination had slightly different prefixes.

Describe the solution you'd like
Something like class IgnorePrefixAttribute(string SourcePrefix = null, string DestinationPrefix = null);

Describe alternatives you've considered
I tried making intermediary types that would have a dot notation to match what I wanted, but the source generator couldn't work it out, ie
Source: { FooBar }
Destination: X { Y Foo }, Y { bool Bar }

@TimothyMakkison
Copy link
Collaborator

TimothyMakkison commented Aug 2, 2023

Hey, unfortunately Mapperly doesn't support automatic unflattening yet. Instead you can try using [MapProperty]

[Mapper]
public static partial class Mapper
{
    [MapProperty("FooBar", "Foo.Bar")]
    public static partial Destination Map(Source src);
}

@latonz
Copy link
Contributor

latonz commented Aug 4, 2023

This may get implemented by #594

@latonz latonz linked a pull request Aug 4, 2023 that will close this issue
7 tasks
@TimothyMakkison
Copy link
Collaborator

TimothyMakkison commented Dec 1, 2023

Would it be worth adding regex support here? This way we don't have to add suffix and custom ignores as well.

[MapperIgnore("Local\w*")] // ignores all members starting with "Local"

@latonz
Copy link
Contributor

latonz commented Dec 2, 2023

@TimothyMakkison I have mixed feelings about regex since it adds a lot of complexity on the users side for probably really rare use-cases.

@latonz latonz added the enhancement New feature or request label Mar 11, 2024
@InspiringCode
Copy link

InspiringCode commented Apr 16, 2024

@latonz Adding support for more flexible member matching would be really useful. I have a DTO where I have A LOT of XyzInInputUnit properties that match to Xyz in the source object. Creating a [MapProperty] attribute for every one of them would be really tedious
😞.

AutoMapper has a feature to replace words and to recognize prefixes/suffixes. I think this is a quite common use case and the examples in their docs are quite practical.

@latonz
Copy link
Contributor

latonz commented Apr 18, 2024

@InspiringCode this issue is about ignoring properties, so its related but not the same.
I think as there are so many possible things on how users want to match properties Regex may really be the best option as @TimothyMakkison proposed.
For the mapper ignore source/target attribute we could introduce a new property IsRegex.
To match properties, a new related issue should be created. I think for this it could be implemented with new properties on the MapperAttribute with a match regex and the target regex replacement. For you sample this could look like this: (.+)InInputUnit => $1. The API would be a little more complex than a simple Prefix/suffix stripping but allows a lot more flexibility.

@InspiringCode
Copy link

@latonz Supporting regexes would be really valuable!

Regarding member name replacing, we have to consider multiple scenarios:

  1. Renaming target members,
  2. Renaming source members,
  3. Renaming muliple members,
  4. Explicitly mapping a member for which the expression would match.

Regarding point 1 and 2 my suggestion would be that the replacement is performed for both, the source and target property (similar to AutoMapper).

Regarding point 3, one way to implement this would be to make the Attribute-properties arrays:

[Mapper(ReplaceMemberNamesRegexes = ["(.+)InInputUnit", "Prsn" ], ReplaceMemberNamesWith=["$1", "Person"])]

Another approach would be to introduce a new ReplaceMemberNameAttribute that can be applied multiple times.

Regarding point 4: Ideally if one of the matched members is explicitly mapped, the explicit mapping should override the regex mapping like in the following example:

[Mapper(ReplaceMemberNameRegex="(.+)InInputUnit", ReplaceMemberNameWith="$1")]
public partial class WeatherMapper {
  [MapProperty(nameof(Weather.SpecialTemperature), nameof(WeatherDTO.SpecialTemperatureInInputUnit), Use=nameof(ConvertWithOffset))]
  public partial WeatherDTO Map(Weather source);
}

I would really love to see this feature in Mapperly. I have used it several times with AutoMapper and I am really missing it.

@latonz
Copy link
Contributor

latonz commented Apr 24, 2024

You are describing even more advanced use-cases than I thought of.. This again increases the API complexity... 🤔
If I understand correctly, your approach would be for each property to walk through a list of regex and replace for each match. Instead of two lists I'd prefer two attributes which can be applied multiple times:

[MapperRenameProperty("(.+)InInputUnit", "$1")]
[MapperRenameProperty("Prsn", "Person")]
public partial class MyMapper;

Explicit MapProperty attributes should always take precedence.
I'm still not really sure if we should increase the complexity that much.

@InspiringCode

I would really love to see this feature in Mapperly. I have used it several times with AutoMapper and I am really missing it.

You are referencing to ReplaceMemberName, RecognizePrefixes and the naming conventions of AutoMapper?

@InspiringCode
Copy link

@latonz
Yes, that would be exactly my suggested approach.
And yes, I was referring to ReplaceMemberName, RecognizePrefixes of AutoMapper.

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

Successfully merging a pull request may close this issue.

4 participants