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

Replace invalid MapPropertyAttribute constructors with valid versions #1354

Merged
merged 1 commit into from
Jun 23, 2024
Merged

Replace invalid MapPropertyAttribute constructors with valid versions #1354

merged 1 commit into from
Jun 23, 2024

Conversation

latonz
Copy link
Contributor

@latonz latonz commented Jun 20, 2024

  • Marks MapPropertyattribute.ctor(string[], string[]) as obsolete
  • Adds MapPropertyAttribute.ctor(string[], string)
  • Adds MapPropertyAttribute.ctor(string, string[])

…sions

* Marks MapPropertyattribute.ctor(string[], string[]) as obsolete
* Adds MapPropertyAttribute.ctor(string[], string)
* Adds MapPropertyattribute.ctor(string, string[])
@latonz latonz marked this pull request as ready for review June 23, 2024 18:52
@latonz latonz merged commit 281ecf2 into riok:main Jun 23, 2024
17 checks passed
@latonz latonz deleted the fix/mappropertyattribute-ctors branch June 23, 2024 18:54
@latonz latonz added the bug Something isn't working label Jun 30, 2024
@latonz latonz changed the title fix: Replace invalid MapPropertyAttribute constructors with valid versions Replace invalid MapPropertyAttribute constructors with valid versions Jun 30, 2024
@onionhammer
Copy link

Why remove support for nested -> nested?

@latonz
Copy link
Contributor Author

latonz commented Oct 14, 2024

It was never really supported by Mapperly, therefore we removed the constructor.

@onionhammer
Copy link

onionhammer commented Oct 14, 2024

What do you mean by 'supported'? meaning not working in every scenario and you didn't want to support it?

It was certainly semi functional (and still is, obsolete aside)

@latonz
Copy link
Contributor Author

latonz commented Oct 14, 2024

I don't know of an example which works as expected with nested => nested. Can you provide an example?

@onionhammer
Copy link

onionhammer commented Oct 14, 2024

For this example, I was using it to map a new backend to our legacy API's shape

using Riok.Mapperly.Abstractions;

namespace APITwo;

public enum ProductType
{
    Test,
}

public class InputProduct
{
    public string? Name { get; set; }
    public required InputPartner Partner { get; set; }
    public InputProductMetadata? Metadata { get; set; }
    public ProductType Type { get; set; }
}

public class InputPartner
{
    /// <summary>
    /// The name of the partner
    /// </summary>
    public string? Name { get; set; }
    public string? Headquarters { get; set; }
    public string? Description { get; set; }
    public string? AreasServed { get; set; }
}

public class InputProductMetadata
{
    public string? ImageUrl { get; set; }

    public InputPartnerMetadata? PartnerMetadata { get; set; }
}

public class InputPartnerMetadata
{
    public string? Headquarters { get; set; }
}

// =======

public class OutputProduct
{
    public Guid Id { get; set; }

    public OutputPartnerMetadata? Partner { get; set; }

    public OutputProductDetails? Details { get; set; }
}

public class OutputPartnerMetadata
{
    public string? Headquarters { get; set; }
    public string? Name { get; set; }
    public string? Description { get; set; }
    public string? AreasServed { get; set; }
}

public class OutputProductDetails
{
    public string? Name { get; set; }
    public string? ImageUrl { get; set; }
    public ProductType Type { get; set; }
}

/// <summary>
/// Map domain models to output models
/// </summary>
[Mapper]
public static partial class TestMapper
{
    [MapProperty(
        nameof(InputProduct.Name),
        [nameof(OutputProduct.Details), nameof(OutputProduct.Details.Name)]
    )]
    [MapProperty(
        [nameof(InputProduct.Partner), nameof(InputProduct.Partner.Name)],
        [nameof(OutputProduct.Partner), nameof(OutputProduct.Partner.Name)]
    )]
    [MapProperty(nameof(InputProduct.Metadata), nameof(OutputProduct.Details))]
    [MapProperty(
        [nameof(InputProduct.Metadata), nameof(InputProduct.Metadata.PartnerMetadata)],
        nameof(OutputProduct.Partner)
    )]
    [MapProperty(
        nameof(InputProduct.Type),
        [nameof(OutputProduct.Details), nameof(OutputProduct.Details.Type)]
    )]
    public static partial OutputProduct ProductToOutputProduct(InputProduct product);
}

The above code generates this mapping:

        [global::System.CodeDom.Compiler.GeneratedCode("Riok.Mapperly", "4.0.0.0")]
        public static partial global::APITwo.OutputProduct ProductToOutputProduct(global::APITwo.InputProduct product)
        {
            var target = new global::APITwo.OutputProduct();
            if (product.Metadata?.PartnerMetadata != null)
            {
                target.Partner = MapToOutputPartnerMetadata(product.Metadata.PartnerMetadata);
            }
            else
            {
                target.Partner = null;
            }
           ///// These lines are added
            target.Partner ??= new global::APITwo.OutputPartnerMetadata();
            target.Partner.Name = product.Partner.Name;
           ////
            if (product.Metadata != null)
            {
                target.Details = MapToOutputProductDetails(product.Metadata);
            }
            else
            {
                target.Details = null;
            }
            target.Details ??= new global::APITwo.OutputProductDetails();
            target.Details.Name = product.Name;
            target.Details.Type = product.Type;
            return target;
        }

        [global::System.CodeDom.Compiler.GeneratedCode("Riok.Mapperly", "4.0.0.0")]
        private static global::APITwo.OutputPartnerMetadata MapToOutputPartnerMetadata(global::APITwo.InputPartnerMetadata source)
        {
            var target = new global::APITwo.OutputPartnerMetadata();
            target.Headquarters = source.Headquarters;
            return target;
        }

        [global::System.CodeDom.Compiler.GeneratedCode("Riok.Mapperly", "4.0.0.0")]
        private static global::APITwo.OutputProductDetails MapToOutputProductDetails(global::APITwo.InputProductMetadata source)
        {
            var target = new global::APITwo.OutputProductDetails();
            target.ImageUrl = source.ImageUrl;
            return target;
        }

@latonz
Copy link
Contributor Author

latonz commented Oct 14, 2024

Oh I see, thanks, I didn't even know that worked and it's completely untested 🙈 I thought I had tested it before deprecating it. I'll investigate further and consider removing the deprecation with 4.1.0. Sorry for the inconvenience.

@onionhammer
Copy link

Ok, thanks for considering that!

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

Successfully merging this pull request may close these issues.

2 participants