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

Support for merge mappings #378

Closed
jobadder-daviddancy opened this issue Apr 26, 2023 · 3 comments
Closed

Support for merge mappings #378

jobadder-daviddancy opened this issue Apr 26, 2023 · 3 comments

Comments

@jobadder-daviddancy
Copy link

jobadder-daviddancy commented Apr 26, 2023

Is your feature request related to a problem? Please describe.

I'm using Mapperly in a project where I have to combine multiple objects together to make a kind of hybrid. My current best effort is to create an intermediary object that I use to map to the final object, where the intermediary has constructor(s) that map the many objects into one. This works OK but it's a lot of manually-written code.
If Mapperly could do "merge" assignments instead of only "create" assignments I think it would enable this multi-stage process to be automated nicely.

Describe the solution you'd like

The default strategy for mapping is assignment to a new record. Add a new strategy called "Merge" or "Assign To Existing Record" that works exactly the same way as the original Mapperly code-generation, except it takes 2 parameters: the record into which the incoming data will be merged, and the record to use for the data.

public class Data1
{
  public int MyInt { get; set; }
  public string MyString { get; set; }
}

public class Data2
{
  public int MyInt { get; set; }
  public string MyOtherString { get; set; }
}

public class AssignResult
{
  public int MyInt { get; set; }
}

public class MergeResult
{
  public int MyInt { get; set; }
  public string MyOtherString { get; set; }
}

[Mapper]
public static partial class AssignMapper 
{
  [MapperIgnoreSource(nameof(Data1.MyString))]
  public static partial AssignResult(this Data1 data);
}

[Mapper(MappingStrategy = MappingStrategy.Merge)]
public static partial class MergeMapper 
{
  [MapperIgnoreTarget(nameof(MergeResult.MyInt))]
  public static partial MergeResult(this AssignResult source, Data2 data);
}

// Usage

public static MergeResult(this Data1 data1, Data2 data2)
{
  return data1.AssignResult().MergeResult(data2);
}

Describe alternatives you've considered

The only viable current alternative is to manually map to an intermediate object and then use Mapperly to map that to the result.

Additional context

This could be a generalised solution to issue 103 (#103) although it might require wrapping the parameters in a mapping class. Perhaps the code-generation could understand whether the merge parameter is a value or a record/struct/class and generate different code for the different circumstances.

Overall I think this idea would enable an arbitrary number of parameters to be treated one at a time in a mapping chain that leverages existing functionality without complicating the code-generation functionality.

@latonz
Copy link
Contributor

latonz commented Apr 26, 2023

I‘m not sure if I understand it correctly, but isn‘t what you are requesting what Mapperly calls void mapping methods? (Should probably be renamed to Map to existing target objects…)

@jobadder-daviddancy
Copy link
Author

Let me try it... sounds promising!

@jobadder-daviddancy
Copy link
Author

I gave it a go and I think it does what I need. Sorry for the noise.

@latonz latonz closed this as completed Apr 26, 2023
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

No branches or pull requests

2 participants