Länka en .NET MAUI Mac Catalyst-app

När den bygger din app kan .NET Multi-plattform App UI (.NET MAUI) använda en länkare som kallas ILLink för att minska appens totala storlek. ILLink minskar storleken genom att analysera mellanliggande kod som skapas av kompilatorn. Den tar bort oanvända metoder, egenskaper, fält, händelser, structs och klasser för att skapa en app som endast innehåller kod- och sammansättningsberoenden som krävs för att köra appen.

Linker-beteende

Länkaren stöder tre lägen för .NET MAUI-appar på iOS och Mac Catalyst:

  • Länka inte. Om du inaktiverar länkning ser du till att sammansättningar inte ändras.
  • Länka endast SDK-sammansättningar. I det här läget lämnar länkaren dina sammansättningar orörda och minskar storleken på SDK-sammansättningarna genom att ta bort typer och medlemmar som inte används av appen.
  • Länka alla sammansättningar. När den länkar alla sammansättningar utför länkaren ytterligare optimeringar för att göra appen så liten som möjligt. Den ändrar den mellanliggande koden för källkoden, vilket kan bryta din app om du använder funktioner med en metod som länkarens statiska analys inte kan identifiera. I dessa fall kan du behöva göra justeringar i källkoden för att appen ska fungera korrekt.

Linker-beteende kan konfigureras för varje byggkonfiguration av din app.

Varning

Om du aktiverar länkaren för appens felsökningskonfiguration kan det hindra felsökningen eftersom det kan ta bort egenskapsåtkomster som gör att du kan kontrollera tillståndet för dina objekt.

För att konfigurera länkningsbeteende i Visual Studio Code bör du lägga till byggegenskapen $(MtouchLink) i en egenskapsgrupp i appens .csproj-fil . Den här byggegenskapen ska vara inställd på None, SdkOnlyeller Full:

<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net8.0-maccatalyst|AnyCPU'">
  <MtouchLink>SdkOnly</MtouchLink>
</PropertyGroup>

Du kan också ange länkningsbeteendet via CLI när du skapar och publicerar din app. Mer information finns i Publicera en .NET MAUI Mac Catalyst-app.

Viktigt!

Byggegenskapen $(MtouchLink) kan anges separat för varje byggkonfiguration för din app.

Bevara kod

När du använder trimmern tar den ibland bort kod som du kanske har anropat dynamiskt, även indirekt. Du kan instruera trimmern att bevara medlemmar genom att kommentera dem med attributet DynamicDependency . Det här attributet kan användas för att uttrycka ett beroende av antingen en typ och delmängd av medlemmar eller för specifika medlemmar.

Viktigt!

Alla medlemmar i BCL:n som inte kan fastställas statiskt för att användas av appen måste tas bort.

Attributet DynamicDependency kan tillämpas på konstruktorer, fält och metoder:

[DynamicDependency("Helper", "MyType", "MyAssembly")]
static void RunHelper()
{
    var helper = Assembly.Load("MyAssembly").GetType("MyType").GetMethod("Helper");
    helper.Invoke(null, null);
}

I det här exemplet säkerställer DynamicDependency att Helper-metoden behålls. Utan attributet skulle trimning ta bort Helper från MyAssembly eller ta bort MyAssembly helt om det inte refereras någon annanstans.

Attributet anger vilken medlem som ska behållas via ett string eller via attributet DynamicallyAccessedMembers . Typen och sammansättningen är antingen implicita i attributkontexten, eller anges uttryckligen i attributet genom Type eller med strings för att specificera typen och sammansättningsnamnet.

Typ- och medlemssträngarna använder en variant av C#-dokumentationens kommentars-ID-strängformat, utan medlemsprefixet. Medlemssträngen ska inte innehålla namnet på deklareringstypen och kan utelämna parametrar för att behålla alla medlemmar i det angivna namnet. I följande exempel visas giltiga användningsområden:

[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<>))]

Bevara sammansättningar

Det går att ange sammansättningar som ska undantas från trimningsprocessen, samtidigt som andra sammansättningar kan trimmas. Den här metoden kan vara användbar när du inte enkelt kan använda DynamicDependency attributet eller inte styr koden som trimmas.

När den trimmar alla sammansättningar kan du be trimmern att hoppa över en sammansättning genom att ange ett TrimmerRootAssembly MSBuild-objekt i projektfilen:

<ItemGroup>
  <TrimmerRootAssembly Include="MyAssembly" />
</ItemGroup>

Anmärkning

Tillägget .dll krävs inte när du ställer in TrimmerRootAssembly egenskapen MSBuild.

Om trimmern hoppar över en modul anses den vara rotad, vilket innebär att den och alla dess statiskt identifierade beroenden behålls. Du kan hoppa över ytterligare sammansättningar genom att lägga till fler TrimmerRootAssembly MSBuild-egenskaper i <ItemGroup>.

Bevara sammansättningar, typer och medlemmar

Du kan ge trimmern en XML-beskrivningsfil som specificerar vilka assembly, typer och medlemmar som måste behållas.

Om du vill undanta en medlem från trimningsprocessen när du trimmar alla sammansättningar anger du TrimmerRootDescriptor OBJEKTET MSBuild i projektfilen till XML-filen som definierar vilka medlemmar som ska undantas:

<ItemGroup>
  <TrimmerRootDescriptor Include="MyRoots.xml" />
</ItemGroup>

XML-filen använder sedan trimmerbeskrivningsformatet för att definiera vilka medlemmar som ska undantas:

<linker>
  <assembly fullname="MyAssembly">
    <type fullname="MyAssembly.MyClass">
      <method name="DynamicallyAccessedMethod" />
    </type>
  </assembly>
</linker>

I det här exemplet anger XML-filen en metod som används dynamiskt av appen, vilket utesluts från trimning.

När en sammansättning, typ eller medlem visas i XML är standardåtgärden bevarande, vilket innebär att oavsett om trimmern tror att den används eller inte bevaras den i utdata.

Anmärkning

Bevarandetaggar är tvetydigt inkluderande. Om du inte anger nästa detaljnivå kommer den att innehålla alla underordnade. Om en sammansättning visas utan några typer bevaras alla sammansättningstyper och medlemmar.

Markera en sammansättning som trimsäker

Om du har ett bibliotek i projektet, eller om du är utvecklare av ett återanvändbart bibliotek och vill att trimmern ska behandla sammansättningen som trimmad, kan du markera sammansättningen som trimsäker genom att lägga till IsTrimmable egenskapen MSBuild i projektfilen för sammansättningen:

<PropertyGroup>
    <IsTrimmable>true</IsTrimmable>
</PropertyGroup>

Detta markerar din sammansättning som "trimbart" och aktiverar trimvarningar för projektet. Att vara "trimmerbar" innebär att din sammansättning anses vara kompatibel med trimning och inte bör ha några trimvarningar när sammansättningen byggs. När den används i en trimmad app tas sammansättningens oanvända medlemmar bort i det slutliga resultatet.

När du använder native AOT-distribution i .NET 9+, anger inställningen av IsAotCompatible-egenskapen i MSBuild också att värdet true tilldelas IsTrimmable-egenskapen och aktiverar ytterligare AOT-analysverktygsbyggnadsegenskaper. Mer information om AOT-analysverktyg finns i AOT-kompatibilitetsanalyser. Mer information om intern AOT-distribution för .NET MAUI finns i Intern AOT-distribution.

IsTrimmable Om du anger egenskapen MSBuild till true i projektfilen infogas AssemblyMetadata attributet i sammansättningen:

[assembly: AssemblyMetadata("IsTrimmable", "True")]

Du kan också lägga till AssemblyMetadata attributet i sammansättningen utan att ha lagt till IsTrimmable egenskapen MSBuild i projektfilen för sammansättningen.

Anmärkning

IsTrimmable Om egenskapen MSBuild har angetts för en sammansättning åsidosätter detta attributetAssemblyMetadata("IsTrimmable", "True"). På så sätt kan du välja en sammansättning till trimning även om den inte har attributet eller att inaktivera trimning av en sammansättning som har attributet.

Ignorera analysvarningar

När trimmern är aktiverad tar den bort IL som inte kan nås statiskt. Appar som använder reflektion eller andra mönster som skapar dynamiska beroenden kan därför brytas. För att varna för sådana mönster, när man markerar en sammansättning som trim-säker, bör biblioteksförfattarna ange SuppressTrimAnalysisWarnings-egenskapen MSBuild till false:

<PropertyGroup>
  <SuppressTrimAnalysisWarnings>false</SuppressTrimAnalysisWarnings>
</PropertyGroup>

Om du inte undertrycker varningar från trimningsanalys kommer varningar att inkluderas för hela appen, inklusive din egen kod, bibliotekskod och SDK-kod.

Visa detaljerade varningar

Trimanalysen ger högst en varning för varje sammansättning som kommer från en PackageReference, vilket indikerar att sammansättningens interna enheter inte är kompatibla med trimning. När du som biblioteksskapare markerar en sammansättning som trimsäker bör du aktivera enskilda varningar för alla sammansättningar genom att ställa in TrimmerSingleWarn egenskapen MSBuild till false:

<PropertyGroup>
  <TrimmerSingleWarn>false</TrimmerSingleWarn>
</PropertyGroup>

Den här inställningen visar alla detaljerade varningar i stället för att komprimera dem till en enda varning per sammansättning.