mapperly icon indicating copy to clipboard operation
mapperly copied to clipboard

Emit more readable constructor mapping code

Open aradalvand opened this issue 1 year ago • 2 comments

Currently, mapping to records emits code that passes the source values to the constructor of the destination record type, but it does so all in a single line, like so:

// <auto-generated />
#nullable enable
namespace PaymentManagement.Infrastructure.Mappers
{
    public static partial class GatewayMappers
    {
        [global::System.CodeDom.Compiler.GeneratedCode("Riok.Mapperly", "3.5.1.0")]
        public static partial global::System.Linq.IQueryable<global::PaymentManagement.Application.UseCases.GatewayDto> ToGatewayDtos(this global::System.Linq.IQueryable<global::PaymentManagement.Domain.Entities.Gateway> query)
        {
#nullable disable
            return System.Linq.Queryable.Select(query, x => new global::PaymentManagement.Application.UseCases.GatewayDto(x.Id, global::PaymentManagement.Domain.Enums.PaymentServiceProviderExtensions.ToHumanReadableName(x.Psp), x.SubsidiaryTitle, new global::PaymentManagement.Application.UseCases.GatewayBankAccountDto(x.BankAccount.Id, x.BankAccount.Number, x.BankAccount.Iban, x.BankAccount.BankTitle)));
#nullable enable
        }

        [global::System.CodeDom.Compiler.GeneratedCode("Riok.Mapperly", "3.5.1.0")]
        private static partial global::PaymentManagement.Application.UseCases.GatewayDto ToGatewayDto(this global::PaymentManagement.Domain.Entities.Gateway gateway)
        {
            var target = new global::PaymentManagement.Application.UseCases.GatewayDto(gateway.Id, MapPspTitle(gateway.Psp), gateway.SubsidiaryTitle, MapToGatewayBankAccountDto(gateway.BankAccount));
            return target;
        }

        [global::System.CodeDom.Compiler.GeneratedCode("Riok.Mapperly", "3.5.1.0")]
        private static global::PaymentManagement.Application.UseCases.GatewayBankAccountDto MapToGatewayBankAccountDto(global::PaymentManagement.Domain.Entities.GatewayBankAccount source)
        {
            var target = new global::PaymentManagement.Application.UseCases.GatewayBankAccountDto(source.Id, source.Number, source.Iban, source.BankTitle);
            return target;
        }
    }
}

Given that one of Mapperly's main claims to fame is generating readable code, it would go a long way in terms of improving readability if the constructor arguments in this case were each on a separate line.

aradalvand avatar Jun 07 '24 09:06 aradalvand

Thanks for reporting, Mapperly doesn't differentiate between records and other constructors. This should target all constructors. I adjusted the title.

latonz avatar Jun 10 '24 15:06 latonz

Would be happy to accept a PR implementing this. A good starting point to contribute is the contributors documentation. Let us know if you plan to work on this 😊 Some hints / affected code:

  • SyntaxFactoryHelper.CreateObject in src/Riok.Mapperly/Emit/Syntax/SyntaxFactoryHelper.New.cs

latonz avatar Jun 10 '24 15:06 latonz