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

Duplicate mappings created when using MapDerivedType and nullable is disable #1709

Open
3 tasks done
twing0 opened this issue Feb 4, 2025 · 0 comments
Open
3 tasks done
Labels
bug Something isn't working

Comments

@twing0
Copy link

twing0 commented Feb 4, 2025

Please do the checklist before filing an issue:

  • I have read the documentation, including the FAQ
  • I can reproduce the bug using the latest prerelease version
  • I have searched existing discussion and issue to avoid duplicates

Describe the bug
Not sure of course if this is a bug, or if I'm doing it wrong but here it goes:
I have a project where nullable is set to disable.
<Nullable>disable</Nullable>

I have a abstract base class and a derived class with a property name mismatch.
When setting up the mappings I use the MapDerivedType attribute on the base class.
I use the MapProperty attribute on the derived class to properly map the different properties.

When looking at the generated code, I can see that there is one mapping generated for the derived class where it maps the object correctly including the property name change.
But, I also see another mapping of the derived class used by the base class mapping that does not contain the property change.

Why isn't it using the "real" mapping for the base class mapping.
Even without the property name change, it seems weird that another mapping is created.

When nullable is set to enable, it looks correct.

Thanks

Declaration code

using Riok.Mapperly.Abstractions;

[Mapper]
public static partial class CarMapper
{
	[MapProperty(nameof(Car.Sold), nameof(CarToCarDto.IsSold))]
	public static partial CarDto CarToCarDto(Car car);

	
	[MapDerivedType(typeof(Car), typeof(CarDto))]
	public static partial VehicleDto VehicleToVehicleDto(Vehicle vehicle);
}

public class Car : Vehicle
{
	public bool Sold { get; set; }
}

public abstract class Vehicle
{
	public int Speed { get; set; }
}

public class CarDto : VehicleDto
{
	public bool IsSold { get; set; }
}

public abstract class VehicleDto
{
	public int Speed { get; set; }
}

Actual relevant generated code

// <auto-generated />
#nullable enable
public static partial class CarMapper
{
    [global::System.CodeDom.Compiler.GeneratedCode("Riok.Mapperly", "4.2.0.0")]
    public static partial global::CarDto? CarToCarDto(global::Car? car)
    {
        if (car == null)
            return default;
        var target = new global::CarDto();
        target.IsSold = car.Sold;
        target.Speed = car.Speed;
        return target;
    }

    [global::System.CodeDom.Compiler.GeneratedCode("Riok.Mapperly", "4.2.0.0")]
    public static partial global::VehicleDto? VehicleToVehicleDto(global::Vehicle? vehicle)
    {
        return vehicle == null ? default : vehicle switch
        {
            global::Car x => MapToCarDto(x),
            _ => throw new System.ArgumentException($"Cannot map {vehicle.GetType()} to VehicleDto as there is no known derived type mapping", nameof(vehicle)),
        };
    }

    [global::System.CodeDom.Compiler.GeneratedCode("Riok.Mapperly", "4.2.0.0")]
    private static global::CarDto MapToCarDto(global::Car source)
    {
        var target = new global::CarDto();
        target.Speed = source.Speed;
        return target;
    }
}

Expected relevant generated code
Maybe something like this

// <auto-generated />
#nullable enable
public static partial class CarMapper
{
    [global::System.CodeDom.Compiler.GeneratedCode("Riok.Mapperly", "4.2.0.0")]
    public static partial global::CarDto? CarToCarDto(global::Car? car)
    {
        if (car == null)
            return default;
        var target = new global::CarDto();
        target.IsSold = car.Sold;
        target.Speed = car.Speed;
        return target;
    }

    [global::System.CodeDom.Compiler.GeneratedCode("Riok.Mapperly", "4.2.0.0")]
    public static partial global::VehicleDto? VehicleToVehicleDto(global::Vehicle vehicle)
    {
        return vehicle == null ? default : vehicle switch
        {
            global::Car x => CarToCarDto(x),
            _ => throw new System.ArgumentException($"Cannot map {vehicle.GetType()} to VehicleDto as there is no known derived type mapping", nameof(vehicle)),
        };
    }
}

Environment (please complete the following information):

  • Mapperly Version: 4.2.0-next.0
  • Nullable reference types: disable
  • .NET Version: .NET 6.0.425
  • Target Framework: .net6.0
  • Compiler Version: 4.13.0-3.25051.1 (8bf80c63)
  • C# Language Version: 10.0
  • IDE: VsCode 1.96.4
  • OS: Windows 10
@twing0 twing0 added the bug Something isn't working label Feb 4, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant