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

Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

Microsoft publie .NET 8 Preview 6, le sixième aperçu de la nouvelle version du framework,
Et présente toutes les nouvelles fonctionnalités et améliorations dans cette version

Le , par Nancy Rey

23PARTAGES

5  0 
Microsoft est heureux de présenter les dernières fonctionnalités et améliorations de .NET 8 Preview 6 ! Cette version est une continuation de la version Preview 5, et nous Microsoft s'engage à apporter plus d'améliorations avec chaque version mensuelle.

Aujourd'hui, Microsoft a une version passionnante comprenant de nombreuses mises à jour de bibliothèques, un nouveau mode WASM, plus de générateurs de sources, des améliorations constantes des performances et le support de NativeAOT sur iOS. Microsoft espére que vous apprécierez ces nouvelles fonctionnalités et améliorations.

https://youtu.be/DgDXGBRC9gE

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

Restez au courant de ce qui est nouveau et à venir dans What's New in .NET 8. Il sera mis à jour tout au long de la publication.

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


Améliorations apportées à System.Text.Json

Microsoft a apporté un certain nombre d'améliorations au générateur de sources System.Text.Json, principalement dans le but de rendre Native AOT comparable au serializer basé sur la réflexion.


JsonStringEnumConverter<TEnum>

Ce nouveau convertisseur complète la classe JsonStringEnumConverter existante, qui n'est pas prise en charge par Native AOT.

Les utilisateurs souhaitant cibler les utilisateurs de Native AOT doivent annoter leurs types d'énumération avec le modèle suivant.

Code : Sélectionner tout
1
2
3
4
5
[JsonConverter(typeof(JsonStringEnumConverter<MyEnum>))] 
public enum MyEnum { Value1, Value2, Value3 } 
 
[JsonSerializable(typeof(MyEnum))] 
public partial class MyContext : JsonSerializerContext { }


JsonConverter.Type

Cette nouvelle propriété permet aux utilisateurs de connaître le type d'une instance non générique de JsonConverter :

Code : Sélectionner tout
1
2
Dictionary<Type, JsonConverter> CreateDictionary(IEnumerable<JsonConverter> converters) 
    => converters.Where(converter => converter.Type != null).ToDictionary(converter => converter.Type!);


La propriété est annulable puisqu'elle renvoie null pour les instances de JsonConverterFactory et typeof(T) pour les instances de JsonConverter<T>.

Surcharge des méthodes ZipFile.CreateFromDirectory et ExtractToDirectory basées sur les flux

Microsoft a ajouté de nouvelles surcharges de ZipFile CreateFromDirectory qui permettent aux utilisateurs de collecter tous les fichiers inclus dans un répertoire et de les zipper, puis de stocker le fichier zip résultant dans le flux fourni.

Symétriquement les surcharges ont été ajouté ZipFile CreateFromDirectory qui permettent aux utilisateurs de fournir un flux contenant un fichier zippé et d'extraire son contenu dans le système de fichiers.

Ces API permettent d'éviter d'utiliser le disque comme étape intermédiaire. Cela peut être utile dans les scénarios où l'espace disque est limité, comme, par exemple, dans les environnements basés sur le cloud :
  • CreateFromDirectory n'a pas besoin d'écrire le résultat zippé sur le disque.
  • ExtractToDirectory ne nécessite pas que le fichier zippé soit situé sur le disque.


Utilisation de ZipFile.CreateFromDirectory

Code : Sélectionner tout
1
2
3
4
5
6
7
8
Stream destinationStream = GetStreamFromSomewhere(); 
 
ZipFile.CreateFromDirectory( 
    sourceDirectoryName: "/home/username/sourcedirectory/", 
    destination: destinationStream, 
    compressionLevel: CompressionLevel.Optimal, 
    includeBaseDirectory: true, 
    entryNameEncoding: Encoding.UTF8);
Utilisation de ZipFile.ExtractToDirectory

Code : Sélectionner tout
1
2
3
4
5
6
7
Stream sourceStream = GetStreamFromSomewhere(); 
 
ZipFile.ExtractToDirectory( 
    source: sourceStream, 
    destinationDirectoryName: "/home/username/destinationdirectory/", 
    entryNameEncoding: Encoding.UTF8, 
    overwriteFiles: true);
API de métriques MetricCollector

MetricCollector est une nouvelle classe conçue pour aider à tester des scénarios. Il s'appelait auparavant InstrumentRecorder. Microsoft a apporté des améliorations significatives à cette classe et l'as déplacée vers le package Microsoft.Extensions.Telemetry.Testing.

La classe MetricCollector peut désormais enregistrer des mesures métriques avec des horodatages. De plus, la classe offre la possibilité d'utiliser n'importe quel fournisseur de temps souhaité pour une génération d'horodatage précise.

L'exemple suivant montre comment utiliser la fonctionnalité.

Usage de MetricCollector

Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const string CounterName = "MyCounter"; 
 
var now = DateTimeOffset.Now; 
 
var timeProvider = new FakeTimeProvider(now); 
using var meter = new Meter(Guid.NewGuid().ToString()); 
var counter = meter.CreateCounter<long>(CounterName); 
using var collector = new MetricCollector<long>(counter, timeProvider); 
 
Assert.Empty(collector.GetMeasurementSnapshot()); 
Assert.Null(collector.LastMeasurement); 
 
counter. Add(3); 
 
// verify the update was recorded 
Assert.Equal(counter, collector.Instrument); 
Assert.NotNull(collector.LastMeasurement); 
 
Assert.Single(collector.GetMeasurementSnapshot()); 
Assert.Same(collector.GetMeasurementSnapshot().Last(), collector.LastMeasurement); 
Assert.Equal(3, collector.LastMeasurement.Value); 
Assert.Empty(collector.LastMeasurement.Tags); 
Assert.Equal(now, collector.LastMeasurement.Timestamp);


Présentation du générateur de source de validation des options

Pour réduire les frais de démarrage et améliorer l'ensemble des fonctionnalités de validation, Microsoft a introduit le générateur de code source qui implémente la logique de validation.

Utilisation de la validation des options

Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public class FirstModelNoNamespace 
{ 
    [Required] 
    [MinLength(5)] 
    public string P1 { get; set; } = string. Empty; 
 
    [Microsoft.Extensions.Options.ValidateObjectMembers(typeof(SecondValidatorNoNamespace))] 
    public SecondModelNoNamespace? P2 { get; set; } 
 
    [Microsoft.Extensions.Options.ValidateObjectMembers] 
    public ThirdModelNoNamespace? P3 { get; set; } 
} 
 
public class SecondModelNoNamespace 
{ 
    [Required] 
    [MinLength(5)] 
    public string P4 { get; set; } = string. Empty; 
} 
 
public class ThirdModelNoNamespace 
{ 
    [Required] 
    [MinLength(5)] 
    public string P5 { get; set; } = string.Empty; 
} 
 
[OptionsValidator] 
public partial class FirstValidatorNoNamespace : IValidateOptions<FirstModelNoNamespace> 
{ 
} 
 
[OptionsValidator] 
public partial class SecondValidatorNoNamespace : IValidateOptions<SecondModelNoNamespace> 
{ 
}
Si l'application utilise l'injection de dépendances, elle peut injecter la validation à l'aide du modèle suivant.

Code : Sélectionner tout
1
2
3
4
5
6
var builder = WebApplication.CreateBuilder(args); 
builder.Services.AddControllersWithViews(); 
builder.Services.Configure<FirstModelNoNamespace>(builder.Configuration.GetSection(...)); 
 
builder.Services.AddSingleton<IValidateOptions<FirstModelNoNamespace>, FirstValidatorNoNamespace>(); 
builder.Services.AddSingleton<IValidateOptions<SecondModelNoNamespace>, SecondValidatorNoNamespace>();
Extension des surcharges du constructeur LoggerMessageAttribute pour une fonctionnalité améliorée

De nouvelles surcharges de constructeur LoggerMessageAttribute ont été introduites, offrant une plus grande flexibilité dans la spécification des paramètres requis avec un code réduit. Les nouvelles surcharges de constructeur incluent des options telles que la spécification uniquement du LogLevel et du message, uniquement du LogLevel ou uniquement du message.

Ces améliorations permettent aux utilisateurs de définir plus facilement les LoggerMessageAttributes tout en minimisant le code inutile.

Code : Sélectionner tout
1
2
3
 public LoggerMessageAttribute(LogLevel level, string message); 
    public LoggerMessageAttribute(LogLevel level); 
    public LoggerMessageAttribute(string message);


Utilisation de LoggerMessage

L'exemple suivant illustre une instanciation de LoggerMessage qui n'était pas possible auparavant.

Code : Sélectionner tout
1
2
 [LoggerMessage(Level = LogLevel.Warning, Message = "{p1} should be valid")] 
        public partial void LogWaraning(string p1);
Remarque : dans un aperçu ultérieur, pour les constructeurs qui ne nécessitent pas d'ID d'événement, le système générera automatiquement l'ID d'événement, éliminant ainsi la nécessité pour les utilisateurs de le fournir manuellement.

Améliorations du générateur de source de liaison de configuration

Dans Preview 3, Microsoft a introduit un nouveau générateur de source pour fournir une configuration AOT et compatible avec le trim dans ASP.NET Core. Le générateur est une alternative à la mise en œuvre préexistante basée sur la réflexion. Depuis lors, nous avons apporté plusieurs améliorations basées sur les commentaires de la communauté et le générateur est prêt à être réutilisé avec Preview 6.

Un exemple d'application qui utilise la liaison de configuration et est publiée avec AOT passe de deux (2) avertissements d'analyse AOT lors de la compilation à aucun. L'application échouerait lors de son exécution, mais maintenant elle fonctionne.

Aucune modification du code source n'est nécessaire pour utiliser le générateur. Il est activé par défaut dans les applications Web Native AOT. Pour les autres types de projets, il est désactivé par défaut, mais vous pouvez le contrôler en ajoutant la propriété suivante à votre projet.

Code : Sélectionner tout
1
2
3
<PropertyGroup> 
    <EnableConfigurationBindingGenerator>true</EnableConfigurationBindingGenerator> 
</PropertyGroup>


Interopérabilité COM générée par la source

Microsoft a maintenant un nouveau générateur de source qui prend en charge l'interopérabilité avec les interfaces COM à l'aide de la prise en charge de l'interopérabilité générée par la source que nous avons démarrée avec LibraryImportAttribute. Vous pouvez utiliser System.Runtime.InteropServices.Marshalling.GeneratedComInterfaceAttribute pour marquer une interface comme interface COM pour le générateur source. Le générateur de source générera ensuite du code pour permettre l'appel du code C# vers du code non managé, ainsi que du code pour permettre l'appel du code non managé vers C#. Ce générateur de source s'intègre à LibraryImportAttribute et vous pouvez utiliser des types avec GeneratedComInterfaceAttribute comme paramètres et types de retour dans les méthodes attribuées par LibraryImportAttribute.

Le générateur de source COM offre une expérience IDE simple grâce à des analyseurs et des fixateurs de code. Ceci est similaire à LibraryImportAttribute. À côté de chaque interface qui a le System.Runtime.InteropServices.ComImportAttribute, une ampoule offrira une option pour convertir en interopérabilité générée par la source. Ce correctif modifiera l'interface pour utiliser GeneratedComInterfaceAttribute. À côté de chaque classe qui implémente une interface avec le GeneratedComInterfaceAttribute, une ampoule offrira une option pour ajouter le GeneratedComInterfaceAttribute au type. Une fois vos types convertis, vous pouvez déplacer vos méthodes DllImport pour utiliser LibraryImportAttribute avec le fixateur de code existant. Avec ces deux ampoules, il est facile de convertir votre code d'interopérabilité COM existant pour utiliser la nouvelle interopérabilité générée par la source. Il existe également d'autres analyseurs pour vous aider à identifier les endroits où vous pouvez mélanger l'interopérabilité COM générée par la source et basée sur l'exécution qui peut nécessiter un travail supplémentaire.

Dans le cadre de ce projet, nous avons mis à jour la bibliothèque System.Transactions pour utiliser la nouvelle interopérabilité générée par la source ! Nous avons utilisé cette expérience pour aider à affiner les analyseurs et les correcteurs de code afin de fournir une bonne expérience de migration.

Usage de GeneratedComInterfaceAttribute

Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
using System.Runtime.InteropServices; 
using System.Runtime.InteropServices.Marshalling; 
 
[GeneratedComInterface] 
[Guid("5401c312-ab23-4dd3-aa40-3cb4b3a4683e")] 
interface IComInterface 
{ 
    void DoWork(); 
} 
 
internal class MyNativeLib 
{ 
    [LibraryImport(nameof(MyNativeLib))] 
    public static partial void GetComInterface(out IComInterface comInterface); 
}


GeneratedComClassAttribute

Le générateur source prend également en charge le nouveau System.Runtime.InteropServices.Marshalling.GeneratedComClassAttribute pour vous permettre de transmettre vos types qui implémentent des interfaces avec les interfaces attribuées par System.Runtime.InteropServices.Marshalling.GeneratedComInterfaceAttribute au code non managé. Le générateur de source générera le code nécessaire pour exposer un objet COM qui implémente les interfaces et transmet les appels à l'implémentation managée.

Usage de GeneratedComClassAttribute

Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
using System.Runtime.InteropServices; 
using System.Runtime.InteropServices.Marshalling; 
 
MyNativeLib.GetComInterface(out IComInterface comInterface); 
comInterface.RegisterCallbacks(new MyCallbacks()); 
comInterface.DoWork(); 
 
[GeneratedComInterface] 
[Guid("5401c312-ab23-4dd3-aa40-3cb4b3a4683e")] 
interface IComInterface 
{ 
    void DoWork(); 
    void RegisterCallbacks(ICallbacks callbacks); 
} 
 
[GeneratedComInterface] 
[Guid("88470b56-aabc-46af-bf97-8106a1aa3cf9")] 
interface ICallbacks 
{ 
    void Callback(); 
} 
 
internal class MyNativeLib 
{ 
    [LibraryImport(nameof(MyNativeLib))] 
    public static partial void GetComInterface(out IComInterface comInterface); 
} 
 
[GeneratedComClass] 
internal class MyCallbacks : ICallbacks 
{ 
    public void Callback() 
    { 
        Console.WriteLine("Callback called"); 
    } 
}
Interagir avec LibraryImportAttribute

Les méthodes sur les interfaces avec GeneratedComInterfaceAttribute prennent en charge tous les mêmes types que LibraryImportAttribute, et LibraryImportAttribute prend en charge les types attribués par GeneratedComInterface et les types attribués par GeneratedComClass dans cette version.

Si votre code C# n'utilisera qu'une interface attribuée par GeneratedComInterfaceAttribute pour encapsuler un objet COM à partir de code non managé ou encapsuler un objet managé à partir de C# pour l'exposer à du code non managé, vous pouvez utiliser les options de la propriété GeneratedComInterfaceAttribute.Options pour personnaliser le code sera généré. Cette option vous permettra de ne pas avoir à écrire de marshallers pour des scénarios dont vous savez qu'ils ne seront pas utilisés.

Le générateur source utilise le nouveau type
System.Runtime.InteropServices.Marshalling.StrategyBasedComWrappers pour créer et gérer les wrappers d'objets COM et les wrappers d'objets gérés. Ce nouveau type gère l'expérience utilisateur .NET attendue pour l'interopérabilité COM, tout en fournissant des points de personnalisation pour les utilisateurs avancés. Si votre application dispose de son propre mécanisme pour définir des types à partir de COM ou si vous devez prendre en charge des scénarios que COM généré par la source ne prend pas actuellement en charge, vous pouvez envisager d'utiliser le nouveau type StrategyBasedComWrappers pour ajouter les fonctionnalités manquantes à votre scénario et obtenir le même .NET expérience utilisateur pour vos types COM.

Limites

Actuellement, le générateur de source COM présente les limitations suivantes. Nous ne prévoyons pas de résoudre ces limitations dans .NET 8, mais nous le pourrons dans une future version de .NET.
- Pas de prise en charge des interfaces basées sur IDispatch.
*La prise en charge de ces interfaces peut être implémentée manuellement à l'aide d'une définition locale de l'interface IDispatch.
- Pas de prise en charge des interfaces basées sur IInspectable.
*Utilisez l'outil CsWinRT pour générer le code d'interopérabilité pour ces interfaces.
- Pas de prise en charge de l'affinité d'appartement.
*Tous les objets COM sont supposés être à thread libre. La prise en charge de l'affinité d'appartement peut être implémentée manuellement à l'aide du type StrategyBasedComWrappers et des implémentations de stratégie personnalisées.
- Pas de prise en charge des propriétés COM.
*Celles-ci peuvent être implémentées manuellement en tant que méthodes sur l'interface.
- Pas de prise en charge des événements COM.
*Celles-ci peuvent être implémentées manuellement à l'aide des API COM sous-jacentes.
- Aucune prise en charge de l'utilisation d’un new mot-clé pour activer une coclasse COM.
*Utilisez LibraryImportAttribute pour P/Invoke à l'API CoCreateInstance pour activer la CoClass.

Prise en charge du proxy HTTPS

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

Bien que HttpClient ait pris en charge divers types de proxy pendant un certain temps, ils permettent tous à l'homme du milieu de voir à quel site le client se connecte. (même pour les URI HTTPS) Le proxy HTTPS permet de créer un canal crypté entre le client et le proxy afin que toutes les requêtes ultérieures puissent être traitées en toute confidentialité.

Utilisation du proxy HTTPS

  • Unix : export all_proxy=https://x.x.x.x:3218
  • Windows : [C]set all_proxy=https://x.x.x.x:3218[/C

]

System.Security : Prise en charge de SHA-3

La prise en charge des primitives de hashing SHA-3 est désormais disponible sur les plateformes qui proposent SHA-3. Il s'agit actuellement de Linux avec OpenSSL 1.1.1+ et Windows 11 build 25324+.

Les API où SHA-2 est disponible offrent désormais un complément SHA-3. Cela inclut SHA3_256, SHA3_384 et SHA3_512 pour le hashing ; HMACSHA3_256, HMACSHA3_384 et HMACSHA3_512 pour HMAC ; HashAlgorithmName.SHA3_256, HashAlgorithmName.SHA3_384 et HashAlgorithmName.SHA3_512 pour le hashing où l'algorithme est configurable ; et RSAEncryptionPadding.OaepSHA3_256, RSAEncryptionPadding.OaepSHA3_384 et RSAEncryptionPadding.OaepSHA3_512 pour le chiffrement RSA OAEP.

L'utilisation des API SHA-3 est similaire à SHA-2, avec l'ajout d'une propriété IsSupported pour déterminer si la plateforme offre SHA-3.

Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// Hashing example 
// Check if SHA-3-256 is supported on the current platform. 
if (SHA3_256.IsSupported) 
{ 
    byte[] hash = SHA3_256.HashData(dataToHash); 
} 
else 
{ 
    // Determine application behavior if SHA-3 is not available. 
} 
 
// Signing Example 
// Check if SHA-3-256 is supported on the current platform. 
if (SHA3_256.IsSupported) 
{ 
     using ECDsa ec = ECDsa.Create(ECCurve.NamedCuves.nistP256); 
     byte[] signature = ec.SignData(dataToBeSigned, HashAlgorithmName.SHA3_256); 
} 
else 
{ 
    // Determine application behavior if SHA-3 is not available. 
}
De plus, SHA-3 inclut deux fonctions de sortie extensibles (XOF), SHAKE128 et SHAKE256. Ceux-ci sont disponibles en tant que Shake128 et Shake256.

Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
if (Shake128.IsSupported) 
{ 
    using Shake128 shake = new Shake128(); 
    shake.AppendData("Hello .NET!"u8); 
    byte[] digest = shake.GetHashAndReset(outputLength: 32); 
 
    // Also available as a one-shot: 
    digest = Shake128.HashData("Hello .NET!"u8, outputLength: 32); 
} 
else 
{ 
    // Determine application behavior if SHAKE is not available. 
}
La prise en charge de SHA-3 vise actuellement à prendre en charge les primitives cryptographiques. Les constructions et les protocoles de niveau supérieur ne devraient pas initialement prendre entièrement en charge SHA-3. Cela inclut, mais sans s'y limiter, les certificats X.509, SignedXml et COSE. La prise en charge de SHA-3 peut s'étendre à l'avenir en fonction de la prise en charge de la plate-forme et des normes qui adoptent SHA-3.

SHA-3 a été normalisé par le NIST en tant que FIPS 202 comme alternative, et non comme successeur, à SHA-2. Les développeurs et les organisations doivent décider quand ou même si l'adoption de SHA-3 leur convient.

SDK : performances et compatibilité de la publication de conteneurs

Nous avons apporté quelques modifications aux valeurs par défaut des images générées pour les applications .NET 8.

  • Les images utilisent désormais par défaut la nouvelle capacité sans racine des conteneurs .NET, ce qui rend vos applications sécurisées par défaut. Vous pouvez changer cela à tout moment en définissant votre propre ContainerUser, comme root.
  • Les images sont étiquetées comme latest par défaut, comme les autres outils de conteneur.


Microsoft a amélioré les performances des poussées de conteneurs vers des registres distants, la fiabilité de l'opération de poussée et la prise en charge d'un plus grand nombre de registres. Dans le même temps, Tom Deseyn de Red Hat était occupé à améliorer la prise en charge d'une gamme d'implémentations de conteneurs courantes.

Cette version devrait voir des performances nettement améliorées pour les poussées de conteneurs, en particulier vers les registres Azure. Cela est dû à notre prise en charge améliorée pour pousser les couches en une seule opération. De plus, pour les registres qui ne prennent pas en charge les téléchargements atomiques, Microsoft a mis en place un mécanisme de téléchargement par blocs plus fiable et réessayable.

Comme effet secondaire de ces changements, Microsoft a également élargi sa matrice de support pour les registres. Harbour et Artifactory rejoignent la liste des registres de travail connus, et le travail de Tom a également permis à Quay.io et Podman de pousser.

Mode HybridGlobalization sur WASM

Les applications WASM peuvent utiliser un nouveau mode de globalisation qui allège l'ensemble ICU et exploite l'API Web à la place. En mode hybride, les données de globalisation sont partiellement extraites du bundle ICU et partiellement des appels vers JS. Il dessert tous les paramètres régionaux pris en charge par WASM.

Quand envisager d'utiliser HybridGlobalization

Cette option est la plus appropriée pour les applications...
La fin de cet article est réservée aux abonnés. Soutenez le Club Developpez.com en prenant un abonnement pour que nous puissions continuer à vous proposer des publications.

Une erreur dans cette actualité ? Signalez-nous-la !

Avatar de daerlnaxe
Membre éprouvé https://www.developpez.com
Le 01/04/2024 à 9:49
Je viens de tester, je ne m'y retrouve absolument plus du tout.

Je ne sais pas s'il me manque des éléments, les pages d'aide n'ont pas suivi sur le site de ce que je vois. Magnifique !!!

De simples custom command pour wpf ont déclenché un enfer.
0  0