Description
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
orOpenApiYamlWriter
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
- 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();
}
}
}
- 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
nb-rubenoost commentedon Jan 3, 2024
If this is something that's wanted, I'd be happy to pick this up.