Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Uwaga
Nie jest to najnowsza wersja tego artykułu. Aby zapoznać się z aktualną wersją, zobacz artykuł w wersji .NET 10.
Ostrzeżenie
Ta wersja ASP.NET Core nie jest już obsługiwana. Aby uzyskać więcej informacji, zobacz zasady pomocy technicznej platformy .NET i platformy .NET Core. Aby zapoznać się z aktualną wersją, zobacz artykuł w wersji .NET 10.
W tym artykule wyjaśniono, jak kontrolować trimmer języka pośredniego (IL) podczas kompilowania Blazor aplikacji.
Blazor WebAssembly wykonuje przycinanie języka pośredniego (IL), aby zmniejszyć rozmiar opublikowanych danych wyjściowych. Przycinanie wykonywane jest podczas publikowania aplikacji.
Domyślny stopień szczegółowości trymeru
Domyślny stopień szczegółowości Blazor dla aplikacji to partial, co oznacza, że tylko podstawowe biblioteki i biblioteki struktury, które mają jawnie włączoną obsługę przycinania, są przycinane. Pełne przycinanie nie jest obsługiwane.
Aby uzyskać więcej informacji, zobacz Trimming options (Dokumentacja platformy.NET).
Konfigurowanie
Aby skonfigurować program IL Trimmer, zobacz artykuł Opcje przycinania w dokumentacji podstaw platformy .NET, który zawiera wskazówki dotyczące następujących tematów:
- Wyłącz przycinanie dla całej aplikacji, używając właściwości
<PublishTrimmed>w pliku projektu. - Kontroluj, jak agresywnie nieużywane IL jest usuwane przez IL Trimmer.
- Zatrzymaj trymer IL od przycinania określonych zestawów.
- Zestawy "Root" do przycinania.
- Ostrzeżenia dotyczące powierzchni dla odzwierciedlone typy przez ustawienie
<SuppressTrimAnalysisWarnings>właściwości nafalsewartość w pliku projektu. - Kontrola przycinania symboli i wsparcie debugera.
- Ustaw funkcje trymmera IL na potrzeby funkcji biblioteki platformy przycinania.
Gdy granularność trymera to partial, czyli wartość domyślna, trymmer IL przycina bibliotekę klas bazowych i wszystkie inne zestawy oznaczone jako trimmowalne. Aby włączyć przycinanie w dowolnych projektach biblioteki klas aplikacji, ustaw właściwość MSBuild na <IsTrimmable> w tych projektach.
<PropertyGroup>
<IsTrimmable>true</IsTrimmable>
</PropertyGroup>
Aby uzyskać wskazówki dotyczące bibliotek platformy .NET, odwołaj się do Przygotowywanie bibliotek .NET do obcinania.
Nie można zachować typów używanych przez opublikowaną aplikację
Przycinanie może mieć szkodliwe skutki dla opublikowanej aplikacji prowadzącej do błędów środowiska uruchomieniowego, nawet pomimo ustawienia <PublishTrimmed> właściwości na false wartość w pliku projektu. W aplikacjach, które używają odbicia, IL Trimmer często nie może określić wymaganych typów dla odbicia w czasie wykonywania i przycina je lub przycina nazwy parametrów z metod. Może się to zdarzyć w przypadku złożonych typów frameworków używanych do współpracy, serializacji/deserializacji JSON oraz innych operacji.
Program IL Trimmer nie może również reagować na dynamiczne zachowanie aplikacji w czasie wykonywania. Aby upewnić się, że przycięta aplikacja działa prawidłowo po wdrożeniu, przetestuj opublikowane dane wyjściowe często podczas opracowywania.
Rozważmy poniższy przykład, który wykonuje deserializacji JSON w Tuple<T1,T2> kolekcji (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)!;
}
}
Poprzedni składnik jest wykonywany normalnie, gdy aplikacja jest uruchamiana lokalnie i tworzy następującą listę renderowaną:
• 1:T1, 1:T2
• 2:T2, 2:T2
Gdy aplikacja zostanie opublikowana, Tuple<T1,T2> zostanie przycięta z aplikacji, nawet pomimo ustawienia <PublishTrimmed> właściwości na false wartość w pliku projektu. Uzyskiwanie dostępu do składnika zgłasza następujący wyjątek:
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]
Aby rozwiązać problem z utraconymi typami, rozważ wdrożenie jednego z następujących podejść.
Typy niestandardowe
Aby uniknąć problemów z przycinaniem w .NET w scenariuszach opartych na odbiciu, takich jak interoperacyjność i serializacja JSON, należy używać typów niestandardowych zdefiniowanych w bibliotekach nieprzycinalnych lub zachować typy poprzez konfigurację linkera.
Poniższe modyfikacje tworzą StringTuple typ do użycia przez składnik.
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;
}
Składnik jest modyfikowany w celu użycia StringTuple typu:
- 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)!;
Ponieważ typy niestandardowe zdefiniowane w zestawach, które nie mogą być przycinane, nie są przycinane przez Blazor podczas publikacji aplikacji, składnik działa zgodnie z projektem po jej opublikowaniu.
Jeśli wolisz używać typów struktur pomimo naszych zaleceń, użyj jednej z następujących metod:
Jeśli wolisz używać typów struktur pomimo naszego zalecenia, zachowaj typ jako zależność dynamiczną.
Zachowywanie typu jako zależności dynamicznej
Utwórz zależność dynamiczną, aby zachować typ za pomocą atrybutu[DynamicDependency] .
Jeśli jeszcze nie istnieje, dodaj dyrektywę @using dla polecenia System.Diagnostics.CodeAnalysis:
@using System.Diagnostics.CodeAnalysis
Dodaj atrybut, [DynamicDependency] aby zachować Tuple<T1,T2>element :
+ [DynamicDependency(DynamicallyAccessedMemberTypes.PublicConstructors,
+ typeof(Tuple<string, string>))]
private List<Tuple<string, string>> items = [];
Używanie deskryptora głównego
Deskryptor główny może zachować typ.
ILLink.Descriptors.xml Dodaj plik do katalogu głównego aplikacji† z typem:
<linker>
<assembly fullname="System.Private.CoreLib">
<type fullname="System.Tuple`2" preserve="all" />
</assembly>
</linker>
† Katalog główny aplikacji odnosi się do katalogu głównego Blazor WebAssembly aplikacji lub katalogu głównego .Client projektu (.NET 8 lub nowszego Blazor Web App ).
TrimmerRootDescriptor Dodaj element do pliku projektu aplikacji} odwołując się ILLink.Descriptors.xml do pliku:
<ItemGroup>
<TrimmerRootDescriptor Include="$(MSBuildThisFileDirectory)ILLink.Descriptors.xml" />
</ItemGroup>
{Plik projektu jest plikiem Blazor WebAssembly projektu aplikacji lub plikiem .Client projektu projektu Blazor Web App (.NET 8 lub nowszym).
Obejście w programie .NET 8
Aby obejść ten problem na platformie .NET 8, możesz dodać _ExtraTrimmerArgs właściwość MSBuild ustawioną na --keep-metadata parametername w pliku projektu aplikacji, aby zachować nazwy parametrów podczas przycinania:
<PropertyGroup>
<_ExtraTrimmerArgs>--keep-metadata parametername</_ExtraTrimmerArgs>
</PropertyGroup>
Dodatkowe zasoby
ASP.NET Core