You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Trimming unused code from libraries used in an application is crucial to minimize deployment size. One of our goals for .NET 9 is to make MAUI trimming-friendly (#18658).
Publishing the base MAUI app dotnet new maui for iOS with NativeAOT currently emits 69 warnings (64 Trim analysis warnings + 5 AOT analysis warnings). Our first goal is to make the codepaths used in the base MAUI app trimming and AOT friendly (0 warnings).
Once the template MAUI app is warning-free, we will move onto more complex scenarios (possibly WeatherTwentyOne or eShop ClientApp).
Build steps
create new MAUI project
./bin/dotnet/dotnet new maui -o TestApp && cd TestApp && dotnet restore
System.Object.GetType() does not return [DynamicallyAccessedMembers] Type required by System.Reflection.RuntimeReflectionExtensions.GetRuntimeProperty(Type,String)
Invokes System.Reflection.Assembly.GetExportedTypes() from an overridden ConvertFrom(ITypeDescriptorContext,CultureInfo,object) and ConvertTo(ITypeDescriptorContext,CultureInfo,object,Type) which aren't decorated with RequiresUnreferencedCodeAttribute
Type from System.Reflection.Assembly.GetExportedTypes() is not decorated with DynamicallAccessedMemberTypes.PublicParameterlessConstructor
Invokes System.Reflection.RuntimeReflectionExtensions.GetRuntimeEvents(Type) with a Type not decorated with DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents
Invokes System.Reflection.RuntimeReflectionExtensions.GetRuntimeEvent(Type,String) with a String not decorated with DynamicallyAccessedMemberTypes.PublicEvents
Invokes System.Reflection.RuntimeReflectionExtensions.GetRuntimeMethods(Type) for a type not decorated with DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods
Invokes System.Reflection.RuntimeReflectionExtensions.GetRuntimeProperties(Type) with a Type not decorated with DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties
Invokes System.Type.GetFields(BindingFlags) with a Type not decorated with DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFieldsInvokes
Invokes System.Type.GetInterfaces() with a Type not decorated with DynamicallyAccessedMemberTypes.Interfaces
Invokes System.Type.GetMethod(String,BindingFlags) with a Type not decorated with DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods
Invokes System.Type.GetProperty(String,BindingFlags) with a Type not decorated with DynamicallyAccessedMemberTypes.PublicProperties
Invokes System.Activator.CreateInstance(Type) with a Type not decorated with DynamicallyAccessedMemberTypes.PublicParameterlessConstructor
Invokes System.Activator.CreateInstance(Type,Object[]) with a Type not decorated with DynamicallyAccessedMemberTypes.PublicConstructors
Invokes System.Reflection.TypeInfo.DeclaredConstructors.get with a TypeInfo not decorated with DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors
Invokes System.Reflection.RuntimeReflectionExtensions.GetRuntimeMethods(Type) with a Type not decorated with DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods
Invokes System.Reflection.TypeInfo.DeclaredFields.get with a TypeInfo not decorated with DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields
Invokes System.Reflection APIs (DeclaredProperties.get, ImplementedInterfaces.get, GetDeclaredMethod(String), GetDeclaredProperty(String)GetDeclaredField(String)) with a TypeInfo not decorated with DynamicallyAccessedMemberTypes
There is a test that counts the warnings in the MAUI app (introduced in #19194). PRs which fix any of the warnings should update the list of expected warnings.
Trimming unused code from libraries used in an application is crucial to minimize deployment size. One of our goals for .NET 9 is to make MAUI trimming-friendly (#18658).
Publishing the base MAUI app
dotnet new mauifor iOS with NativeAOT currently emits 69 warnings (64 Trim analysis warnings + 5 AOT analysis warnings). Our first goal is to make the codepaths used in the base MAUI app trimming and AOT friendly (0 warnings).Once the template MAUI app is warning-free, we will move onto more complex scenarios (possibly WeatherTwentyOne or eShop ClientApp).
Build steps
./bin/dotnet/dotnet publish \ -f net8.0-ios \ -r ios-arm64 \ -p:PublishAot=true \ -p:PublishAotUsingRuntimePack=true \ -p:_RequireCodeSigning=false \ -p:EnableTrimAnalyzer=true \ -p:TrimmerSingleWarn=false | tee TestApp.logWarnings (grouped by class or namespace)
System.Activator.CreateInstance(Type)without aDynamicallyAccessedMemberTypes.PublicParameterlessConstructortype.Type.GetType(String)to grab aMicrosoft.Maui.Controls.*type.System.Activator.CreateInstance(Type,Object[])without aDynamicallyAccessedMemberTypes.PublicConstructorstypeSystem.Activator.CreateInstance(Type)without aDynamicallyAccessedMemberTypes.PublicParameterlessConstructortypeList<Types> DependencyTypes's elements aren'tDynamicallyAccessedMembersTypesSystem.Activator.CreateInstance(Type)without aDynamicallyAccessedMemberTypes.PublicParameterlessConstructortype.RegisterRoute(string, [DynamicallyAccessedMembers...] Type)is accessed through reflection.[QueryProperty]#20466System.Object.GetType()does not return[DynamicallyAccessedMembers] Typerequired bySystem.Reflection.RuntimeReflectionExtensions.GetRuntimeProperty(Type,String)System.Reflection.Assembly.GetExportedTypes()from an overriddenConvertFrom(ITypeDescriptorContext,CultureInfo,object)andConvertTo(ITypeDescriptorContext,CultureInfo,object,Type)which aren't decorated withRequiresUnreferencedCodeAttributeSystem.Reflection.Assembly.GetExportedTypes()is not decorated withDynamicallAccessedMemberTypes.PublicParameterlessConstructorMicrosoft.Maui.Controls.Xaml.TypeConversionExtensions.GetImplicitConversionOperator(Type,Type,Type)typeNameof methodSystem.Type.GetType(String)System.Activator.CreateInstance(Type)without aDynamicallyAccessedMemberTypes.PublicParameterlessConstructortype.System.Reflection.RuntimeReflectionExtensions.GetRuntimeEvents(Type)with a Type not decorated withDynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEventsSystem.Reflection.RuntimeReflectionExtensions.GetRuntimeEvent(Type,String)with a String not decorated withDynamicallyAccessedMemberTypes.PublicEventsSystem.Reflection.RuntimeReflectionExtensions.GetRuntimeMethods(Type)for a type not decorated withDynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethodsSystem.Reflection.RuntimeReflectionExtensions.GetRuntimeProperties(Type)with a Type not decorated withDynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicPropertiesSystem.Type.GetFields(BindingFlags)with a Type not decorated withDynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFieldsInvokesSystem.Type.GetInterfaces()with a Type not decorated withDynamicallyAccessedMemberTypes.InterfacesSystem.Type.GetMethod(String,BindingFlags)with a Type not decorated withDynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethodsSystem.Type.GetProperty(String,BindingFlags)with a Type not decorated withDynamicallyAccessedMemberTypes.PublicPropertiesSystem.Activator.CreateInstance(Type)with a Type not decorated withDynamicallyAccessedMemberTypes.PublicParameterlessConstructorSystem.Activator.CreateInstance(Type,Object[])with a Type not decorated with DynamicallyAccessedMemberTypes.PublicConstructorsSystem.Reflection.TypeInfo.DeclaredConstructors.getwith a TypeInfo not decorated withDynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructorsSystem.Reflection.RuntimeReflectionExtensions.GetRuntimeMethods(Type)with a Type not decorated withDynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethodsSystem.Activator.CreateInstance(Type)with a Type not decorated withDynamicallyAccessedMemberTypes.PublicParameterlessConstructorSystem.Type.GetType(String)System.Type.MakeGenericType(Type[])System.Type.MakeGenericType(Type[])System.Type.GetInterfaces()with a Type not decorated withDynamicallyAccessedMemberTypes.InterfacesSystem.Type.GetInterfaces(String)with a Type not decorated withDynamicallyAccessedMemberTypes.InterfacesSystem.Type.MakeGenericType(Type[])System.Type.GetInterfaces()with a Type not decorated withDynamicallyAccessedMemberTypes.InterfacesSystem.Activator.CreateInstance(Type)with a Type not decorated withDynamicallyAccessedMemberTypes.PublicParameterlessConstructorSystem.Reflection.TypeInfo.DeclaredFields.getwith a TypeInfo not decorated withDynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFieldsSystem.ReflectionAPIs (DeclaredProperties.get,ImplementedInterfaces.get,GetDeclaredMethod(String),GetDeclaredProperty(String)GetDeclaredField(String)) with aTypeInfonot decorated withDynamicallyAccessedMemberTypes<Module>..cctor()- 1System.Enum.GetValues(Type)Automated testing
There is a test that counts the warnings in the MAUI app (introduced in #19194). PRs which fix any of the warnings should update the list of expected warnings.
/cc @jonathanpeppers @mdh1418 @ivanpovazan