Journalisation avec ASP .NET Core

Introduction

Lorsqu’on développe une application, elle a vocation à être déployée sur un environnement de production. Vous aurez alors besoin de surveiller le bon fonctionnement de cette application avec une journalisation.

Il s’agit d’enregistrer les évènements de votre application dans un fichier, communément appelé log. Ces derniers vous serons aussi utiles pendant votre phase de développement et de recette pour détecter les anomalies fonctionnelles et techniques.

Les logs sont une composante essentielle à toutes les applications, c’est pourquoi des frameworks ont été développés afin de faciliter la gestion des niveaux d’informations, l’intégration dans l’application et le format en sortie.

Comparaison

Avec ASP .NET Core, Microsoft propose sa propre interface pour .NET Core : Microsoft.Extensions.Logging.
Il existe plusieurs librairies qui utilisent cette interface pour fonctionner avec .NET Core : Log4net, Nlog et Serilog.

Log4net est un framework datant de 2001 qui a pris un peu de temps pour porter son code sur .NET Core.
Il s’agit d’un portage de Log4j maintenu par la fondation Apache avec une configuration dans une fichier XML.

Nlog est un projet actif et populaire qui date de 2006. Les dernières versions de Nlog supportent les logs structurés.
La structuration des logs en XML ou JSON permet de faciliter la recherche et l’analyse des logs avec des outils externes.

Serilog un framework récent qui supporte aussi les logs structurés. Officialisé en 2013, il s’est rapidement imposé au sein de la communauté .NET grâce à la simplicité de sa configuration et ses très nombreuses solutions de sorties.

Pour ce tutoriel, nous avons choisis d’utiliser Serilog dans notre application ASP .NET Core, car c’est un framework modulaire activement développé avec une intégration efficace et rapide.

Installation

On va créer une nouvelle solution ASP .NET Core dans Visual Studio :

blog ai3 dotnet-create-project Journalisation avec ASP .NET Core

On ajoute le paquet Nuget « Serilog.ASPNetCore » qui contient toutes les dépendances nécessaires pour utiliser Serilog avec ASP .NET Core.

blog ai3 serilog-asp-net-core Journalisation avec ASP .NET Core

Ouvrez le fichier Program.cs à la racine du projet et ajoutez un bloc « try/catch » dans la méthode « Main » :

Ajouter aussi Serilog dans « CreateHostBuilder » :

blog ai3 createhostbuilder-code Journalisation avec ASP .NET Core

Retirer AddLogging() de « CreateHostBuilder » s’il présent, car il n’est pas nécessaire. Dans le fichier de configuration « appsettings.json », vous pouvez également retirer la section « Logging » qui n’est plus nécessaire aussi.

Si vous le souhaitez, vous pouvez modifier la méthode « Configure » dans le fichier « Startup.cs » en ajoutant la ligne « app.UseSerilogRequestLogging(); » pour l’enregistrement des évènements HTTP.

Ecriture des logs

Ouvrir le fichier « HomeController.cs » et ajouter la propriété privée « _logger » en lecture seule et un paramètre dans constructeur pour l’utiliser via une injection de dépendance. Ajoutez ensuite un log dans la méthode « Index » pour tester que Serilog fonctionne bien.

blog ai3 homecontroller-code Journalisation avec ASP .NET Core

Lancez l’application et vérifiez si le fichier a bien été créé dans le répertoire « C:\Workspace\Logs ».

blog ai3 serilog-file-sample Journalisation avec ASP .NET Core

Format de sortie

Le volume de logs à traiter est parfois conséquent, vous pouvez utiliser une solution comme Azure Monitor ou Kibana pour visualiser plus rapidement les évènements de votre application.

La force de Serilog, ce sont ses extensions qui sont vraiment pratiques, on a un large choix et l’intégration est vraiment rapide.

On intègre par exemple Sentry qui est un traqueur d’anomalie en production. Dans un premier temps, ajouter le paquet Nuget « Serilog.Sinks.Sentry » au projet, puis il suffit d’ajouter la ligne « WriteTo.Sentry(« Sentry DSN ») dans l’initialisation du logger.

blog ai3 serilog-sentry Journalisation avec ASP .NET Core

Dans l’image ci-dessus, « Sentry DSN » corresponds à un identifiant que vous obtenez en créant un compte sur le site de Sentry.

Fichier de configuration

Il est aussi possible de configurer Serilog dans le fichier de configuration « appsettings.json » avec une balise « Serilog » :

Modifiez la propriété du fichier « appsettings.json » pour qu’il soit bien copié dans le dossier de sortie de l’application.

blog ai3 copy-if-newer Journalisation avec ASP .NET Core

Ouvrez votre fichier Program.cs et appliquez les modifications ci-dessous :

Conclusion

Les configurations utilisées dans ce tutoriel ne sont pas exhaustives, il existe bien d’autres options pour gérer les environnements, les enregistrements asynchrones et les bases de données par exemple.

L’intégration de Serilog avec ASP .NET Core présentée ici est un démarrage rapide avec ce framework de journalisation moderne.

N’hésitez pas à partager en commentaire si cet article vous a été utile ou si vous avez rencontrez une problème.

Sources:

https://github.com/serilog/serilog-aspnetcore
https://docs.microsoft.com/fr-fr/aspnet/core/fundamentals/logging/

Installer ASP .NET Core sur un Raspberry Pi

Introduction

.NET Core est un Framework open source et multi-plateforme développé par Microsoft et la communauté .NET sur GitHub. Vous pouvez déployer vos applications codées en C# sur Windows, macOS et Linux. Cet article a pour objectif de présenter le déploiement d’une application réalisée avec ASP .NET Core sur un Raspberry Pi.

Installation

Raspbian

Vous aurez besoin d’un Raspberry Pi 2 minimum.

blog ai3 raspberry-pi Installer ASP .NET Core sur un Raspberry Pi

Télécharger la dernière image de Raspbian et graver la sur une carte SD avec Etcher. Copier l’image générée sur la carte MicroSD et créer un fichier vide nommé « ssh » sans extension à la racine de la partition boot pour activer SSH.

Placer ensuite cette carte CD dans de lecteur de votre Raspberry. Après avoir démarrer votre Raspberry, connectez le à votre box internet avec un cable Ethernet. Vous devez maintenant être en mesure de détecter l’IP du Raspberry PI sur votre réseau.

Vous pouvez alors vous y connecter en SSH avec le login « pi » et le mot de passe « raspberry » par défaut.

L’adresse est utilisée à titre d’exemple dans la commande suivante :

Terminer la configuration avec la commande :

ASP .NET Core

Télécharger les mises à jours et les librairies requises :

Sur la page officielle de téléchargement, choisir « All .NET Core downloads » et télécharger la version recommandée de .Net Core et ASP .NET Core pour Linux. Je vous conseille la version ARM32, car l’architecture recommandée en terme de compatibilité sur le Raspberry est 32 bits.

blog ai3 wget-dotnet Installer ASP .NET Core sur un Raspberry Pi

Créer un alias pour accéder facilement à la commande « dotnet »

Vérifier que l’installation s’est bien passée avec la commande :

blog ai3 dotnet-info Installer ASP .NET Core sur un Raspberry Pi

Application Web

Créer un dossier pour votre application web :

On désactive la redirection en HTTS par défaut sur le projet en commentant la ligne : « app.UseHttpsRedirection(); » dans le fichier « Startup.cs » à la racine de l’application.

Afin que le reverse proxy transfère les requêtes à l’application, il est nécessaire d’ajouter ces trois lignes suivantes au début de la méthode « Configure » dans le fichier « Startup.cs »

blog ai3 dotnet-startup-configuration Installer ASP .NET Core sur un Raspberry Pi

Ajouter aussi cet import « using Microsoft.AspNetCore.HttpOverrides; » dans le fichier « Startup.cs » et c’est terminé.

Vous pouvez transférer votre application compilée pour Linux en SFTP avec un outil comme Cyberduck, mais la suite de ce tutoriel ne nécessite pas d’IDE. Compiler l’application avec la commande suivante :

Serveur Web

On installe Nginx pour pouvoir accéer à l’application depuis votre navigateur.

Configurer Nginx en tant que reverse proxy pour transférer les requêtes à votre application ASP .NET Core :

Modifier votre configuration pour y ajouter le contenu ci-dessous :

Vérifier la configuration et appliquer les modifications :

On s’assure que les ports sont ouverts afin d’être en mesure d’accéder à notre application sur le réseau :

Pour lancer l’application web, placez vous dans le dossier d’exécution de l’application web et lancé l’applicatif :

blog ai3 dotnet-start-app Installer ASP .NET Core sur un Raspberry Pi

Vous pouvez maintenant accéder à votre application depuis votre navigateur favori avec l’adresse IP de votre Raspberry Pi. Il s’agit de 192.168.1.84 dans le cas de ce tutoriel. L’application est aussi accessible en local sur votre Raspberry Pi à l’adresse : http://localhost:5000

Service Web

On va créer un service pour que notre application web soit toujours en fonctionnement après avoir quitté le terminal.

Ajouter la configuration suivante :

Activer et redémarrer le service :

blog ai3 dotnet-run-service Installer ASP .NET Core sur un Raspberry Pi

Vous pouvez maintenant terminer votre session en SSH et accéder à votre application à tout moment depuis votre navigateur.

blog ai3 asp-net-core-welcome Installer ASP .NET Core sur un Raspberry Pi

Conclusion

Pour aller plus loin, vous pouvez aussi créer des batchs avec une application console .NET Core, ajouter d’autres applications web moyennent un peu de configuration Nginx et configurer une connexion HTTPS.

J’espère que ce tutoriel vous aura été utile, n’hésiter pas à partager en commentaire votre avis et si vous avez rencontrez des difficultés.

Sources :

https://dev.to/ianknighton/hosting-a-net-core-app-with-nginx-and-let-s-encrypt-1m50
https://blog.edgoad.com/2016/08/setting-up-net-core-on-ubuntu-and.html
https://blogs.infinitesquare.com/posts/web/heberger-une-application-aspnet-core-2-sur-un-raspberry-pi
https://medium.com/@setu677/how-to-host-asp-net-core-on-linux-using-nginx-85339560e929
https://github.com/dotnet/core/blob/master/samples/RaspberryPiInstructions.md

.NET Core 3.0 est disponible !

Le 23 septembre Microsoft à livré .NET Core 3.0 en release.

Voici un résumé des nouveautés de cette version très attendue :

Support du développement d’applications Windows Desktop

Une des nouveauté phare de cette version est la prise en charge native des applications desktop.
Il est donc désormais possible de créer des applications Windows Forms et WPF avec .NET Core sous Windows.
Bien sûr pour les applications de bureau de .NET Framework déjà existantes, Microsoft a veillé à faciliter leur migration vers .NET Core.

blog ai3 Winforms-vs-WPF .NET Core 3.0 est disponible !


Prise en charge JSON native haute performance

NET Core 3.0 inclut une nouvelle famille d’API JSON permettant des scénarios de lecture / écriture, un accès aléatoire avec un modèle de document (DOM) et un sérialiseur.
De nombreux utilisateurs sont probablement familiarisés avec l’utilisation de Json.NET.
Les nouvelles API sont conçues pour répondre à de nombreux scénarios identiques, mais avec moins de mémoire et une exécution plus rapide.

Microsoft a voulu créer une nouvelle API JSON qui tire parti de toutes les nouvelles fonctionnalités de performance de .NET Core tout en fournissant des performances de haut niveau.
Cela n’était pas possible avec la base de code existante de Json.NET en maintenant la compatibilité.

Voici la nouvelle API, couche par couche :

Utf8JsonReader
System.Text.Json.Utf8JsonReader est un lecteur hautes performances, à faible allocation, orienté uniquement vers l’avant pour le texte JSON codé en UTF-8, lu à partir d’un ReadOnlySpan.
Utf8JsonReader est un type fondamental, de bas niveau, qui peut être utilisé pour créer des analyseurs syntaxiques et des desérialiseurs personnalisés. La lecture d’une charge JSON à l’aide du nouveau Utf8JsonReader est deux fois plus rapide que celle du lecteur de Json.NET.
Il n’alloue pas tant que vous n’avez pas besoin d’actualiser les jetons JSON en tant que chaînes (UTF16).

Utf8JsonWriter
System.Text.Json.Utf8JsonWriter fournit un moyen hautement performant, non mis en cache, de transmettre uniquement du texte JSON codé en UTF-8 à partir de types .NET courants tels que String, Int32 et DateTime.
Comme le reader, le writer est un type fondamental, de bas niveau, qui peut être utilisé pour créer des sérialiseurs personnalisés.
L’écriture d’un contenu JSON à l’aide du nouvel utilitaire Utf8JsonWriter est 30 à 80% plus rapide que l’utilisation du writer de Json.NET.

JsonDocument
System.Text.Json.JsonDocument permet d’analyser des données JSON et de créer un DOM (Document Object Model) en lecture seule qui peut être interrogé pour prendre en charge l’accès et l’énumération aléatoires.
Il est construit au dessus de Utf8JsonReader.
Les éléments JSON qui composent les données sont accessibles via le type JsonElement exposé par le JsonDocument en tant que propriété appelée RootElement.
JsonElement contient les énumérateurs de tableau et d’objet JSON, ainsi que des API permettant de convertir du texte JSON en types .NET courants.
L’analyse d’un contenu JSON et l’accès à tous ses membres à l’aide de JsonDocument sont deux à trois fois plus rapides que Json.NET, avec très peu d’allocations pour des données de taille raisonnable (<1 Mo).

Sérialiseur JSON
Les couches System.Text.Json.JsonSerializer se trouvent au-dessus des systèmes hautes performances Utf8JsonReader et Utf8JsonWriter.
Il désérialise les objets à partir de JSON et sérialise les objets en JSON.
Les allocations de mémoire sont réduites au minimum et prennent en charge la lecture et l’écriture de JSON avec Stream de manière asynchrone.


Support de C# 8.0

Ajoutez des flux asynchrones, des plages / index, davantage de modèles et des types de référence nullables.
Nullable vous permet de cibler directement les failles de code qui conduisent à des exceptions de type NullReferenceException.
La couche la plus basse des bibliothèques de structure a été annotée afin que vous sachiez quand il faut s’attendre à null.

C # 8.0 introduit des types de référence nullables et des types de référence non nullables qui vous permettent de formuler des instructions importantes sur les propriétés des variables de type de référence :

  • une référence n’est pas censée être nulle :
    lorsque les variables ne sont pas censées être nulles, le compilateur applique des règles garantissant la possibilité de déréférencer ces variables en toute sécurité sans vérifier au préalable qu’elles ne sont pas nulles.
  • une référence peut être nulle :
    lorsque les variables peuvent être nulles, le compilateur applique différentes règles pour vous assurer que vous avez correctement vérifié la présence d’une référence nulle.

Cette nouvelle fonctionnalité offre des avantages importants par rapport au traitement des variables de référence dans les versions antérieures de C#, dans lesquelles l’intention lors du développement n’était pas possible à définir à partir de la déclaration de la variable.
Avec l’ajout de types de référence nullables, vous pouvez déclarer votre intention plus clairement et le compilateur vous aide à le faire correctement et à détecter les bogues dans votre code.

blog ai3 csharp-8-new .NET Core 3.0 est disponible !


Nouveau SqlClient

SqlClient est le fournisseur de données que vous utilisez pour accéder à Microsoft SQL Server et à la base de données Azure SQL, par l’intermédiaire de l’un des plus populaires .NET ORM, tels que EF Core ou Dapper, ou directement à l’aide des API ADO.NET.
Il va maintenant être publié et mis à jour en tant que package Microsoft.Data.SqlClient NuGet, et pris en charge pour les applications .NET Framework et .NET Core.
En utilisant NuGet, il sera plus facile pour l’équipe SQL de fournir des mises à jour aux utilisateurs .NET Framework et .NET Core.


Prise en charge de Linux ARM64

Microsoft a ajouté la prise en charge de Linux ARM64 dans cette version, après l’ajout de la prise en charge d’ARM32 pour Linux et Windows dans les versions 2.1 et 2.2 de .NET Core, respectivement.
Les puces Raspberry Pi et ARM sont désormais prises en charge pour permettre le développement IoT, y compris avec le débogueur Visual Studio distant.
Vous pouvez déployer des applications qui écoutent des capteurs et affichent des messages ou des images sur un écran, le tout à l’aide des nouvelles API GPIO. ASP.NET peut être utilisé pour exposer des données en tant qu’API ou en tant que site pour la configuration d’un périphérique IoT.


Mise à jour de ASP.NET Core et de Blazor

Les principales nouvelles fonctionnalités de cette version d’ASP.NET Core et de Blazor sont les suivantes:

  • création d’applications Web interactives côté client riches en utilisant C # au lieu de JavaScript avec Blazor,
  • création de services backend hautes performances avec gRPC (framework RPC),
  • SignalR prend désormais en charge la reconnexion automatique et la diffusion en continu d’un client à un serveur,
  • génération de code client fortement typé pour les API Web avec des documents OpenAPI,
  • routage des points d’extrémité intégré à travers le framework,
  • HTTP/2 est maintenant activé par défaut dans Kestrel,
  • prise en charge de l’authentification pour les API Web et les applications mono-page (SPA) intégrées à IdentityServer,
  • prise en charge du certificat et de l’authentification Kerberos,
  • intégration avec le nouveau sérialiseur System.Text.Json,
  • nouvelle configuration du host générique incluant des services courants tels que l’injection de dépendance, la configuration et les logs,
  • nouveau modèle de Worker Service pour la création de services de longue durée,
  • nouveau EventCounters créé pour obtenir les requêtes par seconde, le nombre total de requêtes, les requêtes en cours et les requêtes ayant échoué,
  • les erreurs de démarrage sont maintenant consignées dans le journal des événements Windows lorsqu’elles sont hébergées dans IIS,
  • nouveau pipeline de demandes intégré à System.IO.Pipelines,
  • amélioration des performances sur toute la pile.


F# 4.7

F# 4.7 est la nouvelle version de F# qui met l’accent sur les modifications d’infrastructure apportées au compilateur et à la bibliothèque principale, ainsi que quelques assouplissements sur les exigences de syntaxe précédemment onéreuses.

Cette nouvelle version a été entièrement développée sur la base de RFCs (request for comments) avec l’appui de la communauté F#.

blog ai3 Screen-Shot-2019-09-22-at-14.40.08 .NET Core 3.0 est disponible !


.NET Standard 2.1

Cette nouvelle version du standard .NET introduit de nouveaux types que vous pouvez utiliser dans le code pouvant être utilisé avec .NET Core et Xamarin.
.NET Standard 2.1 inclut tous les types depuis .NET Core 2.1.
Au total, il est prévu d’ajouter environ 3k APIs dans .NET Standard 2.1.
Une bonne partie d’entre elles sont des API nouvelles, tandis que d’autres sont des API existantes que Microsoft a ajoutées à la norme afin de faire converger davantage les implémentations .NET.

Voici les principales nouveautés du .NET Standard 2.1 :

  • Span<T> :
    c’est un type de tableau qui permet de représenter la mémoire gérée et non gérée de manière uniforme et qui prend en charge le découpage sans opération de copie,
  • API de base compatibles avec Span :
    de nombreuses API permettant de travailler avec Span ont été ajoutées, telles que Stream.Read(Span<Byte>),
  • Reflection emit :
    pour accroître la productivité, l’écosystème .NET a toujours fait un usage intensif de fonctionnalités dynamiques telles que la réflexion et l’émission de réflexion.
    Emit est souvent utilisé comme un outil d’optimisation des performances ainsi que comme moyen de générer des types à la volée pour des interfaces de proxy,
  • SIMD :
    .NET Framework et .NET Core supportaient SIMD depuis un moment.
    Microsoft les a utilisés pour accélérer les opérations de base dans la BCL, telles que les comparaisons de chaînes,
  • ValueTask and ValueTask<T> :
    dans .NET Core 2.1, la principale caractéristique consistait à améliorer les fondamentaux du framework afin de prendre en charge des scénarios hautes performances, ce qui incluait également une optimisation de l’efficacité async / wait.
    La ValueTask existe déjà et permet de renvoyer les résultats si l’opération est terminée de manière synchrone sans avoir à affecter une nouvelle tâche.
    Microsoft a amélioré cette fonctionnalité.
    Il était utile d’avoir une ValueTask non générique correspondante qui permet de réduire les allocations, même dans les cas où l’opération doit être terminée de manière asynchrone, une fonctionnalité utilisée actuellement par Socket et NetworkStream.
    Exposer ces API dans .NET Standard 2.1 permet aux auteurs de bibliothèques de bénéficier de ces améliorations, à la fois en tant que consommateur et producteur,
  • DbProviderFactories:
    dans .NET Standard 2.0, presque toutes les primitives dans ADO.NET pour permettre aux mappeurs O/R et aux implémenteurs de base de données de communiquer.
    DbProviderFactories permet aux bibliothèques et aux applications d’utiliser un fournisseur ADO.NET spécifique sans connaître ses types spécifiques au moment de la compilation, en effectuant une sélection parmi les instances enregistrées de DbProviderFactory en fonction d’un nom qui peut être lu, par exemple, dans les paramètres de configuration,
  • Divers :
    Microsoft a ajouté de nombreuses petites fonctionnalités dans les bibliothèques de classes de base telles que System.HashCode pour combiner des codes de hachage ou de nouvelles surcharges sur System.String.
    Il y a environ 800 nouveaux membres dans .NET Core et la plupart d’entre eux ont été ajoutés dans .NET Standard 2.1.
blog ai3 net_standard-1024x552 .NET Core 3.0 est disponible !


Compilation hiérarchisée

La compilation hiérarchisée (tiered compilation) a été ajoutée en tant que fonctionnalité opt-in dans .NET Core 2.1, elle était désactivée par défaut.
C’est une fonctionnalité qui permet au moteur d’exécution d’utiliser de manière plus adaptative le compilateur Just-In-Time (JIT) afin d’améliorer les performances, à la fois pour le démarrage et pour l’optimisation du débit.
Désormais elle est activé par défaut dans .NET Core 3.0.
Microsoft a apporté de nombreuses améliorations à cette fonctionnalité au cours cette année en la testant avec diverses charges de travail, notamment des sites Web, des applications de bureau PowerShell Core et Windows.
Les performances sont désormais bien meilleures, ce qui a permis à Microsoft de l’activer par défaut.

blog ai3 asp_net_startup-1024x489 .NET Core 3.0 est disponible !
blog ai3 asp_net_steady_state-1024x491 .NET Core 3.0 est disponible !
blog ai3 console_app_performance-1024x488 .NET Core 3.0 est disponible !


Support de TLS 1.3 et OpenSSL 1.1.1 sur Linux

.NET Core peut maintenant tirer parti de la prise en charge de TLS 1.3 dans OpenSSL 1.1.1.

Les principaux avantages de TLS 1.3 sont les suivants :

  • amélioration des temps de connexion grâce à une réduction du nombre d’allers et retours nécessaires entre le client et le serveur,
  • amélioration de la sécurité grâce à la suppression de divers algorithmes de chiffrement obsolètes et non sécurisés et au cryptage de plusieurs transactions.

.NET Core 3.0 peut utiliser ou OpenSSL 1.0.2, OpenSSL 1.1.0 ou OpenSSL 1.1.1.
Lorsque OpenSSL 1.1.1 est disponible, les types SslStream et HttpClient utilisent TLS 1.3 lorsqu’ils utilisent SslProtocols.None (protocoles par défaut du système), en supposant que TLS 1.3 soit pris en charge par le client et le serveur.

.NET Core prend donc désormais en charge TLS 1.3 sous Windows et macOS


Cryptographie

Microsoft a ajouté la prise en charge des chiffrements AES-GCM et AES-CCM, implémentée via System.Security.Cryptography.AesGcm et System.Security.Cryptography.AesCcm.
Ces algorithmes sont des algorithmes AEAD (Authenticated Encryption with Association Data), et ce sont les premiers algorithmes AE (Authenticated Encryption) ajoutés à .NET Core.

.NET Core 3.0 prend désormais en charge l’importation et l’exportation de clés publiques et privées asymétriques à partir de formats standard, sans avoir à utiliser de certificat X.509.


Nouvelle ère Japonaise (Reiwa)

Le 1er mai 2019, le Japon est entré dans une nouvelle ère appelée Reiwa. Les logiciels prenant en charge les calendriers japonais, tels que .NET Core, doivent être mis à jour pour prendre en charge Reiwa.
.NET Core et .NET Framework ont été mis à jour et gèrent correctement le formatage et l’analyse de dates japonaises avec la nouvelle ère.


Stratégie de mise à jour du runtime .NET Core

Le runtime .NET Core, plus précisément le binder du runtime, permet désormais d’activer en opt-in (facultatif) la montée de version majeure.
Le binder du runtime active aussi par défaut la restauration sur les versions correctives et les versions mineures.

Il existe désormais une propriété appelée RollForward, qui accepte les valeurs suivantes:

  • LatestPatch : passe à la version corrective la plus élevée.
    Cela désactive la stratégie mineure
  • Minor : avance vers la version mineure la plus basse, si la version mineure demandée est manquante.
    Si la version mineure demandée est présente, la stratégie LatestPatchest utilisée.
    C’est la politique par défaut,
  • Major : passe à la version majeure la plus élevée et à la version mineure la plus basse si la version majeure demandée est manquante. Si la version majeure demandée est présente, la stratégie mineure est utilisée,
  • LatestMinor : avance vers la version mineure la plus élevée, même si la version mineure demandée est présente,
  • LatestMajor : passage à la version majeure la plus importante et à la version mineure la plus élevée, même si la version majeure demandée est présente,
  • Disable : n’avance par vers une version plus élevée.
    Se lie uniquement à la version spécifiée.
    Cette stratégie n’est pas recommandée pour une utilisation générale, car elle désactive la possibilité de passer à la dernière version.
    Elle n’est recommandée que pour les tests .


Plateformes supportées

.NET Core 3.0 est supporté sur les systèmes d’exploitation suivants :

  • Alpine: 3.9+
  • Debian: 9+
  • openSUSE: 42.3+
  • Fedora: 26+
  • Ubuntu: 16.04+
  • RHEL: 6+
  • SLES: 12+
  • macOS: 10.13+
  • Windows Client: 7, 8.1, 10 (1607+)
  • Windows Server: 2012 R2 SP1+

Note: Windows Forms et les apps WPF ne sont supportés que sur Windows.

Le support des puces est le suivant :

  • x64 sur Windows, macOS, et Linux,
  • x86 sur Windows,
  • ARM32 sur Windows et Linux,
  • ARM64 sur Linux (kernel 4.14+).

Mise en place d’Azure SignalR avec ASP.NET Core

blog ai3 téléchargement-1 Mise en place d'Azure SignalR avec ASP.NET Core

Qu’est-ce que c’est ?

SignalR

Lors de la communication entre un client et un serveur, c’est la plupart du temps le client qui engage cette communication et le serveur qui y répond.

Cependant, il peut arriver que le serveur ait besoin d’engager la conversation. Ce sera par exemple nécessaire pour gérer les notifications, pour gérer la messagerie instantanée ou encore l’actualisation en direct des données que l’on regarde.

Il existe plusieurs moyens de faire ceci (WebSocket, Long Polling…). SignalR est une technologie de Microsoft permettant d’abstraire ça et d’utiliser la meilleure technologie disponible pour le navigateur du client.

Azure SignalR Service

Plutôt que d’avoir un endpoint local, l’idée est d’avoir un service azure auquel n’importe qui (un service, un webjob…) peut envoyer un message à destination d’un client qui y serait connecté.

La mise en place

Côté Azure

Commençons par ajouter une ressource de type « SignalR Service ».

blog ai3 image-15 Mise en place d'Azure SignalR avec ASP.NET Core

On lui donne ensuite un nom, un ResourceGroup, un emplacement géographique, on choisit si on le veut gratuit (mais avec un nombre de connexions et de messages limité) ou payant, et on crée notre service.

Ensuite, dans l’onglet « Keys », on trouvera les clés, host name et ConnectionStrings nécessaires pour se connecter à notre service.

Côté service externe

J’appelle « service externe » tout service ou application, en dehors du front ASP.NET Core principal, qui souhaite pouvoir envoyer des messages aux clients.

C’est là que la version service Azure de SignalR prend tout son intérêt. En effet, le service expose une API Rest que l’on va utiliser.

L’API se trouve sur cette URL :
https://{nom-du-service}.service.signalr.net:5002/api/v1/
Et sa documentation se trouve ici :
https://github.com/Azure/azure-signalr/blob/dev/docs/rest-api.md

Authentification

Avoir l’URL de l’API ne donne rien si l’on n’a pas l’autorisation de l’utiliser. On va donc s’authentifier avec un token JWT.

Vous aurez probablement besoin du package nuget System.IdentityModel.Tokens.Jwt pour que ça fonctionne. Personnellement, j’utilise la version 5.2.4. Pour utiliser l’API, j’utilise j’appelle cette méthode avec les paramètres suivants :

L’accessKey correspond à la clé indiquée dans l’onglet « Keys » de Azure. L’audienceUrl, en revanche, est variable : elle correspond à l’URL appelée.

Envoi d’un message à un utilisateur

Pour cela, il faut 4 choses :

  • Le nom du hub (qu’on définira dans la troisième partie : ASP.NET Core)
  • L’identifiant de l’utilisateur (qui pourra être un GUID, un email, un login…)
  • Un type d’événement (une simple chaîne de caractères – ex : « notification »)
  • Éventuellement un tableau d’objets qui sera ensuite sérialisé en JSON et transmis (ex : [« Nouveau message »])

L’URL complète sera donc :
https://{nom-du-service}.service.signalr.net:5002/api/v1/hubs/{nom-du-hub}/users/{identifiant-utilisateur}.
Ensuite, on peut générer le token (puisque celui-ci dépend de l’URL).

Étape suivante : générer le corps de la requête. Ce sera un objet JSON avec 2 propriétés : target et arguments. target correspond au type du message et arguments correspond aux informations supplémentaires que vous souhaiteriez transmettre.

Une fois que tout est prêt, on fait donc une requête POST vers l’URL déterminée précédemment, avec le body que l’on vient de définir, et avec ces headers :

On lance la requête et le message est transmis (si le destinataire existe et est connecté).

Côté application ASP.NET Core

Les packages NuGet

Il est nécessaire d’ajouter 2 packages NuGet, l’un pour gérer SignalR, l’autre pour la gestion du service Azure :

  • Microsoft.AspNetCore.SignalR (version 1.0.4)
  • Microsoft.Azure.SignalR (version 1.0.3)

Le Hub

Il s’agit du point central par lequel passent tous les messages. Il va falloir créer une classe héritant de la classe abstraite Microsoft.AspNetCore.SignalR.Hub.

Et que doit-on implémenter / surcharger dans notre classe ? Uniquement des comportements spécifiques. Autrement dit, pour un comportement de base, notre hub est vide. Si l’on veut des comportements particuliers lors de la connexion ou déconnexion d’un utilisateur, on peut surcharger les méthodes OnConnectedAsync() et OnDisconnectedAsync(). Il est également possible d’utiliser un attribut [Authorize] sur la classe pour n’accepter que les utilisateurs connectés à l’application.

Envoyer un message depuis l’application ASP.NET Core

Pour ça, il faut d’abord obtenir (via l’injection de dépendances) l’objet IHubContext<TypeDuHub>. On accède ensuite à la propriété Clients, puis on filtre sur les destinataires du message (ou on ne filtre pas du tout grâce à la propriété All), puis on appelle SendAsync en indiquant le nom de l’événement et éventuellement des données.

Définir l’identifiant de l’utilisateur

J’ai parlé plusieurs fois de l’identifiant de l’utilisateur. On est donc en droit de se demander comment celui-ci est choisi. L’idée est simple : implémenter l’interface IUserIdProvider. Voici donc un exemple simple se basant sur les claims de l’utilisateur connecté.

Initialiser SignalR

Il ne nous reste donc plus qu’à initialiser SignalR. On va donc faire ceci dans le fichier Startup.cs.

Côté JavaScript

Package NPM

Il faut commencer par installer les scripts (par exemple via npm) : @aspnet/signalr (j’utilise la version 1.0.4).

Ce package donne accès aux quelques fonctions JavaScript dont vous aurez besoin.

Connexion au hub

Ensuite, on démarre la connexion.

Envoi d’un message depuis JavaScript

Envoyons, depuis le client JavaScript, un message de type « notification » via SignalR à l’utilisateur de notre choix.

Abonnement aux messages SignalR

Dernière ligne droite. On a vu comment configurer SignalR côté client et côté serveur. On a vu comment envoyer un message depuis la solution ASP.NET Core, depuis un service externe et depuis JavaScript. Il ne reste plus qu’à réagir à la réception d’un tel message.

Conclusion

En très peu de ligne de code, on peut ainsi faire réagir notre client JavaScript à un événement asynchrone, provenant du site ou même d’un service externe.

Microsoft nous propose une solution compatible avec tous les navigateurs (même ceux qui ne sont pas compatibles avec WebSocket), simple à mettre en place et efficace.

.Net 5, vers un environnement .NET unifié

Lors du Build 2019 les équipes Microsoft ont dévoilé beaucoup de nouveautés, parmi lesquelles la prochaine version majeure de dotnet : .NET 5.0.

À compter de la publication de .NET 5 en novembre 2020, ce sera le seul framework .NET à être mis à jour.

Vous vous demandez peut-être pourquoi la version passe de .NET Core 3 à .NET 5, voici l’explication officielle :

Nous omettons la version 4, car elle risque de perturber les utilisateurs familiarisés avec le .NET Framework, qui utilise la série 4.x depuis longtemps. De plus, nous voulions clairement communiquer que .NET 5 était l’avenir de la plate-forme .NET

Microsoft tient par ailleurs à apporter les précisions suivantes :

« Nous en profitons également pour simplifier les noms. Nous pensions que s’il n’y avait qu’un seul .NET à l’avenir, nous n’aurions pas besoin d’un terme de clarification comme «Core». Le nom abrégé est une simplification et indique également que .NET 5 possède des fonctionnalités et des comportements uniformes. N’hésitez pas à continuer à utiliser le nom «.NET Core» si vous le préférez. » 

Concernant le versioning, de nouvelles versions seront publiées tous les mois de novembre les années suivantes.

A noter que les versions à numéro pair, par exemple .NET 6, seront des versions LTS (Long Term Support) bénéficiant d’un support à long terme.

Une version préliminaire de .NET 5 devrait être disponible dans la première moitié de 2020.

blog ai3 dotnet5_platform-1024x546 .Net 5, vers un environnement .NET unifié

Les principaux axes d’amélioration de .NET 5 ont été les suivants :

  • créer un environnement d’exécution et de framework .NET unique, utilisable partout et offrant des comportements d’exécution et des expériences de développement uniformes,
  • développer les fonctionnalités de .NET en exploitant le meilleur de .NET Core, .NET Framework, Xamarin et Mono,
  • construire ce produit à partir d’une base de code unique sur laquelle les développeurs de la communauté Microsoft peuvent travailler et se développer ensemble, ce qui améliore tous les scénarios.

L’ambition est grande puisque cette version permettra :

  • d’avoir un framework unique et un .NET runtime unique,
  • de profiter de .NET Core, Xamarin et Mono pour améliorer et rendre .NET plus moderne,
  • pour la première fois, de cibler les OS Windows, Apple, Linux et Android ainsi que les WebAssembly.

Tout ce que vous appréciez dans .NET Core continuera d’exister:

  • open source et orienté communauté sur GitHub,
  • implémentation multi-plateforme,
  • prise en charge de l’exploitation de fonctionnalités spécifiques à la plateforme, telles que Windows Forms et WPF sous Windows, ainsi que des liaisons natives vers chaque plateforme native de Xamarin,
  • haute performance,
  • installation côte à côte,
  • petits fichiers de projet (style SDK),
  • interface de ligne de commande (CLI),
  • intégration de Visual Studio, Visual Studio pour Mac et Visual Studio Code.

Les principales nouveautés seront les suivantes :

  • vous aurez plus de choix sur les expériences d’exécution,
  • l’interopérabilité Java sera disponible sur toutes les plateformes,
  • l’interopérabilité Objective-C et Swift sera prise en charge sur plusieurs systèmes d’exploitation,
  • CoreFX sera étendu pour prendre en charge la compilation statique de .NET (ahead-of-time – AOT), des empreintes plus petites et un support pour davantage de systèmes d’exploitation.

Microsoft a aussi annoncé que .NET Core continue à exister en parallèle, toujours en open source. Une interopérabilité avec Java est dans les tuyaux, ainsi que pour Objective-C et Swift. Seule l’interopérabilité avec Kotlin manquera à l’appel pour être complet. La couche CoreFX, utilisée par toutes les app .NET 5, sera optimisée et disponible ultérieurement sur plus d’OS.

L’éditeur de Redmond annonce aussi un gros travail sur l’optimisation, la gestion mémoire, l’empreinte mémoire et les compilateurs : il y aura même un compilateur AOT (ahead-of-time) basé sur LLVM (Low Level Virtual Machine). Blazor quant à lui utilise déjà l’outil provenant de Mono.

L’agenda des releases est le suivant :

  • .NET Core 3 : septembre, version non LTS (Long Term Support),
  • .NET Core 3.1 : version LTS vers novembre 2019,
  • .NET 5 : novembre 2020,
  • .NET 6 / 7 / 8 : 2021, 2022 et 2023.
blog ai3 dotnet_schedule-1024x566 .Net 5, vers un environnement .NET unifié

Docker et .NET Core

Si vous avez déjà entendu parler de docker sans savoir ce que c’était exactement : cet article va vous permettre de faire en sorte que vos doutes se dissipent… Je pendrais l’exemple d’une application .NET Core pour illustrer cela.

Docker, qu’est ce que c’est?

Docker est une plateforme logicielle permettant de regrouper des logiciels dans des conteneurs.

Pour comprendre plus simplement, il suffit de comparer Docker à un porte-conteneurs.

blog ai3 280px-Container_ships_President_Truman_%28IMO_8616283%29_and_President_Kennedy_%28IMO_8616295%29_at_San_Francisco Docker et .NET Core

Dans l’image ci-dessus, vous pouvez vous apercevoir que ce porte conteneurs contient un nombre important de conteneurs avec à l’intérieur de la marchandise. D’un point de vue logiciel, cela fonctionne de la même façon: Docker va héberger des conteneurs logiciels avec à l’intérieur ce que vous souhaitez.

Si une VM est en mesure d’émuler une infrastructure matériel, un conteneur lui sera en mesure d’émuler un système d’exploitation.

Les conteneur et les images

  • Une Image va être composé d’un système de fichier contenant l’OS, l’application, la base de données etc.. bref tout ce que vous souhaitez intégrer dans votre conteneur.
  • On l’a vu au dessus : un conteneur est un réceptacle. Celui-ci va être alimenté par l’image crée préalablement par vos soins.

Tout image Docker que l’on voudra crée où utilisé (en récupérant par exemple l’image d’un repository) sera obligatoirement mis dans un conteneur.

Docker, .NET Core et VS Code

Pour vous montrer l’utilisation de Docker, je vais prendre le cas d’une application .NET Core MVC en utilisation Visual Studio Code.

  • Création du projet .NET Core

Depuis une invite de commande, lancer les commandes suivantes

mkdir dockerapp
cd dockerapp
dotnet new mvc -o DockerApp

blog ai3 image-3-1024x487 Docker et .NET Core
  • Publication de notre application

Dans la même invite de commande, lancer la commande suivante

dotnet publish -o ./publish

blog ai3 image-10-1024x229 Docker et .NET Core

Cette commande permet de compiler l’application sous forme d’exécutable optimisé. Tout cela se trouve dans le répertoire publish.

cd publish

  • Exécution de l’application

Dans la même invite de commande, lancer la commande suivante

dotnet DockerApp.dll

blog ai3 image-11-1024x264 Docker et .NET Core
blog ai3 image-6-1024x406 Docker et .NET Core
  • Maintenant, on va dockeriser cette application 🙂

On va ouvrir le code source de cette application avec Visual Studio Code

blog ai3 image-12-1024x213 Docker et .NET Core

Nous allons ensuite créer un dockerfile : c’est un fichier sans extension avec le nom dockerfile où sont décrit les opérations étapes par étapes de création de conteneur.

blog ai3 image-7 Docker et .NET Core
  • On va remplir ce fichier dockerfile en ajoutant les lignes ci-dessous dans ce fichier.

FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base

WORKDIR /app

COPY /publish .

ENTRYPOINT [« dotnet », « DockerApp.dll »]

  1. Première ligne : va récupérer l’image d’ASP.NET Core 2.1 depuis un repository pour l’inclure dans notre conteneur.
  2. Deuxième ligne : va récupérer le répertoire de travail de notre appli pour l’inclure dans notre conteneur.
  3. Troisième ligne : va copier tout le contenu du répertoire publish
  4. Quatrième ligne : cette dernière ligne est le point d’entrée. Cela indique à Docker que l’on doit exécuter la dotnet command avec DockerApp.dll en paramètre.
  • On va construire l’image myimage qui se trouvera à l’intérieur du conteneur.

Depuis le terminal VS Code, lancer la commande suivante

blog ai3 image-13-1024x478 Docker et .NET Core
blog ai3 image-14-1024x668 Docker et .NET Core
  • On va indiquer à Docker d’exécuter l’image myimage dans un conteneur.

Dans la console vsCode, lancer la commande suivante

blog ai3 image-15-1024x28 Docker et .NET Core
  • Vous pouvez vous apercevoir que l’application s’est lancée normalement. Seule grosse différence : elle est maintenant encapsulée dans un conteneur.
blog ai3 image-16-1024x419 Docker et .NET Core

Les nouveautés de Visual Studio 2019

L’objectif de cet article est de faire le tour d’horizon des principales nouveautés et améliorations de la prochaine version majeure de Visual Studio, l’outil phare de développement de Microsoft.

IntelliCode

Vous connaissiez certainement IntelliSense, une fonctionnalité très appréciée de Visual Studio, voici la version dopée à l’IA : IntelliCode.
IntelliCode se forme sur votre référentiel de code en créant une hiérarchie entre les modèles de code les plus courants ainsi que le code de vos projets et va partager les résultats avec votre équipe.
Pour générer ses recommandations, IntelliCode s’entraîne sur 2 000 projets open source disponibles dans GitHub.
Au final, cela permet de réduire le nombre de frappes dont vous avez besoin et donc de gagner en productivité.

blog ai3 microsoft-vs-code-intellicode Les nouveautés de Visual Studio 2019

La fonctionnalité de recherche a été optimisée : elle est est désormais plus rapide et plus efficace. De plus, les résultats sont affichés au fur et à mesure de la frappe. Enfin, les raccourcis clavier des commandes courantes sont affichés.

blog ai3 search-feature Les nouveautés de Visual Studio 2019

Optimisations du débogueur

Jamais le débogage n’a été aussi simple et intuitif que dans cette version de Visual Studio.
Vous pouvez examiner plusieurs variables dans l’espion sans avoir besoin de scroller.
De plus, la navigation entre plusieurs mot clés de recherche a été facilitée.
Enfin, une option « Profondeur de la recherche » a été ajoutée (valeur de 1 à 10), cette dernière vous sera utile pour spécifier jusqu’à quelle niveau de profondeur la recherche doit être effectuée dans vos projets.

blog ai3 BasicSearch-1024x380 Les nouveautés de Visual Studio 2019
blog ai3 Navigation-1024x379 Les nouveautés de Visual Studio 2019

Nouvelle interface

L’interface a été mise à jour afin d’avoir la meilleur expérience utilisateur possible.
L’icône principal de l’application a été redesigné en utilisant l’approche Fluent Design System.

blog ai3 new-old-vs-win-icons-1 Les nouveautés de Visual Studio 2019

Le menu de démarrage a été optimisé pour plus de simplicité et une meilleure ergonomie.

blog ai3 command-bar-all-1024x838 Les nouveautés de Visual Studio 2019

Un thème bleu a été ajouté.

blog ai3 Visual-Studo-theme-comparison-1024x638 Les nouveautés de Visual Studio 2019

La barre de commande a été optimisée pour une meilleure productivité.

blog ai3 Visual-Studio-command-shelf-comparison-1024x114 Les nouveautés de Visual Studio 2019

La lisibilité des notifications a été améliorée.

blog ai3 Notifications-2-1024x472 Les nouveautés de Visual Studio 2019

Visual Studio Live Share

Visual Studio Live Share est un service de révision de code en temps réel qui vous permet de partager une base de code avec d’autres développeurs.
N’importe quel développeur autorisé peut travailler à distance en simultané sur vos projets de manière transparente, fluide et sécurisée.

blog ai3 indroducing-visual-studio-live-share Les nouveautés de Visual Studio 2019

Pull Request

La fonctionnalité Pull Request a été améliorée : vous pouvez désormais consulter, exécuter et déboguer les Pull Request de votre équipe sans quitter l’EDI.
Ceci nécessite de télécharger l’extension Pull Requests for Visual Studio à partir de Visual Studio Marketplace.

C#

Visual Studio 2019 ajoute quelques fonctionnalités supplémentaires à C# 8.0 :

  • flux asynchrones,
  • types Range et Index,
  • expressions Switch,
  • modèles récursifs,
  • déclarations using,
  • fonctions locales static.

F#

Améliorations des performances pour les solutions comportant de nombreux projets et corrections de bugs.

Universal Windows Platform (UWP)

Le déploiement sur des périphériques Windows Mobile n’est plus pris en charge dans Visual Studio 2019. Toute tentative de déploiement sur un périphérique Windows 10 Mobile provoquera une erreur indiquant que « Le déploiement sur des périphériques Windows Mobile n’est pas pris en charge dans Visual Studio 2019 ». Si vous devez continuer à travailler sur une application pour les appareils Windows 10 Mobile, continuez à utiliser Visual Studio 2017.

JavaScript/TypeScript

Le débogage JavaScript dans les tests unitaires des projets Node.js a été ajouté.

Prise en charge de .NET Core 3 Preview

Visual Studio 2019 permet la génération d’applications .NET Core 3 pour n’importe quelle plateforme.

blog ai3 dot-net-core-three-dev Les nouveautés de Visual Studio 2019

Pour information le lancement officiel de Visual Studio 2019 aura lieu le 2 avril.

blog ai3 visual Les nouveautés de Visual Studio 2019

Les nouveautés de C# 7

L’objectif de cet article est de présenter aux développeurs les dernières nouveautés de la version 7 de C# en les présentant de manière simple et concise.

Bien entendu, si vous souhaitez avoir plus de détails sur ces nouveautés, je vous invite à vous documenter personnellement pour récupérer les informations qui pourrait vous manquer.

  • La version 7.0

  • Amélioration de la lisibilité du code avec les variables OUT
C# 6 C# 7
string nombreAConvertir = « 7878 »;

int nombre;

if (Int32.TryParse(nombreAConvertir, out nombre))

{

}

string nombreAConvertir = « 7878 »;

if(Int32.TryParse(nombreAConvertir, out int nombre))

{

}

Avec la version 7,  la variable OUT est déclaré au moment où on souhaite l’utiliser, nous ne sommes plus obligés de déclarer préalablement la variable.

  • Amélioration de l’utilisation des tuples
Avant C# 7
Un tuple peut être défini de la façon ci-dessous

Tuple<int, string> tuple = new Tuple<int, string, bool>(1, « pomme »);

Pour accéder aux propriétés du tuples, on le fait simplement avec les propriétés item1, item2… suivant le nombre de propriétés défini dans le tuple.

if (tuple.Item1 == 1) {

Console.WriteLine(tuple.Item1);

}

if (tuple.Item2 == « pomme »){

Console.WriteLine(tuple.Item2);

}

Depuis C# 7
Il est bien entendu toujours possible de déclarer les tuples comme indiqué ci-dessus.

Cependant, d’autres façons de le faire sont maintenant disponible depuis la version 7 de C#.

  • var monTuple = (« test », « test1 »);

monTuple est bien un objet de type Tuple et pour accéder aux valeurs de ce tuple (test et test1), on appellera les propriétés item1 et item2.

  •   (string a, string b) monTuple = (« test », « test1 »);

monTuple est bien un objet de type Tuple et pour accéder aux valeurs de ce tuple(test et test1), on appellera les propriétés a et b.

  •   var monTuple = (a: « test », b: « test1 »);

monTuple est bien une instance d’ objet de type Tuple et pour accéder aux valeurs de ce tuple(test et test1), on appellera les propriétés a et b.

  • Apparition des éléments ignorés avec C# 7
Les éléments ignorés sont des variables temporaires factices utilisées dans le code,

  • n’ayant aucune valeur.
  • défini juste par un underscore (_).

 

Utilisé dans le cadre de la déconstruction d’un tuple
var (_, _, _, a, _, b) = ReturnTuple();

ReturnTuple est une méthode qui retourne un tuple de six éléments.

De tous ces élements retournés, certaines valeurs peuvent être inutilisés car , pas nécessaire. Les éléments ignorés indiqués ci-dessus permettent ainsi de réduire les allocations de mémoire : la methode retourne bien les valeurs du tuple mais du fait que certaines valeurs ne nous intéresse pas, on définit alors des élements ignorés.

  • Apparition du pattern matching avec C# 7
Avant C# 7
  • Le mot-clé is vérifie si un objet est compatible avec un type donné

Exemple : expr is Type

  • Le mot-clé switch est une instruction de sélection qui teste la valeur d’une constante.

Exemple : switch (expr)

case constant:

Après C# 7
  • Le mot-clé is prend en charge en plus
  • Le modèle de type : expr is Type nomVariable
    • is vérifie si expr peut être convertie avec le type Type, et si cela est possible effectue le cast directement.

Exemple : if (o is Employee e)

{return (e.Name);

  • Le modèle de variable : expr is var varName
    • Is vérifie si expr peut être assigné dans la variable varName, et si cela est possible effectue l’assignation directement.

Exemple : if (item is var obj){}

  • Le mot-clé switch prend en charge en plus
    • Tout expression de correspondance non null (IEnumerable, ICollection, Array, Int…).
    • L’apparition de la clause when sur la même ligne d’un case.

Exemple : case Shape shape when shape == null:

  • Apparition des fonctions locales avec C# 7

Une fonction locale est une méthode définie à l’intérieur d’une autre méthode. Cette fonctionnalité a été créé dans le but d’avoir plus de facilité de compréhension dans la lecture du code.

Exemple de fonction locale
private static string GetText(string path, string filename)

{

var sr = File.OpenText(AppendPathSeparator(path) + filename);

var text = sr.ReadToEnd();

return text;

// Ci-dessous, vous trouverez la fonction locale

string AppendPathSeparator(string filepath)

{

if (! filepath.EndsWith(@ »\ »))

filepath += @ »\ »;

return filepath;

}

}

  • Généralisation des expressions-bodied dans C# 7

Les expressions-bodied sont apparus dans la version 6 de C#. En C# 7, elles ont été généralisées au niveau des constructeurs et ses accesseurs.

Exemple d’expression-bodied en C# 7
// Accesseurs

public string Label

{

get => label;

set => this.label = value ?? « Default label »;

}

// Constructeur

public ExpressionMembersExample(string label) => this.Label = label;

  • Valeurs de retour de référence et variables locales de référence en C# 7
Variables de retour de référence
Une valeur de retour de référence permet à une méthode de retourner à un appelant une référence à une variable, plutôt qu’à une valeur.

Exemple :

public ref Person GetContactInformation(string fname, string lname)

{

return ref p;

}

On peut s’apercevoir que la méthode retourne une référence à un objet Person nommé p.

Variables locales de référence
Une variable locale de référence est une variable qui va recevoir une affectation de données ( généralement une méthode) non par par valeur mais par référence.

Exemple :

Person p = contacts.GetContactInformation(« Scott », « Hanselman »);

Ci-dessus, nous avons faire face à une variable locale : la valeur de p est copié à partir de la méthode GetContactInformation, si on modifie p par la suite, la valeur renvoyé par GetContactInformation ne sera pas impactée.

Ref Person p = contacts.GetContactInformation(« Scott », « Hanselman »);

Ci-dessus, nous avons faire face à une variable locale de référence : la valeur de p est désormais un alias de la valeur retournée par GetContactInformation, si on modifie p par la suite, la valeur renvoyée par GetContactInformation sera impactée.

  • Types de retours async généralisés
Nouveautés de C# 7
Au niveau asynchronisme, je ne m’étendrais pas dans cet article sur les mot-clés async et await. Je précise juste que les types de retour retournés dans le cadre d’utilisation de ces mots clés peuvent être Task,Task<TResult> ou void. Pour simplifier tout cela, C#7 permet d’utiliser maintenant un type globale, utilisable dés qu’une méthode est awaitable.

System.Threading.Tasks.ValueTask<TResult>

using System;

using System.Threading.Tasks;

class Program

{

static Random rnd;

static void Main()

{

Console.WriteLine($ »You rolled {GetDiceRoll().Result} »);

}

private static async ValueTask<int> GetDiceRoll()

{

int roll1 = await Roll();

int roll2 = await Roll();

return roll1 + roll2;

}

private static async ValueTask<int> Roll()

{

if (rnd == null)

rnd = new Random();

await Task.Delay(500);

int diceRoll = rnd.Next(1, 7);

return diceRoll;

}

}

  • Amélioration de la syntaxe litérale numérique
Nouveautés de C# 7
Avec C# 7, il est possible désormais d’utiliser  des séparateurs de chiffres pour une meilleure compréhension du code dans la lecture de constantes numériques.

public const int SixtyFour = 0b0100_0000;

public const long BillionsAndBillions = 100_000_000_000;

public const double AvogadroConstant = 6.022_140_857_747_474e23;

public const decimal GoldenRatio = 1.618_033_988_749_894_848_204_586_834_365_638_117_720 ;


  • La version 7.1

  • Expressions littérales par défaut
Nouveautés de C# 7
Dans l’optique de toujours plus simplifier le code, le mot-clé default pourra être utilisé de manière littérale pour initialiser des variables, des paramètres de méthodes où bien des instructions de retour.

Cela initialise la chaine à la valeur par défaut d’une string, à savoir null.

string maChaine=default ;

L’utilisation du mot clé dans un paramètre de méthode.

public LabeledPoint(double x, double y, string label = default)

{

X = x;

Y = y;

Label = label;

}

L’utilisation du mot clé en retour d’une méthode.

public static LabeledPoint MovePoint(LabeledPoint source,

double xDistance, double yDistance)

{

// return a default value:

if (source == null)

return default;

return new LabeledPoint(source.X + xDistance, source.Y + yDistance,

source.Label);

}

  • Async dans main
Le mot-clé async pourra être utilisé dans une méthode main.
  • Simplification de fonctionnalité de tuple
  • var monTuple = (a: « test », b: « test1 »);

monTuple est bien un objet de type Tuple et pour accéder aux valeurs de ce tuple(test et test1), on appellera les propriétés a et b.

Cependant en version C# 7.1, la définition du tuple  peut être redéfini de la façon suivante, toujours pour des raisons de simplification de code.

string a= « test »,

string b= »test1″,

  • var monTuple = (a, b);

  • La version 7.2

  • Apparition de private protected
  • Private protected :  cela veut dire qu’un membre pourra être accessible depuis les classes dérivés du même assembly de la classe principale
  • Arguments nommés non placés à la position de fin
Depuis C#4 sont apparus les arguments nommés (exemple ci-dessous)

PrintOrderDetails(orderNum: 31, productName: « Red Mug », sellerName: « Gift Shop »);

Les arguments nommés améliorent la lisibilité du code en identifiant ce que chaque argument représente.

Il ne faut pas les confondre avec des arguments de position (exemple ci-dessous)

PrintOrderDetails(orderNum, productName, sellerName);

 

Depuis la version C# 7.2, nous avons la possibilité de mixer les deux types d’arguments dans l’appel de la méthode.

PrintOrderDetails(orderNum :31, « Red Mug » , sellerName: « Gift Shop » );


  • La version 7.3

  • Prise en charge des opérateurs d’égalité et d’inégalité avec les tuples
Depuis la version 7.3, nous avons la possibilité dorénavant d’utiliser les opérateurs d’égalité == et d’inégalité. Le mode de fonctionnement est basique, il compare chaque membre de l’argument de gauche à chaque membre de l’argument de droite.
Exemple :
var test= (a: 5, b: 10);
var test1= (a: 5, b: 10);
Console.WriteLine(test== test1); // Le résultat sera True
  • Réaffectation des variables locales Ref
Il est désormais maintenant possible de pouvoir réaffecter une variable local Ref , qui était déjà un pointeur vers une autre variable.
Exemple :
ref VeryLargeStruct refLocal = ref veryLargeStruct;
refLocal = ref anotherVeryLargeStruct;On voit bien ci-dessus que la variable qui était un pointeur vers l’objet veryLargeStruct sur la première ligne, est désormais un nouveau pointeur vers l’objet anotherVeryLargeStruct sur la deuxième ligne.
  • Amélioration des tableaux stackalloc
Le mot-clé stackalloc est utilisé dans un contexte de code unsafe pour allouer un bloc de mémoire sur la pile. Avec la version 7.3, ce mot-clé peut dorénavant être utilisé avec des tableaux

Avant 7.3
var arr = new int[3] {1, 2, 3};
var arr2 = new int[] {1, 2, 3};
Depuis 7.3
int* pArr = stackalloc int[3] {1, 2, 3};
int* pArr2 = stackalloc int[] {1, 2, 3};
Span<int>arr = stackalloc [] {1, 2, 3};

  • D’autres types pour l’instruction fixed
L’instruction fixed définit un pointeur un pointeur vers une variable managée et épingle cette variable pendant l’exécution de l’instruction.

À compter de C# 7.3, l’instruction fixed s’applique à d’autres types au-delà des tableaux, chaînes, mémoires tampons de taille fixe ou variables non managées.

 

Blazor : Framework Web .NET

Introduction

Depuis les premiers navigateurs, Javascript a beaucoup évolué pour permettre de développer des applications web plus complexes. L’émergence récente des Web Assembly ouvre la possibilité de compiler du code que les navigateurs pourront exécuter directement sans avoir à parser le code source. Ceci offre une alternative à Javascript pour les développeurs qui souhaitent dynamiser leurs applications avec des langages comme C, C++ ou C#.

Web Assembly est un standard W3C qui consiste en un bytecode s’exécutant dans une sandbox compatible avec Javascript. L’objectif est d’exécuter du code à une vitesse proche du natif avec des fonctionnalités avancées tout en conservant la sécurité et la rétrocompatibilité. L’écosystème Web Assembly est toujours en développement et il est supporté par la plupart des navigateurs web.

Présentation

Microsoft a publié plusieurs versions beta de Blazor, un Framework Web .NET qui s’exécute au sein du navigateur. Blazor se base sur le moteur de rendu Razor pour simplifier la création d’application web monopage aussi appelée Single Page Application.

Frontend

Blazor s’appuie sur les technologies HTML et CSS, mais le C# vient remplacer le Javascript. En effet, la runtime C# .NET est embarquée dans le WASM (Web Assembly) et le navigateur exécute le bytecode du WASM. Il comporte toutes les fonctionnalités d’un Framework moderne tel que le modèle de composant, le routage, la mise en page, l’injection de dépendances, le rendu côté serveur, le débogage .NET et le rechargement à chaud pendant le développement.

blog ai3 Blazor_frontend-300x275 Blazor : Framework Web .NET

Backend

Si le navigateur ne supporte pas Web Assembly, Blazor permet de faire fonctionner l’application dans un environnement asm.js. L’exécution de Blazor côté serveur vous permettra d’écrire votre application web entièrement en C# avec ASP.NET Core, mais il présente quelques inconvénients. Chaque interaction avec l’UI gérée par SignalR nécessite un saut réseau, ceci implique que l’application ne fonctionnera pas hors-ligne et qu’il pourrait y avoir quelques latences en fonction du nombre de connexion.

blog ai3 blazor_backend Blazor : Framework Web .NET

Get started

Prérequis

Votre première application

Ouvrir Visual Studio puis Fichier -> Nouveau -> Projet…
Sélectionner Web et ASP.NET Core Web Application

blog ai3 blazor_tuto1 Blazor : Framework Web .NET

Sélectionnez le template Blazor et compiler la solution.

blog ai3 blazor_tuto2 Blazor : Framework Web .NET

Lancer l’application, vous devez avoir l’écran ci-dessous dans votre navigateur.

blog ai3 blazor_tuto3 Blazor : Framework Web .NET

Ouvrir la page Counter où l’incrémentation dynamique est effectuée en C#.

blog ai3 blazor_tuto4 Blazor : Framework Web .NET

Vous pouvez regarder l’implémentation dans le fichier Counter.cshtml

blog ai3 blazor_tuto5 Blazor : Framework Web .NET

Créer un nouveau fichier Todo.cshtml dans le dossier Pages avec l’implémentation suivante :

Ouvrir le fichier NavMenu.cshtml et ajouter les lignes suivantes :

Créer une classe TodoItem.cs à la racine du projet avec le code suivant :

blog ai3 blazor_tuto9 Blazor : Framework Web .NET

Vous pouvez compiler et relancer votre application, vous venez de coder une todolist avec Blazor !

blog ai3 blazor_tuto10 Blazor : Framework Web .NET

Conclusion

Le projet Blazor est open source et disponible sur Github. Bien que le Framework soit encore au stade expérimental, son approche est vraiment intéressante. Il ne s’agit pas de concurrencer ASP.NET MVC ou Javascript, mais de proposer une nouvelle solution full-stack .NET pour développer des « Single Page Application ».

Sources :
https://blazor.net/index.html
https://blogs.msdn.microsoft.com/webdev/2018/07/25/blazor-0-5-0-experimental-release-now-available/

 

LINQ Expressions

What is it ?

Compiled Expressions, Lambda Expressions, Expression Trees… LINQ Expressions can be named in many ways. This object describes a tree of members, operators, calls, conditions… that can be, during runtime, either read/parsed or compiled into a delegate.

EntityFramework

If you’re using EntityFramework, you’ll find that this C# instruction :

will execute this SQL query :

Well, the SQL query clearly does what we wanted it to do. But how did it know what to do ?

looks like a simple lambda, which would be a C# call to a C# method. Yet the call is not made in C#. It is included in the SQL query. The thing is you’re not using the extension method

but the extension method

The syntax when using both methods is exactly the same. However, the first method’s parameter is a lambda whereas the second method’s parameter is a lambda expression which means the code is not compiled with the app. Instead, it contains the expression tree :

  • We have a parameter named u of type User.
  • We access the property LastName of the parameter.
  • We call the method string.StartsWith on this property, with the parameter « F ».

This expression tree can be accessed and read at runtime. That way, the Where implementation will be able to convert some C# code we wrote into SQL.

Creating a LINQ expression at runtime

Let’s say you want to get, for a given object, the value of a property, which name you got as a string. You can do it with reflection. That’s quite easy. However, it is very slow. Yet, LINQ expressions can be compiled into lambdas, which is about as fast a if you wrote the code directly.

The easiest way to start is to write the lambda you would want :

And then decompose it :

  • You have a parameter of type User.
  • You access a property of this parameter.
  • The lambda type is Func<User, string>.

So here is the detailed code to create the expression :

All you need is calling the right static method of the Expression class.

Once you have the expression, you can compile it with the Compile() method.

A concrete example : an object mapper

In a multi-layer application, you often have more than one class for the same business concept. For example, you might have a UserEntity that matches what you have in your database and a UserDto that only contains the information you want to display.

Both those entities will have some identical properties (same type, same name). Some libraries enable you to automatically map those identical properties from one object to the other (AutoMapper being a famous one). Let’s do our own simple yet fast one.

Let’s imagine those objects :

The goal is to fill a UserDto from a UserEntity.

We will create OurOwnMapper class :

Then we will create a method to prepare the mapping from one class to another. Its prototype will be quite simple :

This method will have to find the matching properties :

Each property will be set from one object to another via a lambda that we will create with LINQ expressions. So, for each (TFrom, TTo) couple, we will have lamba array. However, the lambda array type will be different for each (Type, Type) couple. If you want to save all lambda arrays into the same Dictionary, I see 2 choices :

  • Use a Dictionary<(Type, Type), object[]> and cast the delegate into their real types when needed.
  • Use a Dictionary<(Type, Type), Action<object, object>[]> and do the cast inside the delegate.

I will use the second solution. That means my lambdas should look like that :

Now we add the code to create such lambdas :

Then we add the lambdas collection into a dictionary :

The only thing left to do is the Map method. For that, we just have to get the lambdas for the from and to types, then call all of them on the two objects :

Now, you can use your class like this :

Here is the full code for the OurOwnMapper class :

Not so complicated, is it ?