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

Increased support for XML/WSDL generated model mappings #1636

Open
jcbExp opened this issue Dec 12, 2024 · 2 comments
Open

Increased support for XML/WSDL generated model mappings #1636

jcbExp opened this issue Dec 12, 2024 · 2 comments
Labels
enhancement New feature or request

Comments

@jcbExp
Copy link

jcbExp commented Dec 12, 2024

Is your feature request related to a problem? Please describe.
We are currently using Mapperly to map from models generated from an external service's large WSDL file using svcutil. These models are automatically generated with <field>Specified properties to indicate nullability for types such as int. This creates an extremely large number of Mapperly warnings for these properties, making it hard to see what properties are actually unmapped. In addition, it also requires additional user mappers to be made to avoid default values being taken from the model even if the property was not originally in the input.

Describe the solution you'd like
Boolean mapper configuration indicating in some form that the generated mappers should check for these 'Specified' properties and use these in the generated mappers, as well as suppress warnings for these source properties.

Example:

public class Source
{
    public int MyProperty { get; set; }
    public bool MyPropertySpecified { get; set; }
}

public class Target
{
    public int? MyProperty { get; set; }
}

[Mapper(UseSpecifiedProperties = true)]
public partial class Mapper
{
    public partial Target Map(Source source);
}

Suggested generated code:

// <auto-generated />
#nullable enable
namespace MyNamespace
{
    public partial class Mapper
    {
        [global::System.CodeDom.Compiler.GeneratedCode("Riok.Mapperly", "4.1.1.0")]
        public partial global::MyNamespace.Target Map(global::MyNamespace.Source source)
        {
            var target = new global::MyNamespace.Target();
            target.MyProperty = source.MyPropertySpecified ? target.MyProperty : null;
            return target;
        }
    }
}

Describe alternatives you've considered
Ignoring the properties using [MapperIgnoreSource()] is an alternative I've considered for removing the warnings, and user mappings are also an option for ensuring we map to null if the field is not specified.

However, the models themselves are from an external service and may be updated, as well as being extremely large and containing a lot of these properties (> 1000). Individually ignoring or mapping the properties would create a large amount of messy code and would generally be good to avoid.

Editing the source models themselves also needs to be avoided, since the service is regularly updated to add new fields and we would need to regenerate the models everytime this happens.

Additional context
When generating these models using svcutil, the generated models generally follow the same naming convention of <field>Specified, and this should be the same when mapping models from any XML/WSDL service. Thus, I believe it could be useful to other users in the future who may encounter the same problem.

@jcbExp jcbExp added the enhancement New feature or request label Dec 12, 2024
@latonz
Copy link
Contributor

latonz commented Dec 13, 2024

I can see your use case, however it is quite "niche". Supporting all these edge cases will make Mapperly more complex, so we will probably only implement this if more people request it.
It may also be implemented in a more flexible way, so that also Protos Has could be supported.

@TonEnfer
Copy link
Contributor

TonEnfer commented Dec 13, 2024

I was also thinking of creating a similar issue, but in the context of Protobuf with its Has properties.

It seems that to implement this, as @latonz mentioned, a more flexible approach should be used. In my understanding, it could be something like

[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class UseValueProvidedPropertiesCheckAttribute(string? prefix = null, string? suffix = null): Attribute;

which could be used as

[UseValueProvidedPropertiesCheck(prefix = "Has")]
[UseValueProvidedPropertiesCheck(suffix = "Specified")]
public partial Model MapToModel(Dto dto);

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

3 participants