Partager via


Liaison d’une application .NET MAUI Android

Quand elle génère votre application, l’interface utilisateur d’application multiplateforme .NET (.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 vous permet de découper vos applications Android .NET MAUI. Lorsque le découpage est activé, l’éditeur de liens laisse vos assemblys inchangés 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.

Le comportement de l’éditeur de liens peut être configuré pour chaque configuration de build de votre application. Par défaut, le découpage est désactivé pour les builds de débogage et activé pour les builds de mise en production.

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 vérifier que le découpage est activé :

  1. Dans Visual Studio, dans Explorateur de solutions, cliquez avec le bouton droit sur votre projet d’application .NET MAUI, puis sélectionnez Propriétés. Ensuite, accédez à l’onglet Options > Android et vérifiez que le découpage est activé pour la configuration de build de mise en production :

    Capture d’écran du comportement de l’éditeur de liens pour Android dans Visual Studio.

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 HelperMyAssemblyMyAssembly 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 de compatibilité 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.