Skip to content

Make simple usage of Microsoft.OpenAPI trimmable #1114

Closed
@nb-rubenoost

Description

@nb-rubenoost

I'm trying to use this library in a console app. When trying to publish using trimming, I encountered the fact that this library is not trimmable for even the simplest of cases.

Is your feature request related to a problem? Please describe.

The library is not trimmable when only the following functionality is used:

  • Creating the model by hand through: new OpenApiDocument { ... }
  • Serializing the model using OpenApiJsonWriter or OpenApiYamlWriter

Since these 2 steps don't feel like they are using reflection, I would expect this to be trimmable, which it is not. AFAIK, this is due to EnumExtensions.GetDisplayName():

/_/src/Microsoft.OpenApi/Extensions/EnumExtensions.cs(27,13): Trim analysis warning IL2075: Microsoft.OpenApi.Extension
s.EnumExtensions.GetAttributeOfType<T>(Enum): 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicCo
nstructors', 'DynamicallyAccessedMemberTypes.PublicMethods', 'DynamicallyAccessedMemberTypes.PublicFields', 'Dynamicall
yAccessedMemberTypes.PublicNestedTypes', 'DynamicallyAccessedMemberTypes.PublicProperties', 'DynamicallyAccessedMemberT
ypes.PublicEvents' in call to 'System.Type.GetMember(String)'. The return value of method 'System.Object.GetType()' doe
s not have matching annotations. The source value must declare at least the same requirements as those declared on the
target location it is assigned to.

Describe the solution you'd like

In short, make Microsoft.OpenAPI trimmable for the simple scenario as described before (creating the model and serializing it).

The code that triggers this is:

public static string GetDisplayName(this Enum enumValue)
{
    var attribute = enumValue.GetAttributeOfType<DisplayAttribute>();
    return attribute == null ? enumValue.ToString() : attribute.Name;
}

public static T GetAttributeOfType<T>(this Enum enumValue) where T : Attribute
{
    var type = enumValue.GetType();
    var memInfo = type.GetMember(enumValue.ToString()).First();
    var attributes = memInfo.GetCustomAttributes<T>(false);
    return attributes.FirstOrDefault();
}

This is only used to associate a string with an enum value. My proposed solution is:

Wrap this logic into an IEnumDisplayValueStrategy/DefaultEnumDisplayValueStrategy that we can supply on the OpenApiWriterSettings. End users can implement this themselves, allowing the compiler to trim the DefaultEnumDisplayValueStrategy, thus removing the reflection code.

Describe alternatives you've considered

  1. Instead of using a [Display] attribute, create an extension method that maps Enum to string. This would look something like this:
public enum ParameterStyle
{
    [Display("matrix")] Matrix,
    [Display("label")] Label
}

public static class ParameterStyleExtensions
{
    public static string GetDisplayName(this ParameterStyle style)
    {
        switch (style)
        {
            case ParameterStyle.Matrix:
                return "matrix";
            case ParameterStyle.Label:
                return "label";
            default:
                return style.ToString();
        }
    }
}
  1. Use source generation to generate these methods (similar to 1. but less maintenance). Something like https://github.com/andrewlock/NetEscapades.EnumGenerators would probably suffice.

The issue with both of these solutions is that they would modify the behavior of a public method. This would be a breaking change.

Activity

added
status:needs-discussionAn issue that requires more discussion internally before resolving
type:enhancementEnhancement request targeting an existing experience
on Apr 3, 2023
nb-rubenoost

nb-rubenoost commented on Jan 3, 2024

@nb-rubenoost
Author

If this is something that's wanted, I'd be happy to pick this up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    status:needs-discussionAn issue that requires more discussion internally before resolvingtype:enhancementEnhancement request targeting an existing experience

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      Participants

      @adhiambovivian@nb-rubenoost

      Issue actions

        Make simple usage of `Microsoft.OpenAPI` trimmable · Issue #1114 · microsoft/OpenAPI.NET