Liaison d’une application iOS .NET MAUI
Quand elle génère votre application, .NET Multi-Platform App UI (.NET MAUI) peut utiliser un éditeur de liens appelé ILLink pour réduire la taille globale de l’application. ILLink réduit la taille en analysant le code intermédiaire produit par le compilateur. Il supprime les méthodes, propriétés, champs, événements, structs et classes inutilisés pour produire une application qui contient uniquement le code et les dépendances d’assembly nécessaires pour exécuter l’application.
Comportement de l’éditeur de liens
L’éditeur de liens prend en charge trois modes pour les applications .NET MAUI sur iOS et Mac Catalyst :
- Ne pas lier. La désactivation de la liaison assure que les assemblys ne sont pas modifiés.
- Lier les assemblys du Kit de développement logiciel (SDK) uniquement. Dans ce mode, l’éditeur de liens ne touche pas à vos assemblys et réduit la taille des assemblys du Kit de développement logiciel (SDK) en supprimant les types et les membres que votre application n’utilise pas.
- Lier tous les assemblys. Lorsqu’il lie tous les assemblys, l’éditeur de liens effectue des optimisations supplémentaires pour rendre votre application aussi petite que possible. Il modifie le code intermédiaire de votre code source, ce qui peut casser votre application si vous utilisez des fonctionnalités utilisant une approche que l’analyse statique de l’éditeur de liens ne peut pas détecter. Dans ce cas, vous devrez peut-être modifier votre code source pour que votre application fonctionne correctement.
Le comportement de l’éditeur de liens peut être configuré pour chaque configuration de build de votre application.
Avertissement
L’activation de l’éditeur de liens pour la configuration du débogage de votre application peut entraver votre expérience de débogage, car elle peut supprimer des accesseurs de propriétés qui vous permettent d’inspecter l’état de vos objets.
Pour configurer le comportement de l’éditeur de liens dans Visual Studio :
Dans l’Explorateur de solutions, cliquez avec le bouton droit sur votre projet d’application .NET MAUI et sélectionnez Propriétés. Accédez à l’onglet iOS > Build et définissez le menu déroulant Comportement de l’éditeur de liens sur le comportement souhaité :
Conserver le code
Lorsque vous utilisez le découpage, il supprime parfois le code que vous avez appelé dynamiquement, même indirectement. Vous pouvez indiquer au découpage de conserver les membres en les annotant avec l’attribut DynamicDependency
. Cet attribut peut être utilisé pour exprimer une dépendance sur un type et un sous-ensemble de membres, ou à des membres spécifiques.
Important
Chaque membre de la BCL dont l’utilisation par l’application ne peut pas être déterminée de manière statique est soumis à la suppression.
L’attribut DynamicDependency
peut être appliqué aux constructeurs, aux champs et aux méthodes :
[DynamicDependency("Helper", "MyType", "MyAssembly")]
static void RunHelper()
{
var helper = Assembly.Load("MyAssembly").GetType("MyType").GetMethod("Helper");
helper.Invoke(null, null);
}
Dans cet exemple, l’attribut DynamicDependency
assure que la méthode Helper
est conservée. Sans l’attribut, le découpage supprime ou supprime Helper
MyAssembly
MyAssembly
complètement s’il n’est pas référencé ailleurs.
L’attribut spécifie le membre à conserver via une string
ou via l’attribut DynamicallyAccessedMembers
. Le type et l’assembly sont implicites dans le contexte d’attribut ou spécifiés explicitement dans l’attribut (par Type
, ou par string
pour le type et le nom de l’assembly).
Les chaînes de type et de membre utilisent une variante du format de chaîne d’ID de commentaire de documentation C#, sans préfixe de membre. La chaîne de membre ne doit pas inclure le nom du type déclarant et peut omettre des paramètres pour conserver tous les membres du nom spécifié. Les exemples suivants montrent des utilisations valides :
[DynamicDependency("Method()")]
[DynamicDependency("Method(System,Boolean,System.String)")]
[DynamicDependency("MethodOnDifferentType()", typeof(ContainingType))]
[DynamicDependency("MemberName")]
[DynamicDependency("MemberOnUnreferencedAssembly", "ContainingType", "UnreferencedAssembly")]
[DynamicDependency("MemberName", "Namespace.ContainingType.NestedType", "Assembly")]
// generics
[DynamicDependency("GenericMethodName``1")]
[DynamicDependency("GenericMethod``2(``0,``1)")]
[DynamicDependency("MethodWithGenericParameterTypes(System.Collections.Generic.List{System.String})")]
[DynamicDependency("MethodOnGenericType(`0)", "GenericType`1", "UnreferencedAssembly")]
[DynamicDependency("MethodOnGenericType(`0)", typeof(GenericType<>))]
Conserver les assemblys
Il est possible de spécifier des assemblys qui doivent être exclus du processus de découpage, tout en permettant à d’autres assemblys d’être supprimés. Cette approche peut être utile lorsque vous ne pouvez pas facilement utiliser l’attribut DynamicDependency
ou ne contrôlez pas le code en cours de suppression.
Quand il supprime tous les assemblys, vous pouvez indiquer au découpage d’ignorer un assembly en définissant un TrimmerRootAssembly
élément MSBuild dans le fichier projet :
<ItemGroup>
<TrimmerRootAssembly Include="MyAssembly" />
</ItemGroup>
Remarque
L’extension .dll
n’est pas nécessaire lors de la définition de la propriété MSBuild TrimmerRootAssembly
.
Si le découpage ignore un assembly, il est considéré comme rooté, ce qui signifie que toutes ses dépendances comprises statiquement sont conservées. Vous pouvez ignorer des assemblys supplémentaires en ajoutant d’autres propriétés MSBuild TrimmerRootAssembly
à la balise <ItemGroup>
.
Conserver des assemblys, des types et des membres
Vous pouvez passer le découpage d’un fichier de description XML qui spécifie quels assemblys, types et membres doivent être conservés.
Pour exclure un membre du processus de découpage lors de la suppression de tous les assemblys, définissez l’élément TrimmerRootDescriptor
MSBuild dans le fichier projet sur le fichier XML qui définit les membres à exclure :
<ItemGroup>
<TrimmerRootDescriptor Include="MyRoots.xml" />
</ItemGroup>
Le fichier XML utilise ensuite le format de descripteur de découpage pour définir les membres à exclure :
<linker>
<assembly fullname="MyAssembly">
<type fullname="MyAssembly.MyClass">
<method name="DynamicallyAccessedMethod" />
</type>
</assembly>
</linker>
Dans cet exemple, le fichier XML spécifie une méthode accessible dynamiquement par l’application, qui est exclue du découpage.
Lorsqu’un assembly, un type ou un membre est répertorié dans le code XML, l’action par défaut est conservée, ce qui signifie que, indépendamment du fait que le découpage pense qu’il est utilisé ou non, il est conservé dans la sortie.
Remarque
Les balises de conservation sont inclusives de manière ambiguë. Si vous ne fournissez pas le niveau de détail suivant, il inclut tous les enfants. Si un assembly est répertorié sans type, tous les types et membres de l’assembly sont conservés.
Marquer un assembly comme étant sécurisé
Si vous disposez d’une bibliothèque dans votre projet ou si vous êtes développeur d’une bibliothèque réutilisable et que vous souhaitez que le découpage traite votre assembly comme rognable, vous pouvez marquer l’assembly comme étant supprimé en ajoutant la IsTrimmable
propriété MSBuild au fichier projet pour l’assembly :
<PropertyGroup>
<IsTrimmable>true</IsTrimmable>
</PropertyGroup>
Cela marque votre assembly comme « découpable » et active les avertissements de découpage pour ce projet. Être « découpable » signifie que votre assembly est considéré comme compatible avec le découpage et qu’il ne doit pas avoir d’avertissements de découpage lorsqu’il est généré. Lorsqu’il est utilisé dans une application découpée, les membres inutilisés de l’assembly sont supprimés dans la sortie finale.
Lors de l’utilisation du déploiement AOT natif dans .NET 9+, la définition de la propriété MSBuild IsAotCompatible
sur true
affecte également une valeur de true
à la propriété IsTrimmable
et active des propriétés de build d’analyseur AOT supplémentaires. Pour plus d’informations sur les analyseurs AOT, consultez analyseurs de compatibilité AOT. Pour plus d’informations sur le déploiement AOT natif pour .NET MAUI, consultez déploiement AOT natif.
La définition de la propriété MSBuild IsTrimmable
sur true
dans votre fichier projet insère l’attribut AssemblyMetadata
dans votre assembly :
[assembly: AssemblyMetadata("IsTrimmable", "True")]
Vous pouvez également ajouter l’attribut AssemblyMetadata
dans votre assembly sans avoir ajouté la propriété MSBuild IsTrimmable
au fichier projet de votre assembly.
Remarque
Si la propriété MSBuild IsTrimmable
est définie pour un assembly, cela remplace l’attribut AssemblyMetadata("IsTrimmable", "True")
. Cela vous permet d’opter pour un assembly dans le découpage même s’il n’a pas l’attribut ou de désactiver le découpage d’un assembly qui a l’attribut.
Supprimer les avertissements d’analyse
Lorsque le découpage est activé, il supprime l’il qui n’est pas accessible de manière statique. Les applications qui utilisent la réflexion ou d’autres modèles qui créent des dépendances dynamiques peuvent être rompues en conséquence. Pour avertir de tels modèles, lors du marquage d’un assembly comme sécurisé, les auteurs de bibliothèque doivent définir la SuppressTrimAnalysisWarnings
propriété MSBuild sur false
:
<PropertyGroup>
<SuppressTrimAnalysisWarnings>false</SuppressTrimAnalysisWarnings>
</PropertyGroup>
La suppression des avertissements d’analyse de découpage inclut des avertissements sur l’ensemble de l’application, y compris votre propre code, le code de la bibliothèque et le code du Kit de développement logiciel (SDK).
Afficher les avertissements détaillés
L’analyse de découpage génère au plus un avertissement pour chaque assembly provenant d’un PackageReference
, ce qui indique que les éléments internes de l’assembly ne sont pas compatibles avec le découpage. En tant qu’auteur de bibliothèque, lorsque vous marquez un assembly comme sécurisé, vous devez activer des avertissements individuels pour tous les assemblys en définissant la TrimmerSingleWarn
propriété MSBuild sur false
:
<PropertyGroup>
<TrimmerSingleWarn>false</TrimmerSingleWarn>
</PropertyGroup>
Ce paramètre affiche tous les avertissements détaillés, au lieu de les réduire à un seul avertissement par assembly.