IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Dotnet Discussion :

Microsoft publie .NET 8 Preview 4, le quatrième aperçu de la dernière version du framework


Sujet :

Dotnet

  1. #1
    Chroniqueur Actualités
    Avatar de Anthony
    Homme Profil pro
    Rédacteur technique
    Inscrit en
    novembre 2022
    Messages
    410
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Rédacteur technique

    Informations forums :
    Inscription : novembre 2022
    Messages : 410
    Points : 6 925
    Points
    6 925
    Par défaut Microsoft publie .NET 8 Preview 4, le quatrième aperçu de la dernière version du framework
    Microsoft publie .NET 8 Preview 1, le premier aperçu de la nouvelle version du framework, et ajoute plusieurs nouveautés dont l'extension de Native AOT à plus de scénarios et le support pour Linux

    Bienvenue à .NET 8 ! Le premier aperçu est prêt à être téléchargé : demandez votre copie du premier aperçu de .NET 8 et commencez à créer des applications dès aujourd'hui. Faites défiler vers le bas pour voir la liste des fonctionnalités incluses dans cet aperçu. .NET 8 est une version de support à long terme (LTS). Ce billet de blog couvre les principaux thèmes et objectifs qui déterminent la priorité et la sélection des améliorations à développer. Les versions d'aperçu et les versions candidates de .NET 8 seront livrées tous les mois. Comme d'habitude, la version finale sera livrée en novembre à l'occasion de la conférence .NET.

    Les versions de .NET comprennent des produits, des bibliothèques, un moteur d'exécution et des outils, et représentent une collaboration entre plusieurs équipes au sein et en dehors de Microsoft. Les thèmes plus larges abordés dans ce billet de blog n'englobent pas tous les scénarios et investissements clés pour .NET 8. Ils représentent de vastes domaines, mais ne sont qu'une partie de l'ensemble des travaux importants réalisés pour .NET 8. Nous prévoyons d'importants investissements dans ASP.NET Core, Blazor, EF Core, WinForms, WPF et d'autres plateformes.

    Bienvenue à .NET 8

    À la fin de l'année dernière, nous avons livré .NET 7, le résultat d'une collaboration entre l'équipe .NET et l'incroyable communauté qui a soutenu la version avec plus de 28 000 contributions de plus de 10 000 membres de la communauté. .NET 7 est le cadre de choix pour la création d'applications aujourd'hui. La version unifie la plate-forme avec un support natif pour ARM64 et un support amélioré pour Linux. Elle contribue à la modernisation de vos applications grâce à des outils tels que .NET MAUI, qui permet de créer des applications mobiles et de bureau multiplateformes à partir de la même base de code. Il inclut des améliorations de la performance des API et facilite la création et le déploiement d'applications natives distribuées en nuage. .NET 7 simplifie l'expérience de création d'applications en réduisant la quantité de code nécessaire grâce aux améliorations apportées à C# 11 et en permettant de créer et de configurer des API avec seulement quelques lignes de code. Les nombreuses améliorations apportées aux outils, des tunnels de développement qui facilitent le débogage des intégrations d'API en nuage à la création de conteneurs directement à partir du SDK .NET, aident les développeurs à être plus productifs.

    Nous mettrons à jour les nouveautés de .NET 8 tout au long de la version. Il décrira les principales fonctionnalités de l'ensemble de la version, tandis que les articles de blog se concentreront sur les nouvelles fonctionnalités de chaque version préliminaire.

    Vous pouvez lire ce que nous avons livré dans la première version préliminaire en faisant défiler la page. Tout d'abord, jetons un coup d'œil sur ce qu'est la vision pour .NET 8.

    La meilleure plateforme et les meilleurs outils pour les développeurs natifs du cloud

    Nous pensons que les développeurs .NET doivent être en mesure de transférer rapidement leurs applications vers le cloud, de les faire évoluer sans compromettre les performances et de les faire évoluer en fonction des données et des commentaires exploitables concernant les applications en production. Nous allons investir pour faciliter la gestion de l'expérience complète de bout en bout, du développement et des tests locaux à l'intégration et au déploiement continus. Notre objectif est de faciliter la mise en œuvre d'architectures de microservices et la création et le déploiement de conteneurs.

    Une expérience formidable grâce à l'utilisation de MAUI et Blazor hybrides pour le développement multiplateforme mobile et bureau

    À l'époque de .NET 7, nous avons publié le SDK .NET Multi-platform App UI (MAUI) et la prise en charge des outils Visual Studio. .NET MAUI fournit un cadre pour la création d'applications natives pour les appareils mobiles et de bureau qui fonctionnent sous Android, iOS, macOS et Windows avec un seul code C#. Outre la prise en charge de l'interface utilisateur XAML, vous pouvez également utiliser Blazor pour créer des applications hybrides avec des composants d'interface utilisateur Razor qui peuvent accéder aux plates-formes natives des appareils et être partagés entre le mobile, le bureau et le Web. L'équipe .NET prévoit de s'appuyer sur ces expériences et de se concentrer sur l'amélioration de la qualité, de la stabilité, des performances et de l'intégration du SDK et des outils.

    Momentum : l'accent est mis sur la qualité et les performances, en fonction de vos commentaires

    Chaque version de .NET apporte des améliorations en termes de performances, de qualité, de stabilité et de facilité d'utilisation des API, des bibliothèques et des frameworks qui composent l'écosystème .NET actif et en pleine expansion. Bon nombre de ces améliorations ont été identifiées et classées par ordre de priorité par les clients et les membres de la communauté. .NET 8 suivra la même tendance, en s'appuyant sur vos commentaires très appréciés pour nous aider à guider notre vision et à nous concentrer sur nos objectifs.

    Soyez à niveau et restez à jour

    L'assistance à la mise à niveau de .NET est un outil précieux qui aide les développeurs à faire migrer leurs applications des anciennes versions de .NET Framework vers les nouvelles versions. La dernière version de cet outil est dotée de fonctionnalités améliorées qui prennent en charge de nouveaux scénarios et traitent davantage de cas. Grâce à cet outil, les développeurs peuvent désormais mettre à niveau leurs applications vers .NET 6 ou .NET 7 en toute simplicité.

    L'outil peut détecter et suggérer automatiquement les modifications à apporter au code pour assurer la compatibilité avec les nouvelles versions du framework. En outre, il peut gérer des scénarios plus complexes, comme la mise à niveau d'applications qui utilisent des bibliothèques tierces et l'intégration de nouvelles fonctionnalités de la plate-forme. Ces améliorations font de l'assistance à la mise à niveau de .NET un outil indispensable pour les développeurs qui souhaitent maintenir leurs applications à jour et tirer parti des dernières fonctionnalités de .NET. Cet outil a récemment été introduit en tant qu'extension de Visual Studio pour vous aider à effectuer la mise à niveau depuis le confort de Visual Studio.

    Cibler .NET 8

    Pour cibler .NET 8, vous devez d'abord vous assurer que le SDK .NET 8 est installé à partir du site officiel de Microsoft. Ensuite, vous pouvez créer un nouveau projet et préciser que vous souhaitez cibler .NET 8 en définissant le cadre cible approprié dans les paramètres du projet.

    Vous pouvez également mettre à jour un projet existant pour cibler .NET 8 en modifiant le cadre cible dans les propriétés du projet. Pour ce faire, cliquez avec le bouton droit de la souris sur le projet dans Visual Studio ou votre IDE préféré, sélectionnez "Propriétés", puis l'onglet "Application". À partir de là, vous pouvez choisir la version du framework cible que vous souhaitez utiliser. Ceci définira le framework cible approprié :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <TargetFramework>net8.0</TargetFramework>

    Gardez à l'esprit que cibler .NET 8 peut nécessiter des modifications de votre code ou de vos dépendances, car il peut y avoir des changements dans les API ou d'autres fonctionnalités des versions précédentes de .NET. Nous vous conseillons de consulter la documentation et les notes de mise à jour de .NET 8 pour vous assurer que votre code et vos dépendances sont compatibles avec la nouvelle version.

    Nouveautés de .NET 8 Preview 1

    Notre premier aperçu regorge de nouvelles fonctionnalités que vous pouvez essayer dès aujourd'hui. Voici un résumé de ce à quoi vous pouvez vous attendre.

    Native AOT

    Les premières fonctions NativeAOT ont été livrées dans .NET 7 et ciblaient les applications console. La compilation Ahead-of-Time (AOT) est une fonctionnalité importante de .NET qui peut avoir un impact significatif sur les performances des applications .NET. L'équipe .NET se concentrera sur l'affinage de certains éléments fondamentaux pour .NET 8 tels que la taille. La publication d'une application avec Native AOT crée une version entièrement autonome de votre application qui n'a pas besoin d'un runtime séparé car tout est inclus dans un seul fichier. Depuis l'aperçu 1, ce fichier unique est plus petit. En fait, les versions Linux sont maintenant jusqu'à 50 % plus petites.

    Voici les tailles d'une application "Hello, World" avec Native AOT qui inclut l'intégralité du runtime .NET :

    Nom : taille native aot.PNG
Affichages : 45537
Taille : 12,5 Ko

    Native AOT continuera à s'étendre et à cibler d'autres scénarios d'application dans .NET 8.

    Au cas où vous ne seriez pas familier avec AOT, voici quelques avantages qu'il procure :

    • Empreinte mémoire réduite : Le code compilé par AOT nécessite moins de mémoire que le code compilé par JIT, car le compilateur JIT génère du code intermédiaire qui n'est pas nécessaire dans les applications compilées par AOT. Cela peut être particulièrement bénéfique pour les appareils disposant d'une mémoire limitée, tels que les systèmes embarqués et les appareils mobiles.
    • Amélioration du temps de démarrage : Le code compilé par AOT démarre plus rapidement que le code compilé par JIT, car il élimine la nécessité pour le compilateur JIT de générer du code intermédiaire et d'optimiser le code pour l'environnement matériel et logiciel spécifique. Cela peut être particulièrement bénéfique pour les applications qui doivent démarrer rapidement, comme les services système, les "fonctions" sans serveur et les tâches d'arrière-plan.
    • Amélioration de l'autonomie de la batterie : Le code compilé AOT consomme moins d'énergie par rapport au code compilé JIT, car il élimine la nécessité pour le compilateur JIT de générer du code intermédiaire et d'optimiser le code pour l'environnement matériel et logiciel spécifique. Cela peut être particulièrement bénéfique pour les appareils qui dépendent des batteries, comme les appareils mobiles.

    Images de conteneurs .NET

    Les développeurs .NET peuvent utiliser des images de conteneur pour empaqueter et déployer leurs applications dans un format léger et portable qui fonctionne dans différents environnements et peut être facilement déployé dans le nuage. Le Preview 1 comprend les améliorations suivantes dans la façon dont les images de conteneurs peuvent être utilisées pour les applications .NET :

    Mise à jour de la distribution Linux par défaut vers Debian 12 : Les images de conteneurs utilisent maintenant Debian 12 (Bookworm), la version LTS (Long-term support) qui a été livrée plus tôt cette année. Afin de donner à notre communauté suffisamment de temps pour la transition, nous essayons de l'adopter avec le Preview 1.

    Changement de balisage : les images de conteneur de l'aperçu .NET 8 utiliseront le balisage 8.0-preview (et non 8.0) et passeront à 8.0 avec les versions candidates. L'objectif de cette approche est de décrire plus clairement les versions préliminaires comme telles. Ce changement a été effectué suite à une demande de la communauté.

    Exécuter les images de conteneurs avec des utilisateurs non root : Bien que les images de base des conteneurs soient presque toujours configurées pour s'exécuter avec l'utilisateur root - un paramètre qui tend à être conservé en production - ce n'est pas toujours la meilleure approche. Cependant, il est difficile de configurer chaque application pour qu'elle ait un utilisateur différent, et les images de conteneurs ne sont pas fournies avec un utilisateur non root approprié aux charges de travail des conteneurs.

    .NET 8 offre une meilleure solution. À partir de l'aperçu 1, toutes les images de conteneurs que nous publions pourront être utilisées par un utilisateur non root. Voici un exemple de la ligne unique utilisée pour exécuter un conteneur en tant que non-root pour Dockerfiles :


    En outre, vous pouvez maintenant lancer des images de conteneur avec -u app. Le port par défaut est passé du port 80 au port 8080. Il s'agit d'un changement de rupture qui était nécessaire afin d'activer le scénario non-root, puisque le port 80 est un port privilégié.

    Runtime et bibliothèques

    Méthodes utilitaires pour travailler avec l'aléatoire

    System.Random et System.Security.Cryptography.RandomNumberGenerator ont tous deux gagné des méthodes utilitaires pour choisir de manière aléatoire des éléments dans l'ensemble d'entrée ("avec remplacement"), appelées GetItems, et pour rendre aléatoire l'ordre d'une portée, appelées Shuffle.

    La méthode Shuffle est utile pour réduire le biais de formation dans l'apprentissage automatique (ainsi, la première chose n'est pas toujours la formation et la dernière chose est toujours le test) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    YourType[] trainingData = LoadTrainingData();
     
    Random.Shared.Shuffle(trainingData);
     
     
    IDataView sourceData = mlContext.Data.LoadFromEnumerable(trainingData);
     
    DataOperationsCatalog.TrainTestData split = mlContext.Data.TrainTestSplit(sourceData);
    model = chain.Fit(split.TrainSet);
     
    IDataView predictions = model.Transform(split.TestSet);
    ...

    On joue à un jeu ? Que diriez-vous de Simon ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    private static ReadOnlySpan<Button> s_allButtons = new[]
    {
        Button.Red,
        Button.Green,
        Button.Blue,
        Button.Yellow,
    };
     
    ...
     
    Button[] thisRound = Random.Shared.GetItems(s_allButtons, 31);
    // rest of game goes here ...

    System.Numerics et System.Runtime.Intrinsics

    Nous avons réimplémenté Vector256<T> pour qu'en interne il soit 2x Vector128<T> ops quand c'est possible. Cela permet une accélération partielle de certaines fonctions lorsque Vector128.IsHardwareAccelerated == true mais Vector256.IsHardwareAccelerated == false, comme sur Arm64.

    Ajout de l'implémentation gérée initiale de Vector512<T>. Tout comme l'élément de travail précédent, ceci est implémenté de manière interactive comme 2x Vector256<T> ops (et donc indirectement comme 4x Vector128 ops). Cela permet une accélération partielle de certaines fonctions même lorsque Vector512.IsHardwareAccelerated == false.
    - NOTE : Il n'y a pas encore d'accélération directe pour Vector512, même si le matériel sous-jacent le supporte. Une telle fonctionnalité devrait être activée dans un futur aperçu.

    Réécriture de Matrix3x2 et Matrix4x4 pour mieux profiter de l'accélération matérielle. Cela a permis d'améliorer les performances jusqu'à 48 fois pour certains benchmarks. Des améliorations de 6 à 10 fois étaient plus courantes.
    - NOTE : Des améliorations pour Quaternion et Plane seront apportées dans la Preview 2.

    Les Intrinsèques matérielles sont maintenant annotées avec l'attribut ConstExpected. Cela permet aux utilisateurs de savoir quand le matériel sous-jacent attend une constante et donc quand une valeur non constante peut nuire aux performances de manière inattendue.

    Ajout de l'API Lerp à IFloatingPointIeee754<TSelf> et donc à float (System.Single), double (System.Double), et System.Half. Cela permet d'effectuer efficacement et correctement une interpolation linéaire entre deux valeurs.

    Améliorations de JSON

    Nous continuons à améliorer System.Text.Json, en nous concentrant sur l'amélioration des performances et de la fiabilité du générateur de code source s'il est utilisé avec ASP.NET Core dans les applications NativeAOT. La liste suivante présente les nouvelles fonctionnalités livrées avec l'aperçu 1 :

    • Gestion des membres manquants

    Il est maintenant possible de configurer le comportement de désérialisation des objets, lorsque la charge utile JSON sous-jacente comprend des propriétés qui ne peuvent pas être mappées à des membres du type POCO désérialisé. Ceci peut être contrôlé en définissant une valeur JsonUnmappedMemberHandling, soit en tant qu'annotation sur le type POCO lui-même, globalement sur JsonSerializerOptions ou programmatiquement en personnalisant le contrat JsonTypeInfo pour les types concernés :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    JsonSerializer.Deserialize<MyPoco>("""{"Id" : 42, "AnotherId" : -1 }"""); 
     
    // JsonException : The JSON property 'AnotherId' could not be mapped to any .NET member contained in type 'MyPoco'.
     
    [JsonUnmappedMemberHandling(JsonUnmappedMemberHandling.Disallow)]
    public class MyPoco
    {
       public int Id { get; set; }
    }

    • Support du générateur de sources pour les propriétés required et init

    Le générateur de sources prend désormais en charge la sérialisation des types avec des propriétés required et init, comme c'est actuellement le cas dans la sérialisation basée sur la réflexion.

    • Prise en charge de la hiérarchie des interfaces

    System.Text.Json prend désormais en charge la sérialisation des propriétés des hiérarchies d'interface :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    IDerived value = new Derived { Base = 0, Derived =1 };
     
    JsonSerializer.Serialize(value); // {"Base":0,"Derived":1}
     
    public interface IBase
    {
      public int Base { get; set; }
    }
     
    public interface IDerived : IBase
    {
      public int Derived { get; set; }
    }
     
    public class Derived : IDerived
    {
      public int Base { get; set; }
      public int Derived { get; set; }
    }

    • Snake Case et Kebab Case

    La bibliothèque est maintenant livrée avec des politiques de nommage pour les conversions de noms de propriétés snake_case et kebab-case. Elles peuvent être utilisées de la même manière que la politique de nommage existante camelCase :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower };
     
    JsonSerializer.Serialize(new { PropertyName = "value" }, options); // { "property_name" : "value" }

    Les politiques de nommage suivantes sont maintenant disponibles :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    namespace System.Text.Json;
     
    public class JsonNamingPolicy
    {
      public static JsonNamingPolicy CamelCase { get; }
      public static JsonNamingPolicy KebabCaseLower { get; }
      public static JsonNamingPolicy KebabCaseUpper { get; }
      public static JsonNamingPolicy SnakeCaseLower { get; }
      public static JsonNamingPolicy SnakeCaseUpper { get; }
    }

    • Ajout des API JsonSerializer.MakeReadOnly() et IsReadOnly

    La classe JsonSerializerOptions a toujours utilisé la sémantique du gel, mais jusqu'à présent, le gel ne pouvait être effectué qu'implicitement en passant l'instance à l'une des méthodes JsonSerializer. L'ajout des nouvelles API permet aux utilisateurs de contrôler explicitement quand leur instance JsonSerializerOptions doit être gelée :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public class MySerializer
    {
      private JsonSerializerOptions Options { get; }
     
      public MySerializer()
      {
            Options = new JsonSerializerOptions(JsonSerializerDefaults.Web) { Converters = { new MyCustomConverter() } };
            Options.MakeReadOnly(); // Make read-only before exposing the property.
      }
    }

    Nouveaux types axés sur les performances dans les bibliothèques de base
    Plusieurs nouveaux types ont été ajoutés aux bibliothèques de base pour permettre aux développeurs d'améliorer les performances de leur code dans des scénarios courants.

    Le nouvel espace de noms System.Collections.Frozen fournit des collections FrozenDictionary<TKey, TValue> et FrozenSet<T>. Ces types fournissent une surface immuable telle que, une fois créée, aucune modification n'est autorisée sur les clés ou les valeurs. Cela permet aux collections de mieux optimiser les opérations de lecture ultérieures (par exemple, TryGetValue) en fonction des données fournies, en choisissant de prendre plus de temps lors de la construction pour optimiser tous les accès futurs. Ceci est particulièrement utile pour les collections alimentées lors de la première utilisation et ensuite persistées pour la durée d'un service à longue durée de vie, par exemple.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    private static readonly FrozenDictionary<string, bool> s_configurationData =
     
        LoadConfigurationData().ToFrozenDictionary(optimizeForReads: true);
    ...
    if (s_configurationData.TryGetValue(key, out bool setting) && setting)
    {
        Process();
    }

    Le type existant ImmutableArray<T>.Builder a également gagné une nouvelle méthode pour convertir efficacement son contenu en un ImmutableArray<T>. .NET 8 introduit DrainToImmutable(), qui renvoie le contenu actuel sous forme de tableau immuable et réinitialise la collection du constructeur à un tableau de longueur nulle, en choisissant l'approche la plus efficace pour ce faire. Cette méthode peut être utilisée au lieu d'appeler conditionnellement ToImmutable() ou MoveToImmutable() en fonction du nombre d'éléments.

    Le nouveau type IndexOfAnyValues<T> est un autre exemple de nouveau type qui aide le développeur à investir un peu de temps au départ en échange d'une exécution beaucoup plus rapide par la suite. En plus de nouvelles méthodes comme IndexOfAnyInRange, de nouvelles surcharges de IndexOfAny ont été ajoutées et acceptent une instance IndexOfAnyValues<T>, qui peut être créée pour représenter un ensemble de valeurs T à rechercher. La création de cette instance permet de dériver toutes les données nécessaires afin d'optimiser les recherches ultérieures. Par exemple, si vous recherchez régulièrement toutes les lettres et tous les chiffres ASCII, ainsi que quelques caractères de ponctuation, vous auriez pu écrire précédemment :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    private static readonly char[] s_chars = "-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz".ToCharArray();
    ...
    int i = str.IndexOfAny(s_chars);

    Cependant, cela nécessite soit de ne faire aucune sorte de vectorisation pour améliorer l'efficacité de la recherche, soit de prendre du temps à chaque invocation d'IndexOfAny pour calculer l'état nécessaire pour accélérer l'opération. Maintenant, au lieu de cela, il peut être écrit comme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    private static readonly IndexOfAnyValues<char> s_chars = IndexOfAnyValues.Create("-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz");
    ...
    int i = str.AsSpan().IndexOfAny(s_chars);

    précalculer tout cet état une fois de telle sorte qu'il soit disponible pour être réutilisé à chaque invocation ultérieure de IndexOfAny.
    Ce schéma se répète à nouveau avec le nouveau type CompositeFormat. .NET prend depuis longtemps en charge le formatage des chaînes de caractères par le biais d'API telles que string.Format et StringBuilder.AppendFormat, par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    static string GetMessage(int min, int max) => 
        string.Format(CultureInfo.InvariantCulture, "Range from {0} to {1}", min, max);

    C# 6 a ajouté la prise en charge de l'interpolation de chaînes de caractères, puis C# 10, en conjonction avec .NET 6, a considérablement amélioré l'efficacité de ces opérations, permettant d'écrire la même opération sous la forme suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    static string GetMessage(int min, int max) =>
        string.Create(CultureInfo.InvariantCulture, $"Range from {min} to {max}");

    mais en effectuant tout le travail qui peut être précalculé (par exemple, l'analyse de la chaîne de format) au moment de la compilation plutôt qu'à chaque invocation de string.Format. Cependant, cela nécessite que la chaîne de format soit connue au moment de la compilation afin qu'elle puisse être analysée au moment de la compilation... qu'en est-il si elle n'est pas connue avant l'exécution, par exemple si elle est chargée à partir d'un fichier de ressources ou d'un autre moyen dynamique ? Pour cela, .NET 8 ajoute le type CompositeFormat. Comme pour IndexOfAnyValues<T>, il permet d'effectuer une opération qui, autrement, devrait être réalisée à chaque utilisation, et de l'extraire pour la réaliser une seule fois.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    private static readonly CompositeFormat s_rangeMessage = CompositeFormat.Parse(LoadRangeMessageResource());
    ...
    static string GetMessage(int min, int max) =>
        string.Format(CultureInfo.InvariantCulture, s_rangeMessage, min, max);

    Ces nouvelles surcharges prennent également en charge les arguments génériques, afin d'éviter les surcharges de mise en boîte associées au fait de tout prendre comme object.

    .NET 8 Preview 1 prend également en charge de nouveaux algorithmes de hachage axés sur les performances, notamment les nouveaux types XxHash3 et XxHash128 qui fournissent des implémentations des algorithmes de hachage rapides XXH3 et XXH128.

    SDK .NET

    dotnet publish et dotnet pack produisent des actifs Release par défaut

    Les verbes Publish et Pack sont destinés à produire des actifs de production, ce qui signifie qu'ils doivent produire des actifs de version. Dans .NET 8, ils le feront par défaut. Les gens demandaient cela depuis un certain temps. Désolé que cela ait pris tant de temps !

    Cette fonctionnalité est contrôlée par les propriétés booléennes PublishRelease et PackRelease. Elles ont la valeur true par défaut.

    Il est plus facile de démontrer cette fonctionnalité avec dotnet publish :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    /app# dotnet new console
     
    /app# dotnet build
      app -> /app/bin/Debug/net8.0/app.dll
    /app# dotnet publish
      app -> /app/bin/Release/net8.0/app.dll
      app -> /app/bin/Release/net8.0/publish/
    /app# dotnet publish -p:PublishRelease=false
      app -> /app/bin/Debug/net8.0/app.dll
      app -> /app/bin/Debug/net8.0/publish/

    Notez que PublishRelease et PackRelease existent également dans .NET 7 à partir du SDK 7.0.200. Elles sont optionnelles dans .NET 7 et doivent être définies sur true pour fournir le même comportement.

    Support Linux

    Construisez votre propre .NET à partir de dotnet/dotnet

    .NET peut maintenant être construit sous Linux directement à partir du dépôt dotnet/dotnet. Il utilise dotnet/source-build pour construire les moteurs d'exécution, les outils et les SDK .NET. Il s'agit du même build que Red Hat et Canonical utilisent pour construire .NET, par exemple. Au fil du temps, nous l'étendrons pour prendre en charge macOS et Windows.

    La construction dans un conteneur sera l'approche la plus facile pour de nombreuses personnes, puisque nos images de conteneur dotnet-buildtools/prereqs contiennent toutes les dépendances requises.

    Nous appelons ce nouveau référentiel "Virtual Mono Repository" (VMR). Il présente les avantages d'un vrai dépôt mono mais est une projection régulièrement mise à jour des nombreux dépôts existants dans lesquels les contributeurs travaillent (plus efficacement) chaque jour. Nous pensons que la séparation entre le VMR et les "working repos" beaucoup plus petits est l'avenir du projet .NET. Nous pensons que les fonctionnalités transversales seront plus faciles à construire dans le VMR, mais nous n'en sommes pas encore là.

    Nous considérons cette nouvelle approche comme une avancée significative dans l'accessibilité à la construction de .NET en tant que produit complet à partir des sources.

    Avant .NET 8, la construction à partir de la source était possible, mais nécessitait la création d'un "tarball source" à partir du commit dotnet/installer qui correspondait à une version. Cela n'est plus nécessaire. Le dépôt aura des balises correspondant à chaque version, ainsi que les branches main et release/8.0-previewN qui suivent continuellement l'état du produit.

    .NET 8 + images de conteneurs Ubuntu Chiseled

    Nous publions des images Ubuntu Chiseled avec .NET 8. Ce type d'image est destiné aux développeurs qui souhaitent bénéficier des avantages de l'informatique de type appliance, encore plus qu'avec les conteneurs ordinaires. Nous nous attendons à ce que les images ciselées Ubuntu soient prises en charge en production par Canonical et Microsoft au moment de la sortie de .NET 8.

    Nous prévoyons de livrer les images dotnet/monitor exclusivement en tant qu'Ubuntu Chiseled, à partir de .NET 8. C'est remarquable car les images de moniteurs sont les seules images d'applications de production que nous publions.

    Les images ciselées présentent de nombreux avantages :

    • Images ultra-petites (taille et surface d'attaque réduites)
    • Pas de gestionnaire de paquets (évite toute une catégorie d'attaques)
    • Pas de shell (évite toute une série d'attaques)
    • Non-root (évite toute une classe d'attaques)

    Les images ciselées sont actuellement publiées dans nos dépôts nocturnes, pour les versions .NET 6 et .NET 7.

    Support Linux et cible de la baseline

    Nous mettons à jour nos baselines minimales pour Linux pour .NET 8. Il y a trois changements notables.

    • Le produit .NET sera construit en ciblant Ubuntu 16.04, pour toutes les architectures. C'est principalement important pour définir la version minimale de la glibc pour .NET 8. Par exemple, à cause de ce changement, .NET 8 ne pourra même pas démarrer sur Ubuntu 14.04, par exemple.
    • Pour Red Hat Enterprise Linux (RHEL), nous prendrons en charge RHEL 8+, en abandonnant RHEL 7.
    • Nous ne publierons une déclaration de prise en charge que pour RHEL, mais nous souhaitons que cette prise en charge s'applique aux autres distributions de l'écosystème RHEL.

    Il n'y a pas d'autres changements significatifs. Nous continuerons à prendre en charge Linux sur les architectures Arm32, Arm64 et x64.

    Notez que ces changements ne s'appliquent qu'à la version Microsoft. Les organisations qui utilisent la construction à la source feront des choix différents, produisant généralement une construction pour et qui ne fonctionne qu'avec une seule version de distro, comme Ubuntu 24.04.

    Ce qui suit présente la version de la glibc d'Ubuntu 16.04 et un modèle pour la découvrir pour d'autres distros.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    $ docker run --rm ubuntu:16.04 ldd --version
    ldd (Ubuntu GLIBC 2.23-0ubuntu11.3) 2.23
    Copyright (C) 2016 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions.  There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    Written by Roland McGrath and Ulrich Drepper.

    Clôture

    En conclusion, .NET 8 Preview 1 est un témoignage de la puissance de la collaboration entre une équipe diversifiée d'ingénieurs chez Microsoft et une communauté open source très engagée. Les nouvelles fonctionnalités et les améliorations de .NET 8 sont le résultat direct du travail acharné et du dévouement de cette communauté, et nous sommes incroyablement reconnaissants de la contribution de chacun.

    Nous sommes fiers de faire partie d'une communauté qui valorise l'inclusion et la diversité, et nous nous engageons à construire un écosystème technologique accessible à tous. Nous sommes convaincus qu'en travaillant ensemble, nous pouvons réaliser de grandes choses, et nous sommes impatients de voir ce que l'avenir réserve à .NET.

    Nous tenons à remercier sincèrement tous ceux qui ont contribué à .NET 8 jusqu'à présent, que ce soit par des contributions de code, des rapports de bogue ou des commentaires. Vos contributions ont été déterminantes pour faire de .NET 8 Preview 1 une réalité, et nous sommes impatients de continuer à travailler ensemble pour construire un avenir meilleur pour .NET et l'ensemble de la communauté technologique.

    Source : Microsoft

    Et vous ?

    Que pensez-vous des nouveautés apportées par ce premier aperçu de .NET 8 ?

    Voir aussi :

    .NET 7 est maintenant disponible en tant que plateforme de développement unifiée de Microsoft, et apporte des améliorations pour .NET MAUI et le support de .NET pour ARM64
    Microsoft annonce la première version candidate de .NET 7, testé avec Visual Studio 17.4 Preview 2
    Microsoft publie .NET 7 Preview 7, le dernier aperçu de la nouvelle version du framework avant la sortie de la première version candidate, cet aperçu apporte de nouvelles améliorations au framework
    Contribuez au club : corrections, suggestions, critiques, ... Contactez le service news et Rédigez des actualités

  2. #2
    Chroniqueur Actualités
    Avatar de Anthony
    Homme Profil pro
    Rédacteur technique
    Inscrit en
    novembre 2022
    Messages
    410
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Rédacteur technique

    Informations forums :
    Inscription : novembre 2022
    Messages : 410
    Points : 6 925
    Points
    6 925
    Par défaut Microsoft publie .NET 8 Preview 2, le second aperçu de la dernière version du framework
    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

    Nous sommes ravis de vous présenter les nouveautés de .NET 8 Preview 2. Cette version est un suivi rapide de l'aperçu 1, plus volumineux. Vous continuerez à voir beaucoup plus de fonctionnalités apparaître avec ces versions mensuelles. Les utilisateurs de .NET 6 et 7 voudront suivre cette version de près. Nous nous sommes efforcés de faire en sorte qu'il s'agisse d'un parcours de mise à niveau simple.

    Vous pouvez télécharger .NET 8 Preview 2 pour Linux, macOS et Windows.

    .NET 8 a été testé avec la version 17.6 Preview 2. Nous vous recommandons d'utiliser les builds du canal de prévisualisation si vous souhaitez essayer .NET 8 avec la famille de produits Visual Studio. La prise en charge de .NET 8 par Visual Studio pour Mac n'est pas encore disponible.

    Jetons un coup d'œil à quelques nouvelles fonctionnalités.

    Nom : dotnet-8-preview-2.png
Affichages : 15146
Taille : 111,9 Ko

    Bibliothèques

    Les nouvelles fonctionnalités de la Preview 2 se trouvent dans les bibliothèques.

    Extensions de System.ComponentModel.DataAnnotations

    Nous avons introduit des extensions aux attributs de validation intégrés dans System.ComponentModel.DataAnnotations.

    RequiredAttribute.DisallowAllDefaultValues
    L'attribut RequiredAttribute permet désormais de valider que les structures ne sont pas égales à leurs valeurs par défaut. Par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    [Required(DisallowAllDefaultValues = true)]
    public Guid MyGuidValue { get; set; }

    Cet exemple échouera à la validation si sa valeur est égale à Guid.Empty.

    Limites exclusives de RangeAttribute
    Les utilisateurs peuvent désormais spécifier des bornes exclusives dans leur validation de plage :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    [Range(0d, 1d, MinimumIsExclusive = true, MaximumIsExclusive = true)]
    public double Sample { get; set; }

    Cet attribut accepte toutes les valeurs de l'intervalle ouvert mais rejette les valeurs limites 0 et 1.

    LengthAttribute
    L'attribut LengthAttribute peut désormais être utilisé pour définir les limites inférieures et supérieures des chaînes ou des collections :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    [Length(10, 20)] // Require at least 10 elements and at most 20 elements.
    public ICollection<int> Values { get; set; }

    AllowedValuesAttribute et DeniedValuesAttribute
    Ces attributs peuvent être utilisés pour spécifier des listes d'autorisation et de refus pour la validation d'une propriété :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    [AllowedValues("apple", "banana", "mango")]
    public string Fruit { get; set; }
     
    [DeniedValues("pineapple", "anchovy", "broccoli")]
    public string PizzaTopping { get; set; }

    Base64StringAttribute
    Comme son nom l'indique, cet attribut permet de valider qu'une chaîne donnée est une représentation Base64 valide.

    System.Reflection : prise en charge de l'introspection pour les pointeurs de fonction

    Les pointeurs de fonction ont été ajoutés dans le cadre de .NET 5 et C# 9, mais nous n'avons pas ajouté d'expérience correspondante pour la fonctionnalité dans Reflection. Cette nouvelle fonctionnalité permet d'obtenir les métadonnées des pointeurs de fonction via Reflection, notamment les types de paramètres, le type de retour et les conventions d'appel. Auparavant, le type IntPtr était utilisé pour un type de pointeur de fonction tel que typeof(delegate*<void>()) ou lors de l'obtention d'un type de pointeur de fonction par réflexion tel que FieldInfo.FieldType.

    Une instance de pointeur de fonction, qui est l'adresse physique d'une fonction, continue d'être représentée comme un IntPtr ; seul le type de réflexion a été modifié avec cette fonctionnalité. Cette nouvelle fonctionnalité est actuellement mise en œuvre dans le moteur d'exécution CoreCLR et dans MetadataLoadContext. La prise en charge des runtimes Mono et NativeAOT est prévue ultérieurement.

    Un exemple utilisant la réflexion :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    37
    38
    39
    40
    41
    42
    43
    FieldInfo fieldInfo = typeof(MyClass).GetField(nameof(MyClass._fp));
     
    // Obtain the function pointer type from a field. This used to be the 'IntPtr' type, now it's 'Type':
    Type fpType = fieldInfo.FieldType;
     
    // New methods to determine if a type is a function pointer:
    Console.WriteLine(fpType.IsFunctionPointer); // True
    Console.WriteLine(fpType.IsUnmanagedFunctionPointer); // True
     
    // New methods to obtain the return and parameter types:
    Console.WriteLine($"Return type: {fpType.GetFunctionPointerReturnType()}"); // System.Void
     
    foreach (Type parameterType in fpType.GetFunctionPointerParameterTypes())
    {
        Console.WriteLine($"Parameter type: {parameterType}"); // System.Int32&
    }
     
    // Access to custom modifiers and calling conventions requires a "modified type":
    Type modifiedType = fieldInfo.GetModifiedFieldType();
     
    // A modified type forwards most members to its underlying type which can be obtained with Type.UnderlyingSystemType:
    Type normalType = modifiedType.UnderlyingSystemType;
     
    // New methods to obtain the calling conventions:
    foreach (Type callConv in modifiedType.GetFunctionPointerCallingConventions())
    {
        Console.WriteLine($"Calling convention: {callConv}");
        // System.Runtime.CompilerServices.CallConvSuppressGCTransition
        // System.Runtime.CompilerServices.CallConvCdecl
    }
     
    // New methods to obtain the custom modifiers:
    foreach (Type modreq in modifiedType.GetFunctionPointerParameterTypes()[0].GetRequiredCustomModifiers())
    {
        Console.WriteLine($"Required modifier for first parameter: {modreq }");
        // System.Runtime.InteropServices.InAttribute
    }
     
    // Sample class that contains a function pointer field:
    public unsafe class MyClass
    {
        public delegate* unmanaged[Cdecl, SuppressGCTransition]<in int, void> _fp;
    }

    Les types paramétrés, y compris les types génériques, les pointeurs et les tableaux tels qu'un tableau de pointeurs de fonctions (par exemple delegate*<void>[]) sont pris en charge. Ainsi, la propriété Type.ElementType et la méthode Type.GetGenericArguments() peuvent être utilisées pour obtenir d'autres types qui, en fin de compte, peuvent être des pointeurs de fonction. En outre, un type de paramètre pointeur de fonction est autorisé à être un autre type de pointeur de fonction.

    Conclusion

    L'avant-première 2 de .NET 8 offre une gamme courte mais passionnante de mises à jour de thèmes, de nouvelles fonctionnalités et d'améliorations.

    Nous tenons à remercier sincèrement tous ceux qui ont contribué à .NET 8 jusqu'à présent, que ce soit par des contributions au code, des rapports de bogues ou des commentaires. Vos contributions ont joué un rôle déterminant dans la réalisation des avant-premières de .NET 8, et nous sommes impatients de continuer à travailler ensemble pour construire un avenir meilleur pour .NET et l'ensemble de la communauté technologique.

    Source : Microsoft

    Et vous ?

    Qu'en pensez-vous ?

    Voir aussi :

    Microsoft publie .NET 8 Preview 1, le premier aperçu de la nouvelle version du framework, et ajoute plusieurs nouveautés dont l'extension de Native AOT à plus de scénarios et le support pour Linux

    Microsoft dévoile les mises à jour apportées à ASP.NET Core dans .NET 8 Preview 2, dont l'ajout de Blazor QuickGrid et de plusieurs améliorations de performance

    .NET 7 est maintenant disponible en tant que plateforme de développement unifiée de Microsoft, et apporte des améliorations pour .NET MAUI et le support de .NET pour ARM64
    Contribuez au club : corrections, suggestions, critiques, ... Contactez le service news et Rédigez des actualités

  3. #3
    Chroniqueur Actualités
    Avatar de Anthony
    Homme Profil pro
    Rédacteur technique
    Inscrit en
    novembre 2022
    Messages
    410
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Rédacteur technique

    Informations forums :
    Inscription : novembre 2022
    Messages : 410
    Points : 6 925
    Points
    6 925
    Par défaut Microsoft publie .NET 8 Preview 3, le troisième aperçu de la dernière version du framework
    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

    L'aperçu 3 de .NET 8 est désormais disponible. Elle inclut des changements dans les chemins de génération, les charges de travail, les Microsoft.Extensions et les conteneurs. Elle inclut également des améliorations de performance dans le JIT, pour Arm64, et le PGO dynamique. Si vous avez manqué l'aperçu de mars, vous pouvez lire l'article sur l'aperçu 2.

    Vous pouvez télécharger .NET 8 Preview 3 pour Linux, macOS et Windows.

    .NET 8 a été testé avec la version 17.6 Preview 3. Si vous souhaitez essayer .NET 8 avec la famille de produits Visual Studio, nous vous recommandons d'utiliser les builds du canal de prévisualisation. La prise en charge de .NET 8 par Visual Studio for Mac n'est pas encore disponible.

    Jetons un coup d'œil à quelques-unes des nouvelles fonctionnalités.

    Nom : dotnet-8-preview-3.png
Affichages : 31968
Taille : 175,4 Ko

    SDK

    Plusieurs améliorations ont été apportées au SDK, ainsi qu'une modification majeure.

    Les améliorations apportées au SDK .NET sont les suivantes :

    Chemin de sortie simplifié

    Les applications .NET peuvent être construites de différentes manières et, par conséquent, les utilisateurs de la plateforme se sont familiarisés avec un ensemble très profond et complexe de chemins de sortie pour différents artefacts de construction. Des dossiers tels que bin, obj, publish, et les nombreuses permutations et dispositions différentes de ceux-ci constituent la mémoire musculaire de nombreux développeurs .NET. Le concept de répertoires par projet pour ces sorties est tout aussi fort. Cependant, au fil du temps, nous avons reçu des commentaires de la part d'utilisateurs de longue date et de nouveaux utilisateurs de .NET, selon lesquels cette disposition est :

    • Difficile à utiliser parce que la disposition peut changer radicalement par le biais de modifications relativement simples de MSBuild.
    • Difficile pour les outils d'anticiper car la disposition par projet ne permet pas de s'assurer que vous avez obtenu les sorties pour chaque projet.

    Pour relever ces deux défis et rendre les sorties de compilation plus faciles à utiliser et plus cohérentes, le SDK .NET a introduit une option qui crée une structure de chemin de sortie plus unifiée et simplifiée.

    Le nouveau chemin de sortie se concentre sur :

    • Le rassemblement de toutes les sorties de compilation dans un emplacement commun.
    • La séparation des sorties de compilation par projet dans cet emplacement commun.
    • L'aplatissement de la structure globale des sorties de compilation à un maximum de trois niveaux de profondeur.

    Pour opter pour la nouvelle disposition des chemins de sortie, vous devez définir la propriété UseArtifactsOutput dans un fichier Directory.Build.props. La façon la plus simple de commencer est d'exécuter dotnet new buildprops à la racine de votre référentiel, d'ouvrir le fichier Directory.Build.props généré, puis d'ajouter ce qui suit au PropertyGroup de ce fichier :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <UseArtifactsOutput>true</UseArtifactsOutput>

    À partir de ce moment, la sortie de la compilation pour tous les projets sera placée dans le répertoire .artifacts à la racine du référentiel. Ceci est configurable - il suffit de définir la propriété ArtifactsPath dans votre fichier Directory.Build.props à n'importe quel répertoire que vous préférez. Si vous ne souhaitez pas utiliser .artifacts par défaut, nous serions ravis d'entendre vos commentaires lors de la discussion sur la conception.

    La disposition du répertoire .artifacts sera de la forme <ArtifactsPath>\<Type de sortie>\<Nom du projet>\<Pivots>, où :

    • Type of Output est utilisé pour regrouper différentes catégories de sorties de compilation comme les binaires, les fichiers intermédiaires/générés, les applications publiées ou les paquets NuGet, et
    • Pivots est utilisé pour aplanir toutes les différentes options qui sont utilisées pour différencier les builds, comme Configuration et RuntimeIdentifier.

    Voici quelques exemples de chemins qui seraient créés sous le nouveau format :

    • .artifacts\bin\debug - Le chemin de sortie de la compilation pour un projet simple lorsque vous exécutez dotnet build.
    • .artifacts\obj\debug - Le chemin de sortie intermédiaire pour un projet simple lorsque vous exécutez dotnet build.
    • .artifacts\bin\MyApp\debug_net8.0 - Le chemin de sortie de la compilation pour la compilation net8.0 d'un projet multi-cibles.
    • .artifacts\publish\MyApp\release_linux-x64 - Le chemin de publication pour une application simple lors de la publication pour linux-x64.
    • .artifacts\package\release - Le dossier dans lequel la version .nupkg sera créée pour un projet.

    Nous pensons que cette structure de sortie unifiée répond aux préoccupations que nous avons entendues de la part des utilisateurs et nous donne une base sur laquelle nous pouvons construire pour l'avenir. Les sections Type of Output et Pivots nous permettent d'ajouter de nouveaux types de sorties ou de constructions sans modifier radicalement la présentation à l'avenir. L'ancrage de toutes les sorties dans un seul dossier facilite l'inclusion, l'ignorance ou la manipulation des sorties de construction par les outils. Nous aimerions connaître votre expérience de l'activation et de l'utilisation de la nouvelle présentation dans le cadre de cette enquête SurveyMonkey.

    Commande dotnet workload clean

    Au fil des mises à jour du SDK .NET et de Visual Studio, il est possible que les workload packs (les unités de fonctionnalité, les outils et les modèles qui composent une charge de travail) soient oubliés. Cela peut se produire pour un certain nombre de raisons, mais dans tous les cas, c'est une source de confusion pour les utilisateurs finaux. Certains utilisateurs vont jusqu'à supprimer manuellement les répertoires de charge de travail de leur emplacement d'installation du SDK, ce que l'équipe SDK ne recommande vraiment pas ! Au lieu de cette mesure drastique, nous avons implémenté dans cette version préliminaire une nouvelle commande pour aider à nettoyer les packs de charge de travail restants.

    La nouvelle commande est la suivante :


    La prochaine fois que vous rencontrerez des problèmes dans la gestion des charges de travail, pensez à utiliser dotnet workload clean pour restaurer en toute sécurité un état connu avant de réessayer.

    clean a deux modes d'opération, qui sont discutés ci-dessous.

    dotnet workload clean

    Exécute le garbage collection de la charge de travail pour les charges de travail basées sur des fichiers ou des MSI. Dans ce mode, le garbage collection se comporte normalement, nettoyant uniquement les paquets orphelins eux-mêmes.

    Il nettoiera les paquets orphelins provenant de versions désinstallées du SDK .NET ou de paquets pour lesquels les enregistrements d'installation n'existent plus. Il ne le fera que pour la version donnée du SDK ou pour une version plus ancienne. Si une version plus récente du SDK est installée, vous devrez répéter la commande.

    Si Visual Studio est installé et gère également des charges de travail, dotnet workload clean répertorie toutes les charges de travail Visual Studio installées sur la machine et signale qu'elles doivent être désinstallées via Visual Studio plutôt que via l'interface de gestion du SDK .NET. Cela permet de comprendre pourquoi certaines charges de travail ne sont pas nettoyées/désinstallées après l'exécution de dotnet workload clean.

    dotnet workload clean --all

    Contrairement à workload clean, workload clean --all exécute le garbage collection de manière irrégulière, ce qui signifie qu'il nettoie chaque pack existant sur la machine qui ne provient pas de Visual Studio et qui est du type d'installation de la charge de travail SDK actuelle (soit basée sur des fichiers, soit basée sur MSI).

    Pour cette raison, il supprime également tous les enregistrements d'installation de charge de travail pour la bande de fonctionnalités du SDK .NET en cours d'exécution et les bandes inférieures. workload clean ne supprime pas encore les enregistrements d'installation, car les manifestes sont actuellement le seul moyen de faire correspondre un pack à l'ID de la charge de travail, mais les fichiers manifests peuvent ne pas exister pour les packs orphelins.

    Exécution

    Les améliorations suivantes ont été apportées au moteur d'exécution et aux bibliothèques.

    ValidateOptionsResultBuilder

    Le ValidateOptionsResultBuilder facilite la création d'un objet ValidateOptionsResult, qui est nécessaire pour implémenter IValidateOptions.Validate(String, TOptions). Ce constructeur vous permet d'accumuler plusieurs erreurs, ce qui vous permet de voir tous les problèmes en même temps et de les résoudre en conséquence. Grâce à ce nouvel outil, vous gagnerez du temps et de l'énergie en rationalisant le processus de validation.

    Voici un exemple d'utilisation :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    ValidateOptionsResultBuilder builder = new();
    builder.AddError("Error: invalid operation code");
    builder.AddResult(ValidateOptionsResult.Fail("Invalid request parameters"));
    builder.AddError("Malformed link", "Url");
     
    // Build ValidateOptionsResult object has accumulating multiple errors.
    ValidateOptionsResult result = builder.Build();
     
    // Reset the builder to allow using it in new validation operation.
    builder.Clear();

    Présentation du générateur de source de liaison de configuration

    La configuration d'une application dans ASP.NET Core est réalisée à l'aide d'un ou plusieurs fournisseurs de configuration. Les fournisseurs de configuration lisent des données (sous forme de paires clé-valeur) à partir d'une variété de sources telles que les fichiers de paramètres (par exemple, appsettings.json), les variables d'environnement, Azure Key Vault, etc.

    Au cœur de ce mécanisme se trouve ConfigurationBinder, une classe d'extension qui fournit les méthodes Bind et Get qui mappent les valeurs de configuration (instances IConfiguration) vers des objets fortement typés. Bind prend une instance, tandis que Get en crée une pour le compte de l'appelant. L'approche actuelle utilise la réflexion, ce qui pose des problèmes pour l'élagage et l'AOT natif.

    Dans .NET 8, nous utilisons un générateur de source qui génère des implémentations de liaison sans réflexion et compatibles avec AOT. Le générateur recherche les appels Configure, Bind et Get à partir desquels nous pouvons récupérer des informations sur les types.

    L'exemple suivant montre un code qui invoque la liaison :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    using Microsoft.AspNetCore.Builder;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.DependencyInjection;
     
    WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
    IConfigurationSection section = builder.Configuration.GetSection("MyOptions");
     
    // !! Configure call - to be replaced with source-gen'd implementation
    builder.Services.Configure<MyOptions>(section);
     
    // !! Get call - to be replaced with source-gen'd implementation
    MyOptions options0 = section.Get<MyOptions>();
     
    // !! Bind call - to be replaced with source-gen'd implementation
    MyOptions options1 = new MyOptions();
    section.Bind(myOptions1);
     
    WebApplication app = builder.Build();
    app.MapGet("/", () => "Hello World!");
    app.Run();
     
    public class MyOptions
    {
        public int A { get; set; }
        public string S { get; set; }
        public byte[] Data { get; set; }
        public Dictionary<string, string> Values { get; set; }
        public List<MyClass> Values2 { get; set; }
    }
     
    public class MyClass
    {
        public int SomethingElse { get; set; }
    }

    Lorsque le générateur est activé dans un projet, les méthodes générées sont implicitement choisies par le compilateur, au détriment des implémentations préexistantes du framework basées sur la réflexion. Pour activer le générateur de source, téléchargez la dernière version preview de Microsoft.Extensions.Configuration.Binder. Le générateur est désactivé par défaut. Pour l'utiliser, ajoutez la propriété suivante à votre fichier de projet :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    <PropertyGroup>
        <EnableMicrosoftExtensionsConfigurationBinderSourceGenerator>true</EnableMicrosoftExtensionsConfigurationBinderSourceGenerator>
    </PropertyGroup>
    Dans l'aperçu 4, nous ajouterons le mécanisme d'activation au SDK .NET, de sorte que la référence du paquet NuGet ne soit pas nécessaire pour utiliser le générateur de source.

    Conteneurs

    Nous continuons à améliorer les capacités et l'expérience d'utilisation de .NET dans les conteneurs. Dans cette version, nous nous concentrons sur la sécurité et le ciblage d'architectures multiples.

    Création d'images de conteneurs multiplateformes

    Il est désormais courant d'utiliser régulièrement des machines Arm64 et x64. Les machines x64 existent depuis des décennies, mais les machines de dév Arm64 (comme les Mac d'Apple) et les nœuds cloud Arm64 sont relativement récents. Docker prend en charge l'utilisation et la construction d'images multiplateformes qui fonctionnent dans plusieurs environnements. Nous avons développé un nouveau modèle qui vous permet de mélanger les architectures avec les images .NET que vous construisez.

    Imaginez que vous êtes sur un Apple Mac et que vous voulez cibler un service cloud x64 dans Azure. Vous pouvez créer l'image en utilisant le commutateur --platform comme suit.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    docker build --pull -t app --platform linux/amd64 .

    En utilisant le nouveau modèle, vous ne mettrez à jour qu'une seule ligne dans votre fichier Docker (l'étape de construction) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:8.0-preview-alpine AS build
    Cette ligne permet au SDK de s'exécuter sur l'architecture de la machine locale, ce qui le rendra plus rapide et plus compatible (puisque .NET ne supporte pas QEMU). Cette ligne n'a pas nécessité de changement dans .NET mais est une fonctionnalité utile de Docker.

    Nous avons également mis à jour le SDK (dans la Preview 3) pour prendre en charge les valeurs $TARGETARCH et ajouter l'argument -a lors de la restauration. Vous pouvez le constater dans l'exemple suivant.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    RUN dotnet restore -a $TARGETARCH
     
    # copy everything else and build app
    COPY aspnetapp/. .
    RUN dotnet publish -a $TARGETARCH --self-contained false --no-restore -o /app

    Cette approche permet de produire des applications plus optimisées d'une manière qui s'intègre bien avec les valeurs --platform de Docker.

    Variable d'environnement pour la valeur UID de l'utilisateur non-root

    Nous avons ajouté une variable d'environnement pour l'UID de l'utilisateur non root que nous avons ajouté dans la Preview 1. Nous avons réalisé que le test Kubernetes runAsNonRoot exigeait que l'utilisateur du conteneur soit défini par l'UID et non par le nom. En même temps, nous voulions éviter aux développeurs d'avoir à appliquer un numéro spécial à des milliers de Dockerfiles (collectivement). Au lieu de cela, nous exposons cette valeur - 64198 - dans une variable d'environnement.

    Vous pouvez voir cela utilisé dans ce Dockerfile :


    C'est le modèle que nous recommandons pour .NET 8.

    Lorsque vous construisez une image de conteneur avec USER défini de cette manière, vous verrez ce qui suit dans les métadonnées du conteneur.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ docker inspect app | jq .[-1].Config.User
    "64198"

    Vous pouvez voir comment cette variable d'environnement est définie.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $ docker run --rm -it mcr.microsoft.com/dotnet/runtime bash -c "export | grep APP"
    declare -x APP_UID="64198"
    $ docker run --rm -it mcr.microsoft.com/dotnet/runtime cat /etc/passwd | tail -n 1
    app:x:64198:64198::/home/app:/bin/sh

    Nous entrerons bientôt dans les détails de ce modèle dans un article sur Kubernetes.

    Résumé

    .NET 8 Preview 3 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. Nous tenons à remercier sincèrement tous ceux qui ont contribué à .NET 8 jusqu'à présent, que ce soit par des contributions au code, des rapports de bogues ou des commentaires.

    Vos contributions ont joué un rôle déterminant dans la réalisation des avant-premières de .NET 8, et nous sommes impatients de continuer à travailler ensemble pour construire un avenir meilleur pour .NET et l'ensemble de la communauté technologique.

    Source : Microsoft

    Et vous ?

    Que pensez-vous des nouveautés apportées par ce nouvel apercu de .NET 8 ? Vous seront-elles utiles dans vos projets ?

    Voir aussi

    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

    Microsoft publie .NET 8 Preview 1, le premier aperçu de la nouvelle version du framework, et ajoute plusieurs nouveautés dont l'extension de Native AOT à plus de scénarios et le support pour Linux

    Microsoft dévoile les mises à jour apportées à ASP.NET Core dans .NET 8 Preview 2, dont l'ajout de Blazor QuickGrid et de plusieurs améliorations de performance
    Contribuez au club : corrections, suggestions, critiques, ... Contactez le service news et Rédigez des actualités

  4. #4
    Chroniqueur Actualités
    Avatar de Anthony
    Homme Profil pro
    Rédacteur technique
    Inscrit en
    novembre 2022
    Messages
    410
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Rédacteur technique

    Informations forums :
    Inscription : novembre 2022
    Messages : 410
    Points : 6 925
    Points
    6 925
    Par défaut Microsoft publie .NET 8 Preview 4, le quatrième aperçu de la dernière version du framework
    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 est ravi de partager toutes les nouvelles fonctionnalités et améliorations de la quatrième version préliminaire de .NET 8 ! Cette version fait suite à la version Preview 3. Vous continuerez à voir beaucoup plus de fonctionnalités apparaître avec ces versions mensuelles. Les utilisateurs de .NET 6 et 7 voudront suivre cette version de près, car il s'agit d'un chemin de mise à niveau direct.

    Nom : dotnet-8-preview-4.png
Affichages : 719
Taille : 124,7 Ko

    Vous pouvez télécharger .NET 8 Preview 4 pour Linux, macOS et Windows.


    Microsoft Build 2023 arrive ! L'équipe .NET organisera un certain nombre de sessions, des approfondissements techniques aux questions-réponses avec l'équipe.

    Découvrez les nouveautés d'ASP.NET Core et EF Core dans la version Preview 4. 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 version.

    Enfin, .NET 8 a été testé avec la version 17.7 Preview 1. Il est recommandé d'utiliser les builds du canal de prévisualisation si vous souhaitez essayer .NET 8 avec la famille de produits Visual Studio. La prise en charge de .NET 8 par Visual Studio pour Mac n'est pas encore disponible. Si vous vous en tenez au canal stable, découvrez les dernières fonctionnalités et améliorations de la version 17.6 de Visual Studio.

    Jetons maintenant un coup d'œil à quelques nouvelles fonctionnalités de .NET 8.

    MSBuild : nouveau terminal moderne de sortie
    https://github.com/dotnet/msbuild/issues/8370

    Les utilisateurs nous font souvent remarquer que la sortie par défaut de MSBuild (connue en interne sous le nom de "console logger") est difficile à analyser. Elle est assez statique, est souvent un mur de texte, et émet des erreurs lorsqu'elles sont déclenchées pendant la construction au lieu de les montrer logiquement comme faisant partie du projet en cours de construction. Nous pensons qu'il s'agit là d'excellents retours, et nous sommes heureux de présenter notre première itération d'une nouvelle version, plus moderne, de la journalisation des sorties de MSBuild. Nous l'avons appelé Terminal Logger, et il a quelques objectifs principaux :

    • Regrouper logiquement les erreurs avec le projet auquel elles appartiennent
    • Présenter les projets/constructions de manière à ce que les utilisateurs pensent à la construction (en particulier les projets multi-cibles)
    • Mieux différencier les TargetFrameworks pour lesquels un projet est construit
    • Continuer à fournir des informations d'un coup d'œil sur les résultats d'un projet
    • Fournir des informations sur ce que la compilation est en train de faire au cours d'une compilation.

    Voici à quoi cela ressemble.

    La nouvelle sortie peut être activée en utilisant /tl, optionnellement avec l'une des options suivantes :

    • auto - la valeur par défaut, qui vérifie si le terminal est capable d'utiliser les nouvelles fonctionnalités et n'utilise pas une sortie standard redirigée avant d'activer le nouveau logger,
    • on - annule la détection de l'environnement mentionnée ci-dessus et force l'utilisation du nouveau logger
    • off - annule la détection de l'environnement mentionnée ci-dessus et force l'utilisation de l'ancien enregistreur de la console.

    Une fois activé, le nouveau logger affiche la phase de restauration, suivie de la phase de construction. Durant chaque phase, les projets en cours de construction sont affichés en bas du terminal, et chaque projet en cours de construction vous indique la cible MSBuild en cours de construction, ainsi que le temps passé sur cette cible. Nous espérons que ces informations rendront les constructions moins mystérieuses pour les utilisateurs, et qu'elles leur donneront un point de départ pour effectuer des recherches lorsqu'ils voudront en savoir plus sur la construction ! Au fur et à mesure que les projets sont construits, une section "construction terminée" est écrite pour chaque construction.

    • Le nom du projet construit
    • Le Framework cible (s'il est multi-cibles !)
    • Le statut de cette compilation
    • Le résultat principal de cette compilation (avec un lien hypertexte pour un accès rapide)
    • Et enfin, tous les diagnostics générés par la compilation pour ce projet.

    Il n'y avait pas de diagnostic pour cet exemple - regardons une autre compilation du même projet où une coquille a été introduite.

    Ici, vous pouvez clairement voir le projet et l'erreur typographique décrits.

    Nous pensons que cette présentation correspond à la modernité de .NET et qu'elle utilise les capacités des terminaux modernes pour informer les utilisateurs sur leurs créations. Nous espérons que vous l'essaierez et que vous nous ferez part de vos commentaires sur son fonctionnement, ainsi que des autres informations que vous souhaiteriez y voir figurer. Nous espérons utiliser ce logger comme base pour un nouveau lot d'améliorations UX pour MSBuild - y compris des aspects tels que les rapports de progression et les erreurs structurées à l'avenir ! Au fur et à mesure que vous l'utilisez, merci de nous faire part de vos commentaires via cette enquête, ou via la section Discussions du référentiel MSBuild. Nous sommes impatients d'avoir de vos nouvelles !

    SDK : Mise à jour simplifiée du chemin de sortie
    https://github.com/dotnet/designs/pull/281
    https://github.com/dotnet/sdk/pull/31955

    Dans l'aperçu 3, nous avons annoncé la nouvelle présentation simplifiée du chemin de sortie pour les projets SDK .NET et nous vous avons demandé de nous faire part de vos commentaires et de votre expérience de l'utilisation de cette nouvelle présentation. Nous vous en remercions ! Vos commentaires ont donné lieu à de nombreuses discussions et, sur la base de ce que nous avons entendu de la part de tous ceux qui ont testé les changements, nous avons apporté les mises à jour suivantes à la fonctionnalité :

    • Le chemin d'accès par défaut à la nouvelle présentation passe de .artifacts à artifacts
    • Nous supprimons la possibilité d'utiliser la fonctionnalité à partir de fichiers de projet au lieu de Directory.Build.props.
    • Nous facilitons la prise en main de la fonctionnalité en incluant les propriétés requises en tant qu'option dans le modèle buildprops pour dotnet new.

    J'aimerais expliquer le processus de réflexion qui nous a conduits à ces changements. Vous avez tous massivement soutenu la suppression du . du nom du dossier, principalement pour des raisons de visibilité sur les systèmes Unix, où le . signifie généralement un fichier ou un dossier "caché". Nous savions donc que nous voulions faire ce changement. Cependant, il y a deux raisons principales pour lesquelles nous ne voulions pas utiliser les artifacts comme chemin racine initialement -

    • le support de .gitignore
    • les obstacles liés à la globalisation des fichiers du SDK .NET

    Nous ne voulions pas que les gens aient soudainement à gérer des changements dans leurs fichiers .gitignore juste pour essayer la fonctionnalité, mais après quelques recherches, nous avons découvert qu'un contributeur entreprenant et tourné vers l'avenir (merci @sayedihashimi !) s'est déjà assuré que les artifacts sont dans tous les modèles communs pour les fichiers .gitignore. Cela signifie que nous n'avons pas eu à nous soucier des utilisateurs qui vérifiaient les binaires de manière inattendue.

    Nous ne voulions pas non plus inclure accidentellement les sorties d'artifacts dans les modèles globaux par défaut que le SDK .NET utilise pour trouver les fichiers sources à construire dans un projet. Si nous changions le chemin racine de .artifacts à artifacts et que nous laissions les utilisateurs utiliser les nouvelles fonctionnalités au niveau du fichier de projet, nous devrions également modifier toutes les inclusions par défaut qui rendent les fichiers de projet du SDK si succincts. Cela semblait très propice aux erreurs, et franchement un gouffre d'échec pour l'expérience utilisateur. En conséquence, nous avons resserré les conditions d'utilisation de la fonctionnalité - vous devez maintenant opter pour la fonctionnalité via le fichier Directory.Build.props. Cela a pour effet secondaire de rendre la fonctionnalité plus stable. Avant cette modification, l'emplacement du dossier racine inféré changeait lorsqu'un fichier Directory.Build.props était créé. Maintenant, parce qu'un Directory.Build.props doit exister, l'emplacement du chemin d'accès aux artefacts devrait rester stable.

    Pour tester la nouvelle version de la fonctionnalité, nous avons facilité la génération du fichier Directory.Build.props correct : il suffit d'exécuter dotnet new buildprops --use-artifacts et nous générerons tout ce dont vous avez besoin. Le fichier Directory.Build.props généré ressemble à ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    <Project>
      <!-- See https://aka.ms/dotnet/msbuild/customize for more details on customizing your build -->
      <PropertyGroup>
        <ArtifactsPath>$(MSBuildThisFileDirectory)artifacts</ArtifactsPath>
      </PropertyGroup>
    </Project>

    Template Engine : expérience sécurisée avec les paquets de Nuget.org

    Dans .NET 8, nous intégrons plusieurs fonctionnalités liées à la sécurité de NuGet.org dans le moteur de modèles, en particulier dans l'expérience dotnet new.

    Améliorations

    • Empêche le téléchargement de paquets à partir de flux http:\Nmais autorise les surcharges avec l'option --force.

    L'équipe NuGet a mis en place un plan d'action pour passer progressivement à une approche sécurisée par défaut. Vous pouvez en savoir plus sur leur plan, et les délais impliqués, dans l'article du blog HTTPS Everywhere. Pour soutenir cet objectif, nous allons commencer à générer des erreurs par défaut lorsqu'une source non-HTTPS est utilisée. Cela peut être remplacé par --force pour la version 8 de .NET, mais le plan actuel est de supprimer ce drapeau pour la version 9 de .NET, en accord avec le calendrier de HTTPS Everywhere.

    Nom : securetemplate1.png
Affichages : 767
Taille : 45,6 Ko

    • Notifier un client si un paquet de modèles a des vulnérabilités lors des vérifications install/update/outdated, et exiger --force pour installer les versions vulnérables.


    Nom : securetemplate2.png
Affichages : 768
Taille : 63,6 Ko

    • Ajouter des données aux commandes de recherche et de désinstallation qui indiquent si un modèle est installé à partir d'un paquetage dont le préfixe est réservé dans NuGet.org.


    Nom : securetemplate3.png
Affichages : 752
Taille : 56,2 Ko

    • Ajout d'informations sur le propriétaire du paquetage du modèle. La propriété est vérifiée par le portail Nuget et peut être considérée comme une caractéristique digne de confiance.


    Nom : securetemplate4.png
Affichages : 752
Taille : 103,5 Ko

    NuGet : vérification des paquets signés sous Linux

    À partir du SDK .NET 8 Preview 4, NuGet vérifie par défaut les paquets signés sous Linux. La vérification reste activée sous Windows et désactivée sous macOS.

    Pour la plupart des utilisateurs de Linux, la vérification devrait fonctionner de manière transparente. Toutefois, les utilisateurs disposant d'un paquet de certificats racine situé dans /etc/pki/ca-trust/extracted/pem/objsign-ca-bundle.pem peuvent constater des échecs de confiance accompagnés de NU3042.

    Les utilisateurs peuvent refuser la vérification en définissant la variable d'environnement DOTNET_NUGET_SIGNATURE_VERIFICATION sur false.

    NuGet : Audit des dépendances des paquets pour les vulnérabilités de sécurité
    https://github.com/NuGet/Home/issues/8087
    https://github.com/NuGet/Home/pull/12310

    dotnet restore produira un rapport sur les vulnérabilités de sécurité avec le nom du paquetage affecté, la gravité de la vulnérabilité et un lien vers l'avis pour plus de détails lorsque vous optez pour l'audit de sécurité NuGet.

    Activation de l'audit de sécurité

    À tout moment, si vous souhaitez recevoir des rapports d'audit de sécurité, vous pouvez opter pour l'expérience en définissant la propriété MSBuild suivante dans un fichier .csproj ou MSBuild en cours d'évaluation dans le cadre de votre projet :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <NuGetAudit>true</NuGetAudit>

    En outre, assurez-vous que le registre central de NuGet.org est défini comme l'une de vos sources de paquets afin de récupérer l'ensemble de données sur les vulnérabilités connues :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    <packageSources>
        <add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
    </packageSources>

    dotnet add package

    Lorsque vous essayez d'ajouter un paquetage qui a une vulnérabilité connue, dotnet restore sera exécuté implicitement et vous le fera savoir par un avertissement.

    Nom : nugetaudit1.png
Affichages : 750
Taille : 29,3 Ko

    dotnet restore

    Lorsque vous restaurez vos paquets via dotnet restore, vous verrez des avertissements pour chaque paquet et avis affecté.

    Nom : nugetaudit2.png
Affichages : 745
Taille : 67,0 Ko

    Codes d'avertissement

    Nom : warning codes.PNG
Affichages : 800
Taille : 4,6 Ko

    Définition d'un niveau d'audit de sécurité

    Vous pouvez définir la propriété MSBuild <NuGetAuditLevel> au niveau souhaité pour lequel l'audit échouera. Les valeurs possibles sont low, moderate, high et critical. Par exemple, si vous ne voulez voir que les avis moderate, high et critical, vous pouvez définir ce qui suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <NuGetAuditLevel>moderate</NuGetAuditLevel>

    Bibliothèques : Améliorations de l'UTF8

    Avec .NET 8 Preview 4, nous avons introduit la nouvelle interface IUtf8SpanFormattable, qui, comme sa cousine ISpanFormattable, peut être mise en œuvre sur un type pour permettre l'écriture d'une représentation de type chaîne de caractères de ce type vers une étendue de destination. Alors que ISpanFormattable cible UTF16 et Span<char>, IUtf8SpanFormattable cible UTF8 et Span<byte>. Il a également été mis en œuvre pour tous les types primitifs (et d'autres), avec exactement la même logique partagée (grâce à des interfaces abstraites statiques), qu'il s'agisse de string, de Span<char> ou de Span<byte>, ce qui signifie qu'il prend totalement en charge tous les formats (y compris le spécificateur binaire "B" qui est également nouveau dans .NET 8 Preview 4) et toutes les cultures. Cela signifie que vous pouvez désormais formater directement en UTF8 à partir de Byte, Complex, Char, DateOnly, DateTime, DateTimeOffset, Decimal, Double, Guid, Half, IPAddress, IPNetwork, Int16, Int32, Int64, Int128, IntPtr, NFloat, SByte, Single, Rune, TimeOnly, TimeSpan, UInt16, UInt32, UInt64, UInt128, UIntPtr, et Version.

    En outre, les nouvelles méthodes Utf8.TryWrite fournissent désormais une contrepartie basée sur UTF8 aux méthodes MemoryExtensions.TryWrite UTF16 existantes. Ces méthodes s'appuient sur la prise en charge du gestionnaire de chaînes interpolées introduite dans .NET 6 et C# 10, de sorte que vous pouvez utiliser la syntaxe des chaînes interpolées pour formater une expression complexe directement dans une plage d'octets UTF8, par ex.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    static bool FormatHexVersion(short major, short minor, short build, short revision, Span<byte> utf8Bytes, out int bytesWritten) =>
        Utf8.TryWrite(utf8Bytes, CultureInfo.InvariantCulture, $"{major:X4}.{minor:X4}.{build:X4}.{revision:X4}", out bytesWritten);

    L'implémentation reconnaît IUtf8SpanFormattable sur les valeurs de format et utilise leurs implémentations pour écrire leurs représentations UTF8 directement dans l'étendue de destination.

    L'implémentation utilise également la nouvelle méthode Encoding.TryGetBytes, qui, avec son homologue Encoding.TryGetChars, prend en charge l'encodage/décodage dans un span de destination tant que le span est suffisamment long pour contenir l'état résultant, et renvoie false au lieu de lancer une exception si ce n'est pas le cas.

    Nous nous attendons à ce que d'autres améliorations de l'UTF8, y compris, mais sans s'y limiter, des améliorations de la performance de cette fonctionnalité, apparaissent dans les prochains aperçus de .NET 8.

    Introduction de l'abstraction de temps

    L'introduction de la classe abstraite TimeProvider ajoute l'abstraction de temps, qui permet de simuler le temps dans les scénarios de test. Cette fonctionnalité est également prise en charge par d'autres fonctions qui s'appuient sur la progression temporelle, telles que Task.Delay et Task.Async. Cela signifie que même les opérations de Task peuvent être facilement simulées à l'aide de l'abstraction de temps. L'abstraction prend en charge les opérations temporelles essentielles telles que la récupération de l'heure locale et de l'heure UTC, l'obtention d'un horodatage pour la mesure des performances et la création de temporisateurs.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    37
    38
    39
    40
    41
    42
    43
    public abstract class TimeProvider
    {
        public static TimeProvider System { get; }
        protected TimeProvider() 
        public virtual DateTimeOffset GetUtcNow()
        public DateTimeOffset GetLocalNow()
        public virtual TimeZoneInfo LocalTimeZone { get; }
        public virtual long TimestampFrequency { get; }
        public virtual long GetTimestamp()
        public TimeSpan GetElapsedTime(long startingTimestamp)
        public TimeSpan GetElapsedTime(long startingTimestamp, long endingTimestamp)
        public virtual ITimer CreateTimer(TimerCallback callback, object? state,TimeSpan dueTime, TimeSpan period)
    }
     
    public interface ITimer : IDisposable, IAsyncDisposable
    {
        bool Change(TimeSpan dueTime, TimeSpan period);
    }
     
    public partial class CancellationTokenSource : IDisposable
    {
        public CancellationTokenSource(TimeSpan delay, TimeProvider timeProvider)
    }
     
    public sealed partial class PeriodicTimer : IDisposable
    {
        public PeriodicTimer(TimeSpan period, TimeProvider timeProvider) 
    }
     
    public partial class Task : IAsyncResult, IDisposable
    {
        public static Task Delay(System.TimeSpan delay, System.TimeProvider timeProvider)
        public static Task Delay(System.TimeSpan delay, System.TimeProvider timeProvider, System.Threading.CancellationToken cancellationToken)
     
        public Task WaitAsync(TimeSpan timeout, TimeProvider timeProvider)
        public Task WaitAsync(TimeSpan timeout, TimeProvider timeProvider, CancellationToken cancellationToken) 
    }
     
    public partial class Task<TResult> : Task
    {
        public new Task<TResult> WaitAsync(TimeSpan timeout, TimeProvider timeProvider)
        public new Task<TResult> WaitAsync(TimeSpan timeout, TimeProvider timeProvider, CancellationToken cancellationToken) 
    }

    En outre, nous avons rendu l'abstraction disponible dans .NET 8.0 et créé une bibliothèque netstandard 2.0 appelée Microsoft.Bcl.TimeProvider. Cela permet d'utiliser l'abstraction sur les versions prises en charge du .NET Framework et des versions antérieures de .NET.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    namespace System.Threading.Tasks
    {
        public static class TimeProviderTaskExtensions
        {
            public static Task Delay(this TimeProvider timeProvider, TimeSpan delay, CancellationToken cancellationToken = default) 
            public static Task<TResult> WaitAsync<TResult>(this Task<TResult> task, TimeSpan timeout, TimeProvider timeProvider, CancellationToken cancellationToken = default)
            public static Tasks.Task WaitAsync(this Task task, TimeSpan timeout, TimeProvider timeProvider, CancellationToken cancellationToken = default)
            public static CancellationTokenSource CreateCancellationTokenSource(this TimeProvider timeProvider, TimeSpan delay)
        }
    }

    Exemples d'utilisation

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    //  Get System time
    DateTimeOffset utcNow= TimeProvider.System.GetUtcNow();
    DateTimeOffset localNow = TimeProvider.System.GetLocalNow();
     
    // Create a time provider that work with a time zone different than the local time zone 
    private class ZonedTimeProvider : TimeProvider
    {
        private TimeZoneInfo _zoneInfo;
        public ZonedTimeProvider(TimeZoneInfo zoneInfo) : base()
        {
            _zoneInfo = zoneInfo ?? TimeZoneInfo.Local;
        }
        public override TimeZoneInfo LocalTimeZone { get => _zoneInfo; }
        public static TimeProvider FromLocalTimeZone(TimeZoneInfo zoneInfo) => new ZonedTimeProvider(zoneInfo);
    }
     
    // Create a time using a time provider 
    ITimer timer = timeProvider.CreateTimer(callBack, state, delay, Timeout.InfiniteTimeSpan);
     
    // Measure a period using the system time provider 
    long providerTimestamp1 = TimeProvider.System.GetTimestamp();
    long providerTimestamp2 = TimeProvider.System.GetTimestamp();
    var period = GetElapsedTime(providerTimestamp1, providerTimestamp2);

    https://github.com/dotnet/runtime/issues/36617

    System.Runtime.Intrinsics.Vector512 et AVX-512

    La prise en charge SIMD est un élément essentiel de .NET depuis de nombreuses années, depuis que nous l'avons introduite pour la première fois dans .NET Framework. Dans .NET Core 3.0, nous avons étendu cette prise en charge pour inclure les API intrinsèques matérielles spécifiques à la plate-forme pour x86/x64. .NET 8 ne fait pas exception à la règle et continue de renforcer son support en introduisant System.Runtime.Intrinsics.Vector512<T> et son accélération sur le matériel x86/x64 avec la prise en charge de l'AVX-512.

    AVX-512 lui-même apporte plusieurs fonctionnalités clés dont la Preview 4 ajoute la prise en charge des trois premières. La dernière est encore en cours de développement et nous espérons pouvoir partager plus de détails à une date ultérieure :

    • Prise en charge des opérations vectorielles sur 512 bits
    • Prise en charge de 16 registres SIMD supplémentaires
    • Prise en charge d'instructions supplémentaires disponibles pour les vecteurs 128 bits, 256 bits et 512 bits
    • Prise en charge des opérations vectorielles masquées

    Si votre matériel prend en charge cette fonctionnalité, Vector512.IsHardwareAccelerated indiquera désormais true. Nous avons également exposé plusieurs classes spécifiques aux plates-formes dans l'espace de noms System.Runtime.Intrinsics.X86, notamment Avx512F (Foundational), Avx512BW (Byte and Word), Avx512CD (Conflict Detection), Avx512DQ (Doubleword and Quadword) et Avx512Vbmi (Vector Byte Manipulation Instructions). Ces instructions suivent le même schéma général que les autres ISA en ce sens qu'elles exposent une propriété IsSupported et une classe imbriquée X64 pour les instructions disponibles uniquement pour les processus 64 bits. De plus, nous avons maintenant une classe imbriquée VL dans chacune d'elles qui expose les extensions Avx512VL (Vector Length) pour le jeu d'instructions correspondant.

    En raison des deuxième et troisième caractéristiques clés énumérées ci-dessus, même si vous n'utilisez pas explicitement les instructions spécifiques Vector512 ou Avx512F dans votre code, vous bénéficierez probablement de cette fonctionnalité. En effet, le JIT est en mesure de tirer parti des fonctionnalités implicites lors de l'utilisation de Vector128<T> ou Vector256<T>, ce qui inclut tous les endroits de la BCL qui utilisent des intrinsèques matérielles en interne, comme la plupart des opérations exposées par Span<T> et ReadOnlySpan<T>, la plupart des API mathématiques exposées pour les types primitifs, et bien d'autres encore.

    Améliorations de l'AOT natif

    Nous avons mis à jour le modèle de console par défaut et ajouté le support d'AOT dès le départ. Il est maintenant possible d'invoquer dotnet new console --aot pour créer un projet configuré pour la compilation AOT. La configuration du projet ajoutée par --aot a trois effets :

    • La publication du projet avec, par exemple, dotnet publish ou Visual Studio générera un exécutable autonome natif avec AOT natif.
    • Cela activera les analyseurs de compatibilité basés sur Roslyn pour le découpage, l'AOT et le fichier unique qui marqueront les parties potentiellement problématiques de votre projet (s'il y en a) dans l'éditeur de votre choix.
    • Il permettra l'émulation de l'AOT lors du débogage, de sorte que lorsque vous déboguez votre projet sans compilation de l'AOT, vous obtenez une expérience similaire à celle de l'AOT. Cela permet de s'assurer que, par exemple, l'utilisation de Reflection.Emit dans un package NuGet qui n'a pas été annoté pour AOT (et qui a donc été manqué par l'analyseur de compatibilité) ne vous surprendra pas lorsque vous essayez de publier le projet avec AOT pour la première fois.

    Nous continuons également à améliorer les fondamentaux tels que le débit d'exécution, l'utilisation de la mémoire et la taille sur disque avec Native AOT. Dans l'aperçu 4, nous ajoutons un moyen de communiquer une préférence d'optimisation telle que la vitesse ou la taille. Les paramètres par défaut tentent de trouver le bon équilibre entre ces deux options, mais nous introduisons maintenant un moyen de spécifier la façon de faire les compromis.

    Par exemple, l'optimisation du résultat de dotnet new console --aot pour la taille sur Windows x64 permet de réaliser les économies suivantes dans l'aperçu 4 :

    Nom : size.PNG
Affichages : 753
Taille : 3,7 Ko

    Il s'agit de la taille d'une application entièrement autonome qui comprend le moteur d'exécution (y compris le GC) et toutes les bibliothèques de classes nécessaires.

    Dans l'aperçu 4, nous avons observé que l'optimisation de la vitesse permet d'améliorer le débit de 2 à 3 % pour les charges de travail réelles.

    Prise en charge de la version de la distribution Linux

    Nous avons annoncé précédemment que nous mettions à jour les versions de distro Linux prises en charge pour .NET 8. Ces changements sont inclus dans l'aperçu 4, en particulier la version de la glibc ciblée par .NET 8.

    .NET 8 est conçu pour Ubuntu 16.04, pour toutes les architectures. C'est principalement important pour définir la version minimale de la glibc pour .NET 8. .NET 8 ne démarrera pas sur les versions de distro qui incluent une glibc plus ancienne, comme Ubuntu 14.04 ou Red Hat Enterprise Linux 7.

    Nous sommes également en train de mettre à jour la version Linux de .NET 8 pour utiliser clang 16. Nous prévoyons d'inclure cette modification dans l'aperçu 5. Nous ne ferons pas d'annonce séparée pour cette modification.

    Il n'y a pas d'autres changements significatifs. Nous continuerons à prendre en charge .NET sous Linux sur les architectures Arm32, Arm64 et x64.

    System.Text.Json : Remplissage des membres en lecture seule

    À partir de .NET 8 Preview 4, System.Text.Json introduit la possibilité de désérialiser sur des propriétés ou des champs en lecture seule.

    Nous avons également introduit une option qui permet aux développeurs de l'activer pour toutes les propriétés qui sont capables de remplir - par exemple, les convertisseurs personnalisés peuvent ne pas être compatibles avec cette fonctionnalité :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    JsonSerializerOptions options = new()
    {
      PreferredObjectCreationHandling = JsonObjectCreationHandling.Populate
    };
    Pour les applications existantes qui souhaiteraient utiliser cette fonctionnalité mais dont la compatibilité pose problème, il est également possible de l'activer de manière granulaire en plaçant l'attribut [JsonObjectCreationHandling(JsonObjectCreationHandling.Populate)] sur le type dont les propriétés doivent être renseignées.

    Par exemple, pour activer le remplissage pour toutes les propriétés d'une classe spécifique :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    37
    38
    39
    40
    41
    42
    43
    using System.Text.Json;
    using System.Text.Json.Serialization;
     
    JsonSerializerOptions options = new()
    {
        WriteIndented = true,
        // Instead of granular control we could also enable this globally like this:
        // PreferredObjectCreationHandling = JsonObjectCreationHandling.Populate
    };
     
    CustomerInfo customer = JsonSerializer.Deserialize<CustomerInfo>("""{"Person":{"Name":"John"},"Company":{"Name":"John and Son"}}""", options)!;
     
    Console.WriteLine(JsonSerializer.Serialize(customer, options));
     
    class PersonInfo
    {
        // there is nothing here to be populated since string cannot be re-used
        public required string Name { get; set; }
        public string? Title { get; set; }
    }
     
    class CompanyInfo
    {
        public required string Name { get; set; }
        public string? Address { get; set; }
        public string? PhoneNumber { get; set; }
        public string? Email { get; set; }
    }
     
    // notes:
    // - attribute does not apply to the `CustomerInfo` class itself: i.e. properties of type `CustomerInfo` wouldn't be auto-populated
    //     - automatic rules like these can be implemented with contract customization
    // - attribute do apply to `Person` and `Company` properties
    // - attribute can also be placed on individual properties
    [JsonObjectCreationHandling(JsonObjectCreationHandling.Populate)]
    class CustomerInfo
    {
        private const string NA = "N/A";
     
        // note how neither of these have setters
        public PersonInfo Person { get; } = new PersonInfo() { Name = "Anonymous", Title = "Software Developer" };
        public CompanyInfo Company { get; } = new CompanyInfo() { Name = NA, Address = NA, PhoneNumber = NA, Email = NA };
    }

    Le résultat ci-dessus est identique à celui que l'on obtiendrait avec l'option globale :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    {
      "Person": {
        "Name": "John",
        "Title": "Software Developer"
      },
      "Company": {
        "Name": "John and Son",
        "Address": "N/A",
        "PhoneNumber": "N/A",
        "Email": "N/A"
      }
    }

    à titre de comparaison, nous aurions vu notre entrée, mais comme il n'y avait pas de propriété définissable Person ou Company à désérialiser, nous aurions ignoré complètement l'entrée et la sortie n'aurait montré que les valeurs par défaut :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    {
      "Person": {
        "Name": "Anonymous",
        "Title": "Software Developer"
      },
      "Company": {
        "Name": "N/A",
        "Address": "N/A",
        "PhoneNumber": "N/A",
        "Email": "N/A"
      }
    }

    Autres notes concernant le remplissage des membres en lecture seule

    • Pour plus d'informations, voir le problème original de la conception : https://github.com/dotnet/runtime/issues/78556
    • Les structures peuvent également être alimentées, mais l'alimentation se fait en créant d'abord une copie, puis en la réinitialisant à la propriété, et ces propriétés nécessitent donc également des fixateurs (setters).
    • Le peuplement des collections se fait de manière additive - la collection existante avec tout son contenu est traitée comme l'objet d'origine et tous les éléments existants sont donc préservés - ce comportement peut être modifié par la personnalisation du contrat et/ou les rappels de désérialisation.

    Améliorations de System.Text.Json

    JsonSerializer.IsReflectionEnabledByDefault
    https://github.com/dotnet/runtime/pull/83844

    La classe JsonSerializer expose un certain nombre de méthodes de sérialisation et de désérialisation qui acceptent un paramètre optionnel JsonSerializerOptions. Si elles ne sont pas spécifiées, ces méthodes utiliseront par défaut le sérialiseur basé sur la réflexion. Dans le contexte des applications AOT natives, ce défaut peut créer des problèmes en ce qui concerne la taille de l'application : même si l'utilisateur prend soin de passer une valeur JsonSerializerOptions générée par la source, il en résultera toujours que les composants de réflexion seront enracinés par l'outil de découpage.

    System.Text.Json est désormais livré avec le commutateur de fonctionnalité System.Text.Json.JsonSerializer.IsReflectionEnabledByDefault qui contrôle le comportement par défaut des méthodes JsonSerializer. Le fait de définir le commutateur sur false au moment de la publication permet désormais d'éviter l'enracinement accidentel des composants de réflexion. Il convient de noter qu'avec l'interrupteur désactivé, ce code

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    JsonSerializer.Serialize(new { Value = 42 });
    échouera désormais avec une exception NotSupportedException. Un JsonSerializerOptions configuré devra être passé explicitement pour que la méthode fonctionne.

    En outre, la valeur du commutateur de fonctionnalité est reflétée dans la propriété JsonSerializer.IsReflectionEnabledByDefault qui est traitée comme une constante de temps de liaison. Les auteurs de bibliothèques construites au-dessus de System.Text.Json peuvent s'appuyer sur cette propriété pour configurer leurs valeurs par défaut sans enraciner accidentellement des composants de réflexion :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    static JsonSerializerOptions GetDefaultOptions()
    {
        if (JsonSerializer.IsReflectionEnabledByDefault)
        {
            // This branch has a dependency on DefaultJsonTypeInfo
            // but will get trimmed away by the linker if the feature switch is disabled.
            return new JsonSerializerOptions
            {
                  TypeInfoResolver = new DefaultJsonTypeInfoResolver(),
                  PropertyNamingPolicy = JsonNamingPolicy.KebabCase,
            }
        }
     
        return new() { PropertyNamingPolicy = JsonNamingPolicy.KebabCaseLower } ;
    }

    JsonSerializerOptions.TypeInfoResolverChain
    https://github.com/dotnet/runtime/issues/83095

    Lorsqu'elle a été livrée en .NET 7, la fonction de personnalisation des contrats a ajouté la prise en charge du chaînage des générateurs de sources au moyen de la méthode JsonTypeInfoResolver.Combine :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    var options = new JsonSerializerOptions
    {
        TypeInfoResolver = JsonTypeInfoResolver.Combine(ContextA.Default, ContextB.Default, ContextC.Default);
    };
    D'après les commentaires que nous avons reçus, cette approche pose quelques problèmes d'utilisation :

    1. Elle nécessite la spécification de tous les composants chaînés dans un site d'appel - les résolveurs ne peuvent pas être ajoutés à la chaîne après coup.
    2. L'implémentation du chaînage étant abstraite derrière l'implémentation d'un résolveur IJsonTypeInfoResolver, il n'existe aucun moyen pour les utilisateurs d'introspecter la chaîne ou d'en supprimer des composants.

    La classe JsonSerializerOptions comprend désormais une propriété TypeInfoResolverChain qui est complémentaire de TypeInfoResolver :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    namespace System.Text.Json;
     
    public partial class JsonSerializerOptions
    {
        public IJsonTypeInfoResolver? TypeInfoResolver { get; set; }
        public IList<IJsonTypeInfoResolver> TypeInfoResolverChain { get; }
    }

    L'instance d'options telle que définie dans l'exemple original peut maintenant être manipulée comme suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    options.TypeInfoResolverChain.Count; // 3
    options.TypeInfoResolverChain.RemoveAt(0);
    options.TypeInfoResolverChain.Count; // 2
    Il convient de noter que les propriétés TypeInfoResolver et TypeInfoResolverChain sont toujours synchronisées, de sorte qu'une modification apportée à l'une d'entre elles entraînera une mise à jour de l'autre.

    Obsolescence de JsonSerializerOptions.AddContext
    https://github.com/dotnet/runtime/issues/83280

    La propriété JsonSerializerOptions.AddContext a été remplacée par les propriétés TypeInfoResolver et TypeInfoResolverChain, elle est donc marquée comme obsolète.

    Prise en charge des types unspeakable
    https://github.com/dotnet/runtime/issues/82457

    Les types générés par le compilateur ou "unspeakable" ont été difficiles à prendre en charge dans les scénarios de génération de source faiblement typée. Dans .NET 7, l'application suivante

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    object value = Test();
    JsonSerializer.Serialize(value, MyContext.Default.Options);
     
    async IAsyncEnumerable<int> Test()
    {
        for (int i = 0; i < 10; i++)
        {
            await Task.Delay(1000);
            yield return i;
        }
    }
     
    [JsonSerializable(typeof(IAsyncEnumerable<int>))]
    internal partial class MyContext : JsonSerializerContext {}

    échoue avec l'erreur

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Metadata for type 'Program+<<<Main>$>g__Test|0_5>d' was not provided by TypeInfoResolver of type 'MyContext'

    En effet, le type Program+<<<Main>$>g__Test|0_5>d généré par le compilateur ne peut pas être explicitement spécifié par le générateur de source.

    À partir de l'aperçu 4, System.Text.Json effectue la résolution de l'ancêtre le plus proche lors de l'exécution afin de déterminer le super-type le plus approprié pour sérialiser la valeur (dans ce cas, IAsyncEnumerable<int>).

    JsonSerializerOptions.TryGetTypeInfo
    https://github.com/dotnet/runtime/pull/84411

    L'aperçu 4 inclut désormais une variante Try- de la méthode GetTypeInfo qui renvoie false si aucune métadonnée n'a été trouvée pour le type spécifié.

    Codegen

    Allocation de registres consécutifs

    Dans cette version preview, nous avons introduit une nouvelle fonctionnalité dans notre allocateur de registres appelée allocation de "registres consécutifs". Avant d'entrer dans les détails de ce qu'elle implique et pourquoi elle était nécessaire, examinons d'abord ce qu'est l'allocation de registre et comment elle fonctionne dans RyuJIT.

    L'algorithme d'allocation de registre utilisé dans RyuJIT est basé sur une approche "Linear Scan". Il parcourt le programme pour identifier la durée de vie de toutes les variables, appelées "intervalles" dans la littérature, et assigne un seul registre à chaque variable à chaque utilisation. Pour déterminer le meilleur registre à affecter à un point donné, l'algorithme doit identifier les variables qui sont actives à ce point et qui ne se chevauchent pas avec d'autres variables. Il sélectionne ensuite un registre parmi un ensemble de registres libres disponibles, en utilisant une heuristique pour déterminer le meilleur ensemble de registres au point d'affectation. Si aucun registre n'est disponible parce qu'ils sont tous affectés à des intervalles, l'algorithme identifie le meilleur registre qui peut être "déversé" et affecté à cet endroit. Le déversement consiste à stocker la valeur d'un registre sur la pile et à la récupérer plus tard en cas de besoin, ce qui est une opération coûteuse que l'allocateur de registres tente de minimiser.

    L'Arm64 possède deux instructions, TBL et TBX, qui sont utilisées pour la recherche de vecteur de table. Ces instructions prennent un "tuple" comme l'un de leurs opérandes, qui peut contenir 2, 3 ou 4 entités. Dans le PR# 80297, nous avons ajouté deux ensembles d'API, VectorTableLookup et VectorTableLookupExtension, sous l'espace de noms AdvSimd pour ces instructions. Cependant, ces instructions exigent que toutes les entités du n-uplet soient présentes dans des registres consécutifs. Pour mieux comprendre cette exigence, prenons un exemple.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    public static Vector128<byte> Test(float f)
    {
            var a = Produce1();
            var b = Produce2();
            var c = a + b;      
            var d = c + a;      
            var e = d + b;     
            d = AdvSimd.Arm64.VectorTableLookup((d, e, e, b), c); 
    }

    Voici le code généré pour la méthode.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
                movz    x0, #0xD1FFAB1E      // code for helloworld:Produce1():System.Runtime.Intrinsics.Vector128`1[ubyte]
                movk    x0, #0xD1FFAB1E LSL #16
                movk    x0, #0xD1FFAB1E LSL #32
                ldr     x0, [x0]
                blr     x0
                str     q0, [fp, #0x20] // [V01 loc0]
                movz    x0, #0xD1FFAB1E      // code for helloworld:Produce2():System.Runtime.Intrinsics.Vector128`1[ubyte]
                movk    x0, #0xD1FFAB1E LSL #16
                movk    x0, #0xD1FFAB1E LSL #32
                ldr     x0, [x0]
                blr     x0
                ldr     q16, [fp, #0x20]    // [V01 loc0]
                add     v17.16b, v16.16b, v0.16b
                str     q17, [fp, #0x10]    // [V03 loc2]
                add     v16.16b, v17.16b, v16.16b
                add     v18.16b, v16.16b, v0.16b
                mov     v17.16b, v18.16b
                mov     v19.16b, v0.16b
                ldr     q20, [fp, #0x10]    // [V03 loc2]
                tbl     v16.16b, {v16.16b, v17.16b, v18.16b, v19.16b}, v20.16b
                add     v0.16b, v0.16b, v16.16b

    Dans l'exemple donné, VectorTableLookup() prend un tuple composé de 4 vecteurs d, e, e, et b, qui sont passés dans les registres consécutifs v16 à v19. Même si la deuxième et la troisième valeur sont la même variable e, elles sont toujours passées dans des registres différents v17 et v18. Cela introduit la complexité de trouver non seulement plusieurs registres libres (ou occupés) (2, 3 ou 4) pour les instructions tbl et tbx, mais aussi des registres consécutifs. Afin de répondre à cette nouvelle exigence, notre algorithme a dû être mis à jour à différentes étapes, comme la vérification à l'avance si des registres consécutifs sont libres lors de l'assignation d'un registre à la première entité du tuple, l'assurance que les registres assignés sont consécutifs si les variables ont déjà des registres assignés et qu'ils ne sont pas consécutifs, et l'ajout de scénarios de tests de stress pour gérer les registres alternatifs lorsqu'ils sont disponibles. Dans le PR #85189, @MihaZupan a utilisé le VectorTableLookup dans la méthode IndexOf de ProbabilisticMap et a obtenu une amélioration de 30%.

    Optimisation de l'accès aux champs ThreadStatic

    L'accès aux champs marqués avec ThreadStatic devait passer par des appels d'aide qui accédaient au stockage local du thread (TLS) du thread et du module en cours avant d'accéder aux données du champ. Dans le PR #82973, nous avons intégré tout ce code et ainsi, la valeur du champ peut être récupérée sans passer par l'aide. Cela permet de multiplier par 10 les performances d'accès aux champs.

    Arm64

    Nous avons continué à améliorer la qualité du code d'Arm64 et nos amis @SwapnilGaikwad et @a74nh d'Arm ont apporté de bonnes contributions à cette version.

    • Dans le PR #84350, les paires de "str wzr" ont été optimisées et remplacées par "str xzr".
    • Dans le PR #84135, les optimisations peephole de ldp/stp ont été activées pour les registres SIMD.
    • Dans le PR #83458, un chargement a été remplacé par une instruction mov moins chère lorsque cela était possible.
    • Dans le PR #79283, les conditions dans la clause if ont été combinées avec des chaînes de comparaison.
    • Dans le PR #82031, on a commencé à utiliser cinc au lieu de csel quand c'était possible.
    • Dans le PR #84667, combiner 'neg' et 'cmp' en 'cmn'.
    • Dans le PR #84605, combiner les opérations cmp et shift en une seule opération cmp.
    • Dans le PR #83694, ajouter IsVNNeverNegative (a amélioré tous les arcs, mais a eu un impact important sur ARM64).

    Jusqu'à présent, l'optimisation de la paire load/store peephole n'était pas effectuée si l'une des valeurs provenait d'une variable locale. La PR #84399 a corrigé cette limitation et activé l'optimisation peephole de manière générale.

    L'opérateur >>> est optimisé pour les intrinsèques ShiftRightLogical sur Arm64 dans le PR#85258.

    Vectorisation du code

    JIT/NativeAOT peut maintenant dérouler et vectoriser automatiquement diverses opérations mémoire telles que la comparaison, la copie et la mise à zéro avec SIMD (y compris les instructions AVX-512 sur x64 !) s'il peut déterminer leurs tailles au moment de la compilation :

    • PR#83255 a rendu la mise à zéro de stackalloc 2 à 3 fois plus rapide avec SIMD
    • PR#83638, PR#83740 et PR#84530 ont activé l'auto-vectorisation pour diverses opérations de type "copy buffer".
    • Le PR#83945 a fait de même pour les comparaisons, y compris SequenceEqual et StartsWith pour tous les types de primitives. Un bon exemple d'un motif que le JIT peut maintenant vectoriser automatiquement est l'extrait suivant :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    bool CopyFirst50Items(ReadOnlySpan<int> src, Span<int> dst) => 
        src.Slice(0, 50).TryCopyTo(dst);
    ```csharp
    ```asm
    ; Method CopyFirst50Items
           push     rbp
           vzeroupper 
           mov      rbp, rsp
           cmp      edx, 50 ;; src.Length >= 50 ?
           jb       SHORT G_M1291_IG05
           xor      eax, eax
           cmp      r8d, 50 ;; dst.Length >= 50 ?
           jb       SHORT G_M1291_IG04
           vmovdqu  zmm0, zmmword ptr [rsi]
           vmovdqu  zmm1, zmmword ptr [rsi+40H]
           vmovdqu  zmm2, zmmword ptr [rsi+80H]
           vmovdqu  xmm3, xmmword ptr [rsi+B8H]
           vmovdqu  zmmword ptr [rcx], zmm0
           vmovdqu  zmmword ptr [rcx+40H], zmm1
           vmovdqu  zmmword ptr [rcx+80H], zmm2
           vmovdqu  xmmword ptr [rcx+B8H], xmm3
           mov      eax, 1
    G_M1291_IG04:
           pop      rbp
           ret      
    G_M1291_IG05:
           call     [System.ThrowHelper:ThrowArgumentOutOfRangeException()]
           int3     
    ; Total bytes of code: 96

    Ici, le JIT a utilisé 3 registres ZMM (AVX-512) pour effectuer une opération de type memmove en ligne (même si src et dst se chevauchent). Un codegen similaire sera généré pour les données constantes à la compilation, par exemple les littéraux utf8 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    bool WriteHeader(Span<int> dst) => "text/html"u8.CopyTo(dst);
    bool StartsWithHeader(Span<int> dst) => dst.StartsWith("text/html"u8);

    Optimisations générales

    • PR#83911 Les initialisations statiques sont maintenant moins coûteuses dans NativeAOT.
    • PR#84213 et PR#84231 : amélioration de l'élimination des contrôles pour les motifs arr[arr.Length - cns] et arr[index % arr.Length].
    • L'optimisation de la substitution vers l'avant est activée pour plus de cas tels que les petits types, PR#83969.
    • Amélioration de certains cas de déversements lors de l'allocation des registres avec PR#85251.
    • PR#84427 a amélioré l'extensibilité de l'instrumentation PGO.
    • Nous avons continué à améliorer les capacités d'optimisation des boucles JIT. Dans l'aperçu 4, nous avons amélioré le calcul des ensembles d'accessibilité, PR#84204.

    Résumé

    L'aperçu 4 de .NET 8 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. Nous tenons à remercier sincèrement tous ceux qui ont contribué à .NET 8 jusqu'à présent, que ce soit par des contributions au code, des rapports de bogues ou des commentaires.

    Vos contributions ont joué un rôle déterminant dans la réalisation des avant-premières de .NET 8, et nous sommes impatients de continuer à travailler ensemble pour construire un avenir meilleur pour .NET et l'ensemble de la communauté technologique.
    Source : Microsoft

    Et vous ?

    Que pensez-vous des nouveautés apportées par cet aperçu de .NET 8 ?

    Voir aussi

    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

    Microsoft publie .NET 8 Preview 1, le premier aperçu de la nouvelle version du framework, et ajoute plusieurs nouveautés dont l'extension de Native AOT à plus de scénarios et le support pour Linux
    Contribuez au club : corrections, suggestions, critiques, ... Contactez le service news et Rédigez des actualités

Discussions similaires

  1. Réponses: 0
    Dernier message: 14/04/2022, 04h51
  2. Réponses: 0
    Dernier message: 18/06/2021, 14h42
  3. Réponses: 0
    Dernier message: 11/03/2020, 18h32
  4. Microsoft publie .NET Core 1.0.1
    Par Hinault Romaric dans le forum Général Dotnet
    Réponses: 2
    Dernier message: 08/10/2016, 21h58
  5. Microsoft publie la première preview publique de SQL Server 2016
    Par Arsene Newman dans le forum MS SQL Server
    Réponses: 0
    Dernier message: 27/05/2015, 22h02

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo