Skip to content

feat: Automatically use ref target property mappings#2242

Open
juliancarrivick wants to merge 1 commit intoriok:mainfrom
juliancarrivick:detect-user-ref-mappings
Open

feat: Automatically use ref target property mappings#2242
juliancarrivick wants to merge 1 commit intoriok:mainfrom
juliancarrivick:detect-user-ref-mappings

Conversation

@juliancarrivick
Copy link
Copy Markdown

Automatically use ref target property mappings

Description

This was motivated by wanting to switch from Automapper, where I was able to conditionally update a value based on whether a custom Optional class had a value or not. With Mapperly this requires a ref target mapping, however they currently have to be explicitly opted into for every field on the object, which doesn't scale very well. e.g. When you have many DTOs with many properties that need such a mapping from a controller type to the DB entity type. It seemed timely to implement this functionality since 5.0 is in pre-release at the moment.

As a disclosure, I used Claude to generate the initially failing test cases and inspected that they were reasonable, adapting them to use the pre-existing test models. I also used it to generate the initial fix and also adapted that to the existing conventions.

I'm not entirely happy with the fix, it seems to duplicate checks that are performed elsewhere too (e.g. default checking) and having to downcast to see if it is a ref target or not. I investigated doing some refactoring in this space but it got very messy very quickly so I figured that would be better performed by someone more familiar with the code base.

Thank you for this great project, I hope to be able to use it with this change soon!

Checklist

  • I did not use AI tools to generate this PR, or I have manually verified that the code is correct, optimal, and follows the project guidelines and architecture
  • I understand that low-quality, AI-generated PRs will be closed immediately without further explanation
  • 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)

… for property mapping

When a user defines a void mapping method with a `ref` target parameter, Mapperly
now automatically uses it for property-level mappings of those types, without
requiring explicit `[MapProperty(Use = nameof(...))]` opt-in.

A new-instance user mapping for the same types still takes precedence, and same-type
mappings are excluded to avoid shadowing direct assignment. A method decorated
with `[UseMapper]`/`Default = true` overrides this precedence.

Adds `HasExistingTargetRefUserMapping` on `MappingBuilderContext` and an
`IsRefTarget` property on `UserImplementedExistingTargetMethodMapping`.
@latonz latonz added enhancement New feature or request breaking-change This issue or pull request will break existing consumers labels Apr 24, 2026
@latonz
Copy link
Copy Markdown
Contributor

latonz commented Apr 24, 2026

Thank you for this contribution! I'll look into this the coming week.

@latonz
Copy link
Copy Markdown
Contributor

latonz commented May 2, 2026

I have some concerns about making this the default behavior… Wouldn't the use cases for this be more robustly handled by the proposal in #276 and #1311?
I'd like to understand the necessity of this change versus the more explicit alternatives.

@kammerjaeger
Copy link
Copy Markdown

I agree that some solution would be good.
I basically have the same problem with an Optional class/struct.

I tried generic mappings from https://next.mapperly.riok.app/docs/configuration/generic-mapping/ and explicit method mappings. The current implementation does not support either (without being explicit with MapProperty). If needed I can give examples.
I don't see a reason why not. There is probably some other use case where ref support would also be useful.

But in this case #276 would probably be the better implementation.
Perfect would be something like this https://next.mapperly.riok.app/docs/configuration/mapper/#null-values for optional types, I'm just not sure how this could work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking-change This issue or pull request will break existing consumers enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants