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 accepting destination type as a parameter #349

Closed
tvardero opened this issue Apr 17, 2023 · 5 comments · Fixed by #398
Closed

Support accepting destination type as a parameter #349

tvardero opened this issue Apr 17, 2023 · 5 comments · Fixed by #398
Assignees
Labels
enhancement New feature or request

Comments

@tvardero
Copy link

tvardero commented Apr 17, 2023

Example:

public partial class Mapper
{
    public partial Car MapToModel(CarDto dto);
    public partial CarDto MapToDto(Car model);
    public partial Dog MapToModel(DogDto dto);
    public partial DogDto MapToDto(Dog model);

    public partial TDestination Map<TSource, TDestination>(TSource source);
    public partial TDestination Map<TDestination>(object source, Type sourceType);
    public partial TDestination Map<TDestination>(object source);
    public partial object Map(object source, Type destinationType);
    public partial object Map(object source, Type sourceType, Type destinationType);
    public partial object Map(object source, object destination, Type sourceType, Type destinationType);
}

public class Car
{
    public required string Name { get; set; }
}

public class Dog
{
    public required int LegsCount { get; set; }
}

public record CarDto(string Name);
public record DogDto(int LegsCount);

Will be generated to this code, using all known mappings in the current class:

public partial class Mapper
{
    public partial object Map(object source, Type destinationType)
    {
        if (destinationType.IsAssignableFrom(typeof(CarDto)) && source is Car car) return MapToDto(car);
        if (destinationType.IsAssignableFrom(typeof(Car)) && source is CarDto carDto) return MapToModel(carDto);
        if (destinationType.IsAssignableFrom(typeof(DogDto)) && source is Dog dog) return MapToDto(dog);
        if (destinationType.IsAssignableFrom(typeof(Dog)) && source is DogDto dogDto) return MapToModel(dogDto);

        throw new NotSupportedException();
    }
}

What does this give us?

If user plans to migrate their project from Automapper to Mapperly, then user could just implement either interface IMapper interface or IMapperBase in their Mapperly mapper class.

This will reduce amount of refactoring required on the project. Probably, project code will not change at all, except for IServiceContrainer configuration code.

p.s. I don't know cases when Type sourceType is needed, but it is there in IMapperBase interface.

@tvardero
Copy link
Author

For reference (IMapper interface and others): https://github.com/AutoMapper/AutoMapper/blob/master/src/AutoMapper/Mapper.cs

@tvardero tvardero changed the title Support accepting destination type as parameter to partial method. Support accepting destination type as a parameter Apr 17, 2023
@latonz latonz added the enhancement New feature or request label Apr 17, 2023
@latonz
Copy link
Contributor

latonz commented Apr 17, 2023

This would be a great enhancement for Mapperly but this needs some effort and therefore may take some time until it is implemented.

@tvardero
Copy link
Author

Wow, that was fast! :)

I have a question: given the interface IMapper from AutoMapper, what methods from the interface are now supported (source generated) by Mapperly, and what methods still needed to be implemented manually by user?

From new documentation it is clear that only object Map(object source, Type targetType); is supported.

@tvardero
Copy link
Author

Also second question, if in the future passed parameters will be supported (#103), what will happen if target model has its own property Type TargetType. How the conflict will be resolved, or what user should do in such cases?

@latonz
Copy link
Contributor

latonz commented May 10, 2023

@tvardero for now only object Map(object source, Type targetType); is supported. Most other AutoMapper IMapper methods should be implementable by using the object Map(object source, Type targetType); method. What I think could be a nice addition to Mapperly is to also support void Map(object source, object target) and void Map(object source, object target, Type targetType). These would probably also contribute to support AutoMapper migrations.

A model with a property Type TargetType seems to be an edge case which should be addressed in a concept on how to implement #103. A solution could be to use attributes to mark the additional parameters or the the target type (which then would be a breaking change).

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.

2 participants