Aujourd'hui, Microsoft a une version passionnante comprenant de nombreuses mises à jour de bibliothèques, un nouveau mode WASM, plus de générateurs de sources, des améliorations constantes des performances et le support de NativeAOT sur iOS. Microsoft espére que vous apprécierez ces nouvelles fonctionnalités et améliorations.
Vous pouvez télécharger .NET 8 Preview 6 pour Linux, macOS et Windows.
Restez au courant de ce qui est nouveau et à venir dans What's New in .NET 8. Il sera mis à jour tout au long de la publication.
Jetons maintenant un coup d'œil à quelques nouvelles fonctionnalités de .NET 8.
Améliorations apportées à System.Text.Json
Microsoft a apporté un certain nombre d'améliorations au générateur de sources System.Text.Json, principalement dans le but de rendre Native AOT comparable au serializer basé sur la réflexion.
- Ajout du support de la mise en cache au générateur incrémental, améliorant ainsi les performances de l'IDE dans les grands projets. https://github.com/dotnet/runtime/pull/86121
- Amélioration du formatage du code source généré, y compris des corrections pour un certain nombre de problèmes d'indentation https://github.com/dotnet/runtime/pull/86526, https://github.com/dotnet/runtime/pull/87557
- Ajout d'un certain nombre de nouveaux avertissements de diagnostic https://github.com/dotnet/runtime/pull/87980
- Correction d'un certain nombre de bogues liés à la résolution des modificateurs d'accessibilité https://github.com/dotnet/runtime/pull/87136
- Veille à ce que les types de propriétés ignorées ou inaccessibles ne soient pas inclus par le générateur https://github.com/dotnet/runtime/pull/87383
- Correction de problèmes liés à la prise en charge de JsonNumberHandling https://github.com/dotnet/runtime/pull/87484
- Correction de la prise en charge des types de collection récursifs https://github.com/dotnet/runtime/pull/87632
- Correction de la prise en charge des convertisseurs personnalisés pour les structures nullables https://github.com/dotnet/runtime/pull/84208
- Correction d'un certain nombre de bogues dans l'implémentation de l'analyse d'attributs à la compilation https://github.com/dotnet/runtime/pull/87796
- Ajout de la prise en charge de l'imbrication des déclarations JsonSerializerContext dans des types arbitraires https://github.com/dotnet/runtime/pull/87829
JsonStringEnumConverter<TEnum>
Ce nouveau convertisseur complète la classe JsonStringEnumConverter existante, qui n'est pas prise en charge par Native AOT.
Les utilisateurs souhaitant cibler les utilisateurs de Native AOT doivent annoter leurs types d'énumération avec le modèle suivant.
Code : | Sélectionner tout |
1 2 3 4 5 | [JsonConverter(typeof(JsonStringEnumConverter<MyEnum>))] public enum MyEnum { Value1, Value2, Value3 } [JsonSerializable(typeof(MyEnum))] public partial class MyContext : JsonSerializerContext { } |
JsonConverter.Type
Cette nouvelle propriété permet aux utilisateurs de connaître le type d'une instance non générique de JsonConverter :
Code : | Sélectionner tout |
1 2 | Dictionary<Type, JsonConverter> CreateDictionary(IEnumerable<JsonConverter> converters) => converters.Where(converter => converter.Type != null).ToDictionary(converter => converter.Type!); |
La propriété est annulable puisqu'elle renvoie null pour les instances de JsonConverterFactory et typeof(T) pour les instances de JsonConverter<T>.
Surcharge des méthodes ZipFile.CreateFromDirectory et ExtractToDirectory basées sur les flux
Microsoft a ajouté de nouvelles surcharges de ZipFile CreateFromDirectory qui permettent aux utilisateurs de collecter tous les fichiers inclus dans un répertoire et de les zipper, puis de stocker le fichier zip résultant dans le flux fourni.
Symétriquement les surcharges ont été ajouté ZipFile CreateFromDirectory qui permettent aux utilisateurs de fournir un flux contenant un fichier zippé et d'extraire son contenu dans le système de fichiers.
Ces API permettent d'éviter d'utiliser le disque comme étape intermédiaire. Cela peut être utile dans les scénarios où l'espace disque est limité, comme, par exemple, dans les environnements basés sur le cloud :
- CreateFromDirectory n'a pas besoin d'écrire le résultat zippé sur le disque.
- ExtractToDirectory ne nécessite pas que le fichier zippé soit situé sur le disque.
Utilisation de ZipFile.CreateFromDirectory
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 | Stream destinationStream = GetStreamFromSomewhere(); ZipFile.CreateFromDirectory( sourceDirectoryName: "/home/username/sourcedirectory/", destination: destinationStream, compressionLevel: CompressionLevel.Optimal, includeBaseDirectory: true, entryNameEncoding: Encoding.UTF8); |
Code : | Sélectionner tout |
1 2 3 4 5 6 7 | Stream sourceStream = GetStreamFromSomewhere(); ZipFile.ExtractToDirectory( source: sourceStream, destinationDirectoryName: "/home/username/destinationdirectory/", entryNameEncoding: Encoding.UTF8, overwriteFiles: true); |
MetricCollector est une nouvelle classe conçue pour aider à tester des scénarios. Il s'appelait auparavant InstrumentRecorder. Microsoft a apporté des améliorations significatives à cette classe et l'as déplacée vers le package Microsoft.Extensions.Telemetry.Testing.
La classe MetricCollector peut désormais enregistrer des mesures métriques avec des horodatages. De plus, la classe offre la possibilité d'utiliser n'importe quel fournisseur de temps souhaité pour une génération d'horodatage précise.
L'exemple suivant montre comment utiliser la fonctionnalité.
Usage de MetricCollector
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | const string CounterName = "MyCounter"; var now = DateTimeOffset.Now; var timeProvider = new FakeTimeProvider(now); using var meter = new Meter(Guid.NewGuid().ToString()); var counter = meter.CreateCounter<long>(CounterName); using var collector = new MetricCollector<long>(counter, timeProvider); Assert.Empty(collector.GetMeasurementSnapshot()); Assert.Null(collector.LastMeasurement); counter. Add(3); // verify the update was recorded Assert.Equal(counter, collector.Instrument); Assert.NotNull(collector.LastMeasurement); Assert.Single(collector.GetMeasurementSnapshot()); Assert.Same(collector.GetMeasurementSnapshot().Last(), collector.LastMeasurement); Assert.Equal(3, collector.LastMeasurement.Value); Assert.Empty(collector.LastMeasurement.Tags); Assert.Equal(now, collector.LastMeasurement.Timestamp); |
Présentation du générateur de source de validation des options
Pour réduire les frais de démarrage et améliorer l'ensemble des fonctionnalités de validation, Microsoft a introduit le générateur de code source qui implémente la logique de validation.
Utilisation de la validation des options
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | public class FirstModelNoNamespace { [Required] [MinLength(5)] public string P1 { get; set; } = string. Empty; [Microsoft.Extensions.Options.ValidateObjectMembers(typeof(SecondValidatorNoNamespace))] public SecondModelNoNamespace? P2 { get; set; } [Microsoft.Extensions.Options.ValidateObjectMembers] public ThirdModelNoNamespace? P3 { get; set; } } public class SecondModelNoNamespace { [Required] [MinLength(5)] public string P4 { get; set; } = string. Empty; } public class ThirdModelNoNamespace { [Required] [MinLength(5)] public string P5 { get; set; } = string.Empty; } [OptionsValidator] public partial class FirstValidatorNoNamespace : IValidateOptions<FirstModelNoNamespace> { } [OptionsValidator] public partial class SecondValidatorNoNamespace : IValidateOptions<SecondModelNoNamespace> { } |
Code : | Sélectionner tout |
1 2 3 4 5 6 | var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllersWithViews(); builder.Services.Configure<FirstModelNoNamespace>(builder.Configuration.GetSection(...)); builder.Services.AddSingleton<IValidateOptions<FirstModelNoNamespace>, FirstValidatorNoNamespace>(); builder.Services.AddSingleton<IValidateOptions<SecondModelNoNamespace>, SecondValidatorNoNamespace>(); |
De nouvelles surcharges de constructeur LoggerMessageAttribute ont été introduites, offrant une plus grande flexibilité dans la spécification des paramètres requis avec un code réduit. Les nouvelles surcharges de constructeur incluent des options telles que la spécification uniquement du LogLevel et du message, uniquement du LogLevel ou uniquement du message.
Ces améliorations permettent aux utilisateurs de définir plus facilement les LoggerMessageAttributes tout en minimisant le code inutile.
Code : | Sélectionner tout |
1 2 3 | public LoggerMessageAttribute(LogLevel level, string message); public LoggerMessageAttribute(LogLevel level); public LoggerMessageAttribute(string message); |
Utilisation de LoggerMessage
L'exemple suivant illustre une instanciation de LoggerMessage qui n'était pas possible auparavant.
Code : | Sélectionner tout |
1 2 | [LoggerMessage(Level = LogLevel.Warning, Message = "{p1} should be valid")] public partial void LogWaraning(string p1); |
Améliorations du générateur de source de liaison de configuration
Dans Preview 3, Microsoft a introduit un nouveau générateur de source pour fournir une configuration AOT et compatible avec le trim dans ASP.NET Core. Le générateur est une alternative à la mise en œuvre préexistante basée sur la réflexion. Depuis lors, nous avons apporté plusieurs améliorations basées sur les commentaires de la communauté et le générateur est prêt à être réutilisé avec Preview 6.
Un exemple d'application qui utilise la liaison de configuration et est publiée avec AOT passe de deux (2) avertissements d'analyse AOT lors de la compilation à aucun. L'application échouerait lors de son exécution, mais maintenant elle fonctionne.
Aucune modification du code source n'est nécessaire pour utiliser le générateur. Il est activé par défaut dans les applications Web Native AOT. Pour les autres types de projets, il est désactivé par défaut, mais vous pouvez le contrôler en ajoutant la propriété suivante à votre projet.
Code : | Sélectionner tout |
1 2 3 | <PropertyGroup> <EnableConfigurationBindingGenerator>true</EnableConfigurationBindingGenerator> </PropertyGroup> |
Interopérabilité COM générée par la source
Microsoft a maintenant un nouveau générateur de source qui prend en charge l'interopérabilité avec les interfaces COM à l'aide de la prise en charge de l'interopérabilité générée par la source que nous avons démarrée avec LibraryImportAttribute. Vous pouvez utiliser System.Runtime.InteropServices.Marshalling.GeneratedComInterfaceAttribute pour marquer une interface comme interface COM pour le générateur source. Le générateur de source générera ensuite du code pour permettre l'appel du code C# vers du code non managé, ainsi que du code pour permettre l'appel du code non managé vers C#. Ce générateur de source s'intègre à LibraryImportAttribute et vous pouvez utiliser des types avec GeneratedComInterfaceAttribute comme paramètres et types de retour dans les méthodes attribuées par LibraryImportAttribute.
Le générateur de source COM offre une expérience IDE simple grâce à des analyseurs et des fixateurs de code. Ceci est similaire à LibraryImportAttribute. À côté de chaque interface qui a le System.Runtime.InteropServices.ComImportAttribute, une ampoule offrira une option pour convertir en interopérabilité générée par la source. Ce correctif modifiera l'interface pour utiliser GeneratedComInterfaceAttribute. À côté de chaque classe qui implémente une interface avec le GeneratedComInterfaceAttribute, une ampoule offrira une option pour ajouter le GeneratedComInterfaceAttribute au type. Une fois vos types convertis, vous pouvez déplacer vos méthodes DllImport pour utiliser LibraryImportAttribute avec le fixateur de code existant. Avec ces deux ampoules, il est facile de convertir votre code d'interopérabilité COM existant pour utiliser la nouvelle interopérabilité générée par la source. Il existe également d'autres analyseurs pour vous aider à identifier les endroits où vous pouvez mélanger l'interopérabilité COM générée par la source et basée sur l'exécution qui peut nécessiter un travail supplémentaire.
Dans le cadre de ce projet, nous avons mis à jour la bibliothèque System.Transactions pour utiliser la nouvelle interopérabilité générée par la source ! Nous avons utilisé cette expérience pour aider à affiner les analyseurs et les correcteurs de code afin de fournir une bonne expérience de migration.
Usage de GeneratedComInterfaceAttribute
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | using System.Runtime.InteropServices; using System.Runtime.InteropServices.Marshalling; [GeneratedComInterface] [Guid("5401c312-ab23-4dd3-aa40-3cb4b3a4683e")] interface IComInterface { void DoWork(); } internal class MyNativeLib { [LibraryImport(nameof(MyNativeLib))] public static partial void GetComInterface(out IComInterface comInterface); } |
GeneratedComClassAttribute
Le générateur source prend également en charge le nouveau System.Runtime.InteropServices.Marshalling.GeneratedComClassAttribute pour vous permettre de transmettre vos types qui implémentent des interfaces avec les interfaces attribuées par System.Runtime.InteropServices.Marshalling.GeneratedComInterfaceAttribute au code non managé. Le générateur de source générera le code nécessaire pour exposer un objet COM qui implémente les interfaces et transmet les appels à l'implémentation managée.
Usage de GeneratedComClassAttribute
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | using System.Runtime.InteropServices; using System.Runtime.InteropServices.Marshalling; MyNativeLib.GetComInterface(out IComInterface comInterface); comInterface.RegisterCallbacks(new MyCallbacks()); comInterface.DoWork(); [GeneratedComInterface] [Guid("5401c312-ab23-4dd3-aa40-3cb4b3a4683e")] interface IComInterface { void DoWork(); void RegisterCallbacks(ICallbacks callbacks); } [GeneratedComInterface] [Guid("88470b56-aabc-46af-bf97-8106a1aa3cf9")] interface ICallbacks { void Callback(); } internal class MyNativeLib { [LibraryImport(nameof(MyNativeLib))] public static partial void GetComInterface(out IComInterface comInterface); } [GeneratedComClass] internal class MyCallbacks : ICallbacks { public void Callback() { Console.WriteLine("Callback called"); } } |
Les méthodes sur les interfaces avec GeneratedComInterfaceAttribute prennent en charge tous les mêmes types que LibraryImportAttribute, et LibraryImportAttribute prend en charge les types attribués par GeneratedComInterface et les types attribués par GeneratedComClass dans cette version.
Si votre code C# n'utilisera qu'une interface attribuée par GeneratedComInterfaceAttribute pour encapsuler un objet COM à partir de code non managé ou encapsuler un objet managé à partir de C# pour l'exposer à du code non managé, vous pouvez utiliser les options de la propriété GeneratedComInterfaceAttribute.Options pour personnaliser le code sera généré. Cette option vous permettra de ne pas avoir à écrire de marshallers pour des scénarios dont vous savez qu'ils ne seront pas utilisés.
Le générateur source utilise le nouveau type
System.Runtime.InteropServices.Marshalling.StrategyBasedComWrappers pour créer et gérer les wrappers d'objets COM et les wrappers d'objets gérés. Ce nouveau type gère l'expérience utilisateur .NET attendue pour l'interopérabilité COM, tout en fournissant des points de personnalisation pour les utilisateurs avancés. Si votre application dispose de son propre mécanisme pour définir des types à partir de COM ou si vous devez prendre en charge des scénarios que COM généré par la source ne prend pas actuellement en charge, vous pouvez envisager d'utiliser le nouveau type StrategyBasedComWrappers pour ajouter les fonctionnalités manquantes à votre scénario et obtenir le même .NET expérience utilisateur pour vos types COM.
Limites
Actuellement, le générateur de source COM présente les limitations suivantes. Nous ne prévoyons pas de résoudre ces limitations dans .NET 8, mais nous le pourrons dans une future version de .NET.
- Pas de prise en charge des interfaces basées sur IDispatch.
*La prise en charge de ces interfaces peut être implémentée manuellement à l'aide d'une définition locale de l'interface IDispatch.
- Pas de prise en charge des interfaces basées sur IInspectable.
*Utilisez l'outil CsWinRT pour générer le code d'interopérabilité pour ces interfaces.
- Pas de prise en charge de l'affinité d'appartement.
*Tous les objets COM sont supposés être à thread libre. La prise en charge de l'affinité d'appartement peut être implémentée manuellement à l'aide du type StrategyBasedComWrappers et des implémentations de stratégie personnalisées.
- Pas de prise en charge des propriétés COM.
*Celles-ci peuvent être implémentées manuellement en tant que méthodes sur l'interface.
- Pas de prise en charge des événements COM.
*Celles-ci peuvent être implémentées manuellement à l'aide des API COM sous-jacentes.
- Aucune prise en charge de l'utilisation d’un new mot-clé pour activer une coclasse COM.
*Utilisez LibraryImportAttribute pour P/Invoke à l'API CoCreateInstance pour activer la CoClass.
Prise en charge du proxy HTTPS
https://github.com/dotnet/runtime/issues/31113
Bien que HttpClient ait pris en charge divers types de proxy pendant un certain temps, ils permettent tous à l'homme du milieu de voir à quel site le client se connecte. (même pour les URI HTTPS) Le proxy HTTPS permet de créer un canal crypté entre le client et le proxy afin que toutes les requêtes ultérieures puissent être traitées en toute confidentialité.
Utilisation du proxy HTTPS
- Unix : export all_proxy=https://x.x.x.x:3218
- Windows : [C]set all_proxy=https://x.x.x.x:3218[/C
]
System.Security : Prise en charge de SHA-3
La prise en charge des primitives de hashing SHA-3 est désormais disponible sur les plateformes qui proposent SHA-3. Il s'agit actuellement de Linux avec OpenSSL 1.1.1+ et Windows 11 build 25324+.
Les API où SHA-2 est disponible offrent désormais un complément SHA-3. Cela inclut SHA3_256, SHA3_384 et SHA3_512 pour le hashing ; HMACSHA3_256, HMACSHA3_384 et HMACSHA3_512 pour HMAC ; HashAlgorithmName.SHA3_256, HashAlgorithmName.SHA3_384 et HashAlgorithmName.SHA3_512 pour le hashing où l'algorithme est configurable ; et RSAEncryptionPadding.OaepSHA3_256, RSAEncryptionPadding.OaepSHA3_384 et RSAEncryptionPadding.OaepSHA3_512 pour le chiffrement RSA OAEP.
L'utilisation des API SHA-3 est similaire à SHA-2, avec l'ajout d'une propriété IsSupported pour déterminer si la plateforme offre SHA-3.
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | // Hashing example // Check if SHA-3-256 is supported on the current platform. if (SHA3_256.IsSupported) { byte[] hash = SHA3_256.HashData(dataToHash); } else { // Determine application behavior if SHA-3 is not available. } // Signing Example // Check if SHA-3-256 is supported on the current platform. if (SHA3_256.IsSupported) { using ECDsa ec = ECDsa.Create(ECCurve.NamedCuves.nistP256); byte[] signature = ec.SignData(dataToBeSigned, HashAlgorithmName.SHA3_256); } else { // Determine application behavior if SHA-3 is not available. } |
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 | if (Shake128.IsSupported) { using Shake128 shake = new Shake128(); shake.AppendData("Hello .NET!"u8); byte[] digest = shake.GetHashAndReset(outputLength: 32); // Also available as a one-shot: digest = Shake128.HashData("Hello .NET!"u8, outputLength: 32); } else { // Determine application behavior if SHAKE is not available. } |
SHA-3 a été normalisé par le NIST en tant que FIPS 202 comme alternative, et non comme successeur, à SHA-2. Les développeurs et les organisations doivent décider quand ou même si l'adoption de SHA-3 leur convient.
SDK : performances et compatibilité de la publication de conteneurs
Nous avons apporté quelques modifications aux valeurs par défaut des images générées pour les applications .NET 8.
- Les images utilisent désormais par défaut la nouvelle capacité sans racine des conteneurs .NET, ce qui rend vos applications sécurisées par défaut. Vous pouvez changer cela à tout moment en définissant votre propre ContainerUser, comme root.
- Les images sont étiquetées comme latest par défaut, comme les autres outils de conteneur.
Microsoft a amélioré les performances des poussées de conteneurs vers des registres distants, la fiabilité de l'opération de poussée et la prise en charge d'un plus grand nombre de registres. Dans le même temps, Tom Deseyn de Red Hat était occupé à améliorer la prise en charge d'une gamme d'implémentations de conteneurs courantes.
Cette version devrait voir des performances nettement améliorées pour les poussées de conteneurs, en particulier vers les registres Azure. Cela est dû à notre prise en charge améliorée pour pousser les couches en une seule opération. De plus, pour les registres qui ne prennent pas en charge les téléchargements atomiques, Microsoft a mis en place un mécanisme de téléchargement par blocs plus fiable et réessayable.
Comme effet secondaire de ces changements, Microsoft a également élargi sa matrice de support pour les registres. Harbour et Artifactory rejoignent la liste des registres de travail connus, et le travail de Tom a également permis à Quay.io et Podman de pousser.
Mode HybridGlobalization sur WASM
Les applications WASM peuvent utiliser un nouveau mode de globalisation qui allège l'ensemble ICU et exploite l'API Web à la place. En mode hybride, les données de globalisation sont partiellement extraites du bundle ICU et partiellement des appels vers JS. Il dessert tous les paramètres régionaux pris en charge par WASM.
Quand envisager d'utiliser HybridGlobalization
Cette option est la plus appropriée pour les applications qui ne peuvent pas fonctionner en mode InvariantGlobalization et utilisent les données de localisation de plus d'un fragment ICU (EFIGS, CJK, no-CJK) - donc actuellement en utilisant soit :
Code : | Sélectionner tout |
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
Code : | Sélectionner tout |
<WasmIncludeFullIcuData>true</WasmIncludeFullIcuData>
Applications qui chargeaient une partition sans CJC ou CJC à l'aide de la méthode de chargement de fichier ICU personnalisée :
Code : | Sélectionner tout |
<WasmIcuDataFileName>icudt_no_CJK.dat</WasmIcuDataFileName>
Comment utiliser HybridGlobalization
Définissez la propriété MsBuild : <HybridGlobalization>true</HybridGlobalization>. Il chargera le fichier icudt_hybrid.dat qui est 46 % plus petit que le fichier icudt.dat chargé à l'origine.
Limites
En raison des limitations de l'API Web, toutes les API de globalisation ne sont pas prises en charge en mode hybride. Certaines des API prises en charge ont changé de comportement. Pour vous assurer que votre application ne sera pas affectée, lisez la section Différences de comportement pour WASM.
Les API qui obtiennent le résultat en appelant JS ont de moins bonnes performances que la version non hybride. Ces API sont répertoriées dans la documentation. Les API qui ne figurent pas dans les listes "API publiques concernées" fonctionnent de la même manière qu'en mode non hybride.
Prise en charge du ciblage des plateformes iOS avec NativeAOT
Nous prenons désormais en charge le ciblage des plates-formes de type iOS avec Native AOT. Cela inclut la création et l'exécution d'applications .NET iOS et .NET MAU avec NativeAOT sur : les systèmes ios, iossimulator, maccatalyst, tvos ou tvossimulator. La motivation de ce travail est de permettre aux utilisateurs d'explorer la possibilité d'obtenir de meilleures performances et des économies de taille en ciblant de telles plates-formes avec NativeAOT.
Ceci est disponible en tant que fonctionnalité opt-in destinée au déploiement d'applications, tandis que Mono est toujours utilisé comme choix d'exécution par défaut pour le développement et le déploiement d'applications. Cette étape a été franchie grâce à une excellente collaboration entre les membres de notre communauté : @filipnavara @AustinWise et @am11 qui ont contribué par leur travail, et les efforts conjoints des équipes NativeAOT, Mono et Xamarin.
État actuel
L'état actuel a été testé avec :
- .NET iOS app (dotnet new ios)
- .NET MAUI iOS app (dotnet new maui)
Ces exemples d'applications montrent les résultats préliminaires suivants par rapport à Mono :
Code : | Sélectionner tout |
1 2 3 | .NET iOS app Mono-p6 NativeAOT-p6 diff (%) Size on disk (Mb) 11,61 6,99 -40% .ipa (Mb) 4,37 2,69 -39% |
Code : | Sélectionner tout |
1 2 3 | ET MAUI iOS app Mono-p6 NativeAOT-p6 diff (%) NativeAOT-fix diff (%) Size on disk (Mb) 40,24 50,13 25% 27,58 -31,46% .ipa (Mb) 14,68 16,59 13% 10,23 -30,32% |
1- https://github.com/xamarin/xamarin-macios/pull/18532
2- https://github.com/xamarin/xamarin-macios/issues/18479
3- https://github.com/dotnet/runtime/issues/87924
4- https://github.com/dotnet/runtime/issues/86649
En corrigeant les problèmes identifiés 1-3), nous avons estimé que NativeAOT peut atteindre d'excellents résultats avec l'application .NET MAUI, qui est indiquée dans la colonne NativeAOT-fix, où la taille du bundle d'applications est ~30 % inférieure à celle de Mono. Résoudre le problème 4) améliorerait potentiellement encore plus les performances, mais à ce stade, nous ne pouvons pas estimer les chiffres exacts. Plus d'informations sur les performances de .NET MAUI avec NativeAOT sont suivies dans : https://github.com/dotnet/runtime/issues/80907
Microsoft tient à souligner que les conclusions concernant les performances de NativeAOT sur les plateformes de type iOS ne doivent pas être tirées des chiffres présentés dans le tableau ni de la version .NET 8 Preview 6 en général. D'autant plus qu'il s'agit toujours d'un travail en cours et que la première étape vers la préparation de la fonctionnalité pour la sortie officielle de .NET 9. Par conséquent, Microsoft travaille activement sur des améliorations et identifie tout le travail qui tentera d'apporter une expérience NativeAOT complète à nos clients pour obtenir de grandes performances et des économies de taille, ce qui est suivi dans la liste suivante de problèmes (et leurs sous-tâches) :
- https://github.com/dotnet/runtime/issues/80905 pistes : progression globale
- https://github.com/xamarin/xamarin-macios/issues/17339 pistes : améliorations de l'intégration de Xamarin
- https://github.com/dotnet/runtime/issues/86649 pistes : Améliorations de la compatibilité du découpage et des extensions =
Comment créer et exécuter une application .NET MAUI avec NativeAOT sur un appareil iOS avec .NET CLI
Installation
Code : | Sélectionner tout |
dotnet workload install maui
Code : | Sélectionner tout |
dotnet new maui -n HelloMaui
Les propriétés MSBuild PublishAot=true et PublishAotUsingRuntimePack=true (temporaire, voir ci-dessous) activent les déploiements NativeAOT.
Ces deux propriétés sont la seule différence notable par rapport au déploiement avec Mono. Vous devez les ajouter dans un PropertyGroup du fichier projet de votre application :
Code : | Sélectionner tout |
1 2 3 4 | <PropertyGroup> <PublishAot>true</PublishAot> <PublishAotUsingRuntimePack>true</PublishAotUsingRuntimePack> </PropertyGroup> |
Lancer votre application
Code : | Sélectionner tout |
dotnet publish -f net8.0-ios -c Release -r ios-arm64 /t:Run
Toutes les fonctionnalités d'iOS ne sont pas compatibles avec NativeAOT. De même, toutes les bibliothèques couramment utilisées dans iOS ne sont pas compatibles avec NativeAOT. .NET 8 représente le début des travaux pour activer NativeAOT pour iOS, vos commentaires nous aideront à guider nos efforts lors des aperçus de .NET 8 et au-delà, pour nous assurer que nous nous concentrons sur les endroits où les avantages de NativeAOT peuvent avoir le plus grand impact.
La liste suivante inclut certaines limitations lors du ciblage des plates-formes de type iOS qui ont été rencontrées jusqu'à présent (et ne sont donc peut-être pas la liste finale) :
- L'installation et le déploiement d'applications à l'aide de Visual Studio n'ont pas encore été testés
- L'utilisation de NativeAOT n'est activée que pendant le déploiement de l'application - dotnet publish
- La fonctionnalité de la bibliothèque Linq.Expressions n'est pas encore entièrement prise en charge
- La propriété PublishAotUsingRuntimePack=true MSBuild est une solution de contournement temporaire requise pour cibler les plates-formes de type iOS avec NativeAOT
- Cette exigence deviendra obsolète en corrigeant : https://github.com/dotnet/runtime/issues/87060
- Le débogage de code managé n'est pris en charge qu'avec Mono
REMARQUE : La liste précédente est une extension des limitations applicables à toutes les plates-formes avec NativeAOT : https://github.com/dotnet/runtime/bl...limitations.md
Résumé
.NET 8 Preview 6 contient de nouvelles fonctionnalités et améliorations passionnantes qui n'auraient pas été possibles sans le travail acharné et le dévouement d'une équipe diversifiée d'ingénieurs chez Microsoft et d'une communauté open source passionnée. Microsoft tient à remercier sincèrement tous ceux qui ont contribué à .NET 8 jusqu'à présent, que ce soit par le biais de contributions de code, de rapports de bogues ou de commentaires.
Source : Microsoft
Et vous ?
Que pensez-vous de cet aperçu de .NET 8 ? Avez-vous identifié des fonctionnalités intéressantes ?
Voir aussi :
Microsoft publie .NET 8 Preview 4, le quatrième aperçu de la dernière version du framework, et ajoute des nouvelles fonctionnalités ainsi que des améliorations passionnantes
Microsoft publie .NET 8 Preview 3, le troisième aperçu de la dernière version du framework, et inclut plusieurs changements ainsi que de nombreuses améliorations de performance
Microsoft publie .NET 8 Preview 2, le second aperçu de la dernière version du framework, et apporte plusieurs nouvelles fonctionnalités dans les bibliothèques