Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Remarque
Ceci n’est pas la dernière version de cet article. Pour la version actuelle, consultez la version .NET 10 de cet article.
Avertissement
Cette version d'ASP.NET Core n'est plus prise en charge. Pour plus d’informations, consultez la stratégie de prise en charge de .NET et .NET Core. Pour la version actuelle, consultez la version .NET 10 de cet article.
Cet article explique comment contrôler l’outil de découpage de langage intermédiaire (IL) lors de la création d’une application Blazor.
Blazor WebAssembly effectue un découpage du langage intermédiaire (IL) pour réduire la taille de la sortie publiée. Le découpage se produit lorsqu'une application est publiée.
Granularité par défaut de l'outil de découpage
La granularité de découpage par défaut pour Blazor les applications est partial, ce qui signifie que seules les bibliothèques et bibliothèques de framework de base qui ont explicitement activé la prise en charge du découpage sont coupées. Le découpage complet n’est pas pris en charge.
Pour plus d'informations, voir Options de découpage (Documentation .NET).
Paramétrage
Pour configurer l'outil de découpage de langage intermédiaire (IL), voir l'article Options de découpage dans la documentation sur les principes fondamentaux de .NET, qui contient des recommandations sur les sujets suivants :
- Désactiver le découpage pour l'ensemble de l'application avec la propriété
<PublishTrimmed>dans le fichier de projet. - Contrôler le niveau d'agressivité avec lequel le langage intermédiaire inutilisé est rejeté par l'outil de découpage de langage intermédiaire.
- Arrêter l'outil de découpage de langage intermédiaire à partir d'assemblys spécifiques au découpage.
- Assemblys racines pour le découpage.
- Faire apparaître des avertissements pour les types accédés par réflexion en définissant la propriété
<SuppressTrimAnalysisWarnings>surfalsedans le fichier projet. - Contrôler le découpage des symboles et la prise en charge du débogueur.
- Configurer les fonctionnalités de l'outil de découpage de langage intermédiaire pour le découpage de fonctionnalités de la bibliothèque du framework.
Lorsque la granularité du découpage est partial, qui est la valeur par défaut, le découpage IL supprime la bibliothèque de classes de base et tous les autres assemblys marqués comme pouvant être supprimés. Pour activer le découpage dans l’un des projets de bibliothèque de classes de l’application, définissez la propriété MSBuild <IsTrimmable> à true dans ces projets :
<PropertyGroup>
<IsTrimmable>true</IsTrimmable>
</PropertyGroup>
Pour obtenir des conseils relatifs aux bibliothèques .NET, consultez Préparer les bibliothèques .NET pour le découpage.
Échec de conservation des types utilisés par une application publiée
Le découpage peut avoir des effets néfastes pour une application publiée entraînant des erreurs d’exécution, même en dépit de la définition de la <PublishTrimmed> propriétéfalse dans le fichier projet. Dans les applications qui utilisent la réflexion, l'outil de découpage de langage intermédiaire ne peut pas déterminer les types requis pour la réflexion lors de l'exécution, et les supprime ou supprime les noms de paramètres des méthodes. Cela peut se produire avec des types complexes du framework utilisés pour l'interopérabilité avec JS, la sérialisation/désérialisation JSON, et d'autres opérations.
L'outil de découpage de langage intermédiaire est également incapable de réagir au comportement dynamique d'une application à l'exécution. Pour s'assurer que l'application réduite fonctionne correctement une fois déployée, testez fréquemment la sortie publiée pendant le développement.
Prenons l’exemple suivant qui effectue la désérialisation JSON dans une Tuple<T1,T2> collection (List<Tuple<string, string>>).
TrimExample.razor :
@page "/trim-example"
@using System.Diagnostics.CodeAnalysis
@using System.Text.Json
<h1>Trim Example</h1>
<ul>
@foreach (var item in @items)
{
<li>@item.Item1, @item.Item2</li>
}
</ul>
@code {
private List<Tuple<string, string>> items = [];
[StringSyntax(StringSyntaxAttribute.Json)]
private const string data =
"""[{"item1":"1:T1","item2":"1:T2"},{"item1":"2:T1","item2":"2:T2"}]""";
protected override void OnInitialized()
{
JsonSerializerOptions options = new() { PropertyNameCaseInsensitive = true };
items = JsonSerializer
.Deserialize<List<Tuple<string, string>>>(data, options)!;
}
}
Le composant précédent s’exécute normalement lorsque l’application est exécutée localement et produit la liste rendue suivante :
• 1 :T1, 1 :T2
• 2 :T2, 2 :T2
Lorsque l’application est publiée, Tuple<T1,T2> elle est supprimée de l’application, même en dépit de la définition de la <PublishTrimmed> propriété false dans le fichier projet. L'accès au composant lève l'exception suivante :
crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
Unhandled exception rendering component: ConstructorContainsNullParameterNames, System.Tuple`2[System.String,System.String]
System.NotSupportedException: ConstructorContainsNullParameterNames, System.Tuple`2[System.String,System.String]
Pour traiter les types perdus, envisagez d’adopter l’une des approches suivantes.
Types personnalisés
Pour éviter les problèmes liés au découpage .NET dans les scénarios qui reposent sur la réflexion, tels que JS l’interopérabilité et la sérialisation JSON, utilisez des types personnalisés définis dans des bibliothèques non rognables ou conservez les types via la configuration de l’éditeur de liens.
Les modifications suivantes créent un type StringTuple à utiliser par le composant.
StringTuple.cs :
[method: SetsRequiredMembers]
public sealed class StringTuple(string item1, string item2)
{
public required string Item1 { get; init; } = item1;
public required string Item2 { get; init; } = item2;
}
Le composant est modifié pour utiliser le type StringTuple :
- private List<Tuple<string, string>> items = [];
+ private List<StringTuple> items = [];
- items = JsonSerializer.Deserialize<List<Tuple<string, string>>>(data, options)!;
+ items = JsonSerializer.Deserialize<List<StringTuple>>(data, options)!;
Étant donné que les types personnalisés définis dans les assemblies non rognables ne sont pas rognés lors de la publication de l'application Blazor, le composant fonctionne comme prévu après la publication de l'application.
Si vous préférez utiliser des types de framework malgré notre recommandation, utilisez l’une des approches suivantes :
Si vous préférez utiliser des types d’infrastructure malgré notre recommandation, conservez le type comme dépendance dynamique.
Conserver le type en tant que dépendance dynamique
Créez une dépendance dynamique pour conserver le type avec l’attribut[DynamicDependency].
Si elle n'existe pas déjà, ajoutez une directive @using pour System.Diagnostics.CodeAnalysis :
@using System.Diagnostics.CodeAnalysis
Ajoutez un [DynamicDependency]attribut pour conserver le Tuple<T1,T2> :
+ [DynamicDependency(DynamicallyAccessedMemberTypes.PublicConstructors,
+ typeof(Tuple<string, string>))]
private List<Tuple<string, string>> items = [];
Utiliser un descripteur racine
Un descripteur racine peut conserver le type.
Ajoutez un ILLink.Descriptors.xml fichier à la racine de l’application† avec le type :
<linker>
<assembly fullname="System.Private.CoreLib">
<type fullname="System.Tuple`2" preserve="all" />
</assembly>
</linker>
† La racine de l’application fait référence à la racine de l’application Blazor WebAssembly ou à la .Client racine du projet d’un Blazor Web App (.NET 8 ou version ultérieure).
Ajoutez un TrimmerRootDescriptor élément au fichier projet de l’application en référençant le ILLink.Descriptors.xml fichier :
<ItemGroup>
<TrimmerRootDescriptor Include="$(MSBuildThisFileDirectory)ILLink.Descriptors.xml" />
</ItemGroup>
•Le fichier projet est soit le fichier projet de l’applicationBlazor WebAssembly, soit le fichier projet d’un .ClientBlazor Web App projet (.NET 8 ou version ultérieure).
Solution de contournement dans .NET 8
Pour contourner ce problème dans .NET 8, vous pouvez ajouter la _ExtraTrimmerArgs propriété MSBuild définie --keep-metadata parametername dans le fichier projet de l’application pour conserver les noms de paramètres lors de la suppression :
<PropertyGroup>
<_ExtraTrimmerArgs>--keep-metadata parametername</_ExtraTrimmerArgs>
</PropertyGroup>