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

Include mapping configuration #513

Open
latonz opened this issue Jun 21, 2023 · 7 comments
Open

Include mapping configuration #513

latonz opened this issue Jun 21, 2023 · 7 comments
Labels
enhancement New feature or request

Comments

@latonz
Copy link
Contributor

latonz commented Jun 21, 2023

Introduce two new attributes to include the mapping configuration of another mapper / mapping method.
Each mapping configuration is identified by a name which is by default the name of the method, but can be overwritten by NamedMappingAttribute, eg. [NamedMapping("myName")].
A mapping configuration can be applied to the current mapping method by applying IncludeMappingConfigurationAttribute: [IncludeMappingConfiguration("myName")] / [IncludeMappingConfiguration(nameof(OtherMappingMethod))].
If an IncludeMappingConfigurationAttribute references an ambiguous mapping configuration, a diagnostic should be emitted.

Proposed API:

[AttributeUsage(AttributeTargets.Method)]
public class IncludeMappingConfigurationAttribute : Attribute
{
    public IncludeMappingConfigurationAttribute(string name);
}

[AttributeUsage(AttributeTargets.Method)]
public class NamedMappingAttribute : Attribute
{
    public NamedMappingAttribute(string name);
}

Usage:

class Fruit { public string Name { get; set; } public decimal PricePerUnit { get; set; } }
class FruitDto { public string Title { get; set; } }

class Apple : Fruit { public int Weight { get; set; } }
class AppleDto : FruitDto { public int Weight { get; set; } }

[Mapper]
public partial static class MyMapper
{
    [MapProperty(nameof(Fruit.Name), nameof(FruitDto.Title))]
    [MapperIgnoreSource(nameof(Fruit.PricePerUnit))]
    private partial FruitDto ToFruit(Fruit fruit);

    [IncludeMappingConfiguration(nameof(ToFruit))]
    public partial static AppleDto Map(Apple apple);
}
@latonz latonz added the enhancement New feature or request label Jun 21, 2023
@latonz latonz added this to the v2.10.0 milestone Jun 21, 2023
@latonz latonz self-assigned this Jul 14, 2023
@mutzl
Copy link

mutzl commented Jul 21, 2023

What if the (named) mapping configuration is defined in another (different) Mapping class?
(Happens a lot in my projects.)

Will/should it work anyway?

@latonz
Copy link
Contributor Author

latonz commented Jul 25, 2023

@mutzl it will work as long as it is in the same project and via explicit name. We could probably also add a constructor overload to include the mapper type and generate the name based on the name of the mapper + the name of the mapping method.

@nicholass-alcidion
Copy link

Being able to reuse mappings from a base type would be critical for a number of usecases we have

@latonz
Copy link
Contributor Author

latonz commented Jun 18, 2024

This should also work for reverse mappings with an additional property bool Reverse and on existing target instance mappings.

@dotnetshadow
Copy link

What is the current guidance to work around this issue since the attribute isn't available.
Would you advise passing in the mapper as a property to other mappers?

For the example public partial static AppleDto Map(Apple apple); currently nothing would be automatically mapped since Mapperly doesn't know that a mapper exists for this is that correct?

@InspiringCode
Copy link

@latonz What's the status of this feature? I would really need this for scenarios that involve inheritance. Example:

      public partial PositionDTO Map(Position source);

      [MapProperty(nameof(MassPosition.Mass), nameof(MassPositionDTO.MassInInputUnit))]
      public partial MassPositionDTO Map(MassPosition source);

      [MapProperty(nameof(@DurationPosition.Duration.Hours), nameof(DurationPositionDTO.DurationInH))]
      public partial DurationPositionDTO Map(DurationPosition source);

      // ShaftSealingPosition derives from MassPosition and I need to duplicate this mapping on every subtype
      [MapProperty(nameof(MassPosition.Mass), nameof(MassPositionDTO.MassInInputUnit))]
      public partial ShaftSealingPositionDTO Map(ShaftSealingPosition source);

IncludeMappingConfiguration would solve this problem, but the best solution would be if Mapperly automatically recognizes that there is already a mapping defined for the base class and pick it up automatically.

@latonz
Copy link
Contributor Author

latonz commented Sep 26, 2024

This hasn‘t been implemented yet and also no one is currently working on this. Feel free to contribute. There is no real workaround, except to duplicate your configuration.

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

No branches or pull requests

5 participants