Fermer

décembre 2, 2021

Voici quelques-unes de mes choses préférées


Dans cet article, explorons les fonctionnalités de .NET 6 telles que le rechargement à chaud, les API minimales, la journalisation HTTP et les améliorations de Blazor.

Pour le deuxième mois de novembre consécutif, les développeurs .NET ont reçu un cadeau de vacances : sortie de la plateforme .NET. Le mois dernier, Microsoft a rendu .NET 6 accessible à tous et a organisé une conférence virtuelle pour célébrer ses nouvelles fonctionnalités.

Quels étaient les objectifs de .NET 6 ? Si vous regardez themesof.netvous pouvez rapidement voir les thèmes de la version .NET 6, qui incluent certains des éléments suivants :

  • Appel aux nouveaux développeurs, étudiants et nouveaux technologues
  • ]Améliorez le démarrage et le débit à l'aide des informations sur les exceptions d'exécution
  • L'expérience de développement d'applications client
  • Reconnue comme un cadre convaincant pour les applications natives du cloud
  • Améliorez les performances de la boucle interne pour les développeurs .NET

Nous pourrions passer le prochain 10 articles de blog sur toutes les nouvelles améliorations et fonctionnalités de .NET 6. J'adorerais faire ça, mais je n'ai même pas commencé à magasiner pour les vacances.

Au lieu de cela, j'aimerais montrer certaines de mes choses préférées que je vais utiliser sur mes projets .NET 6. La plupart de ces changements tournent autour du développement Web dans ASP.NET Core 6 puisque ce site se concentre sur ces sujets. Capacité de rechargement dans .NET 6. Nous avons parcouru un long chemin depuis, mais j'ai ressenti la même chose que maintenant : c'est le plus gros coup de pouce à la productivité d'un développeur Web .NET au cours des dernières années. Si vous n'êtes pas familier avec le rechargement à chaud, récapitulons rapidement.

L'idée de « rechargement à chaud » existe depuis plusieurs années : vous enregistrez un fichier et le changement apparaît presque instantanément. Une fois que vous travaillez avec le rechargement à chaud, il est difficile de revenir en arrière.

Alors que l'équipe .NET essaie d'attirer des étrangers et de nouveaux développeurs, ne pas disposer de cette fonctionnalité peut être un échec pour les étrangers : c'est un enjeu de table pour de nombreux développeurs. Le concept est assez populaire dans l'espace frontend, et les développeurs .NET le demandent depuis un certain temps. (Certes, introduire le rechargement à chaud dans un langage à typage statique est beaucoup plus complexe que de le faire pour un langage interprété traditionnellement comme JavaScript.)

Avec .NET 6, vous pouvez utiliser le rechargement à chaud pour apporter des modifications à votre application sans avoir à redémarrer ou le reconstruire. Hot Reload ne fonctionne pas seulement avec le contenu statique non plus, il fonctionne avec la plupart des cas d'utilisation C# et préserve également l'état de votre application, mais vous voudrez consulter les documents Microsoft pour en savoir plus sur application non prise en charge scénarios.

Voici un exemple rapide pour montrer comment l'état de l'application est préservé dans une application Web Blazor. Si je suis au milieu d'une interaction et que je mets à jour le currentCount de 0 à 10les choses seront-elles réinitialisées ? Non! Remarquez comment je peux continuer à augmenter le compteur, puis mon compteur commence à 10 lorsque j'actualise la page.

Hot Reload preserve state" title="Hot Reload preserve state"/></p data-recalc-dims=

Vous pouvez tirer parti de Hot Rechargez de la manière que vous préférez : les IDE puissants comme JetBrains Rider et Visual Studio 2022 ont cette capacité. Vous pouvez également l'utiliser à partir de la ligne de commande si vous préférez (oui, nous le faisons). Il est important de mentionner que cela fonctionne pour toutes les applications Web ASP.NET Core.

API minimales

Avez-vous déjà voulu écrire des API simples dans ASP.NET Core rapidement mais vous êtes senti impuissant pléthore d'ASP.NET Core MVC, souhaitant pouvoir disposer d'un modèle de type Express pour écrire des API ?

L'équipe ASP.NET a déployé des API minimales, un nouveau moyen simple de créer de petits microservices et les API HTTP dans ASP.NET Core.Les API minimales se connectent aux capacités d'hébergement et de routage d'ASP.NET Core et vous permettent de créer ld des API entièrement fonctionnelles avec seulement quelques lignes de code.

Les API minimales ne remplacent pas la création d'API avec MVC – si vous créez des API complexes ou préférez MVC, vous pouvez continuer à l'utiliser comme vous l'avez toujours fait – mais c'est une excellente approche à l'écriture d'API simples. Nous en avons parlé en juinmais les choses ont beaucoup évolué depuis. Écrivons une API simple pour le montrer.

Tout d'abord, les bases : grâce aux lambdas, aux instructions de haut niveau et aux utilisations globales de C# 10, c'est tout ce qu'il faut pour écrire un « Bonjour, Telerik ! » API.

var application = WebApplication.Créer(args);
app.MapGet("/", () => "Bonjour, Telerik!"[19659028]);
app.Run();

Bien sûr, nous voudrons dépasser les bases. Comment puis-je vraiment l'utiliser ? En utilisant WebApplicationvous pouvez ajouter un middleware comme vous le feriez auparavant dans la méthode Configure dans Startup.cs. Dans .NET 6, votre configuration s'effectue dans Program.cs au lieu d'une classe Startup distincte.

var app = WebApplication.Créer (args);
app.UtiliserResponseCaching();
app.UtiliserResponseCompression();
app.UseStaticFiles();



app.Run();

Si vous voulez faire quelque chose de substantiel, cependant, vous voudrez ajouter des services à l'aide d'un WebApplicationBuilder (encore une fois, comme vous le feriez généralement auparavant dans la méthode ConfigureServices dans Startup.cs):

var builder = WebApplication. Créer Générateur(args);
constructeur.Services.AddSingleton<MyCoolService>();
constructeur.Services.AddSingleton<MyReallyCoolService>();

constructeur.Services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", nouveau() {
        Titre = builder.Environnement.ApplicationName, Version = "v1" } );
});

var application = builder.Build()[19659028];



app.Run();

En réunissant le tout, écrivons une API CRUD simple qui fonctionne avec Entity Framework Core et un DbContext . Nous allons travailler avec des super-héros parce que, apparemment, c'est ce que je fais. À l'aide des types d'enregistrementnous pouvons également rendre nos modèles de données un peu moins détaillés.

à l'aide de Microsoft.EntityFrameworkCore;

var  builder = WebApplication.CreateBuilder(args);
constructeur.Services.AddDbContext<SuperheroDb>(o => o.UseInMemoryDatabase("Superheroes"));

constructeur.Services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", nouveau() {
        Titre = builder.Environnement.ApplicationName, Version = "v1" } );
});

var application = builder.Build()[19659028];

app.MapGet("/superheroes", async (SuperheroDb db) =>[19659082]{
    wait db.Superheroes.ToListAsync();
}) ;

app.MapGet("/superheroes/{id}", async (SuperheroDb db, int id) =>
{
    wait db.Super-héros.FindAsync( id) est Super-héros super-héros ?
    Résultats.Ok(superhero)  : Résultats.NotFound();[19659082]});

app.MapPost("/superheroes", async (SuperheroDb db, Superhero hero)  =>
{
    db.Superheroes.Add(hero);
    wait db.SaveChangesAsync[19659028]();

    retourner Résultats.Créé($"/superheroes/{hero.Id}"[19659028], héros);
});

app.MapPut("/superheroes/{id}",
    async (SuperheroDb db, int id, Superhero heroInput) =>
    {
        var hero = wait db.Super-héros.FindAsync(id);
        
        if (héros est null )
           retourner Résultats.NotFound();

        db.Update(heroInput);
        wait db.SaveChangesAsync()[19659028];

        retourner Résultats.NoContent();
    });


app.MapDelete("/superheroes/{id}",
    async (SuperheroDb db, int id) =>
    {
        var hero = wait db.Super-héros .FindAsync(id);
        if (hero is null)
            return Résultats.NotFound();

        db.Super-héros.Supprimer(hero);
        wait db.Enregistrer les modificationsAsync[19659028]();
        retourner Résultats.Ok();
    }) ;

application.Exécuter();

record Superhero(int Id, string? Name, int maxSpeed)[19659028];

class SuperheroDb :DbContext
{
    public SuperheroDb(DbContextOptions<SuperheroDb> options)
        : base[19659028](options) { }

    public DbSet<Superhero> Superheroes =>  Set<Superhero>();
}

Comme vous pouvez le voir, vous pouvez faire un beaucoup avec un minimum d'API tout en les gardant relativement légers. Si vous souhaitez continuer à utiliser MVC, c'est votre choix, mais avec les API dans .NET, vous n'avez plus à vous soucier de la surcharge de MVC si vous ne le souhaitez pas. Si vous voulez en savoir plus, David Fowler a rédigé un document complet sur la façon d'exploiter des API minimales — cela vaut la peine de vérifier.

En regardant l'exemple de code ci-dessus, il est facile de se demander si c'est toute une course pour voir ce que nous pouvons jeter dans le fichier Program.cs et à quel point il est facile de devenir désordonné. Cela peut arriver dans n'importe quelle application – je ne sais pas pour vous, mais j'ai vu ma part de contrôleurs qui étaient nombreux à être abusés.

Il est essentiel de voir la vraie valeur de ce modèle – pas à quel point il est cool et sexy. consiste à écrire une API .NET CRUD entière dans un seul fichier, mais la possibilité d'écrire des API simples avec des dépendances minimales et des performances exceptionnelles. Si les choses semblent compliquées, organisez votre projet comme bon vous semble, comme vous l'avez toujours fait. Je l'ai fait plus que je ne voudrais l'admettre. .NET 6 introduit le middleware de journalisation HTTP pour les applications ASP.NET Core qui enregistrent des informations sur les demandes et les réponses HTTP pour vouscomme :

  • Demander des informations
  • Propriétés
  • En-têtes
  • Données corporelles
  • Informations de réponse

Vous pouvez également sélectionner les propriétés de journalisation à inclure, ce qui peut également améliorer les performances.

Pour commencer, ajoutez ceci dans le middleware de votre projet :

public void  Configurer(Application IApplicationBuilder, IWebHostEnvironment env)
{
    app.UtiliserHttpLogging();

    
}

Pour personnaliser l'enregistreur, vous pouvez utiliser AddHttpLogging :

public[19659087]void ConfigureServices(IServiceCollection services)
{
    services.AddHttpLogging(logging =>
    {
        logging.LoggingFields = HttpLoggingFields.All;
        logging.RequestHeaders.Add("X-Request-Header");
        logging.ResponseHeaders.Add("X-Response-Header");
        journalisation.RequestBodyLogLimit = 4096;
        logging.ResponseBodyLogLimit = 4096;
    });
}

Si nous voulons coupler cela avec une API minimale , voici à quoi cela ressemblerait :

using Microsoft.AspNetCore.HttpLogging;

var builder = Application Web.CreateBuilder(args);
builder.Services.AddHttpLogging(logging =>
{
    logging.LoggingFields = HttpLoggingFields.All;
    logging.RequestHeaders.Add("X-Request-Header");
    logging.RequestHeaders.Add("X-Response-Header");
    journalisation.RequestBodyLogLimit = 4096;
    logging.ResponseBodyLogLimit = 4096;
});

var app = builder.Construire();
app.UtiliserHttpLogging();

app.MapGet("/", () => "Je viens d'enregistrer la requête HTTP ! ");

app.Run();

Blazor Improvements

.NET 6 est livré avec de nombreuses mises à jour importantes pour Blazorle côté client Bibliothèque d'interface utilisateur fournie avec ASP.NET Core. Je souhaite discuter de mes mises à jour préférées : limites d'erreur, composants dynamiques et préservation de l'état pré-rendu. Lorsqu'une exception non gérée se produit dans Blazor Server, elle est traitée comme une erreur fatale car le circuit se bloque dans un état indéfini. Par conséquent, votre application est presque morte, elle perd son état et vos utilisateurs reçoivent un message indésirable Une erreur non gérée s'est produiteavec un lien pour recharger la page.

Inspiré. par les limites d'erreur dans React, le composant ErrorBoundary tente de détecter les erreurs récupérables qui ne peuvent pas corrompre l'état de manière permanente – et comme la fonctionnalité React, il rend également une interface utilisateur de secours.

Je peux ajouter un ErrorBoundary autour du @Body de la mise en page par défaut d'une application Blazor, comme ceci.

<div class="main">
    <div class="content px-4">[19659437]<ErrorBoundary>
            @Body
        </ErrorBoundary>
    </div>
</div>

Si je reçois une exception non gérée, je reçois le message d'erreur de secours par défaut.

message de limite d'erreur : une erreur s'est produite

Bien sûr, vous pouvez toujours personnaliser l'interface utilisateur vous-même.

<ErrorBoundary>
    <ChildContent>
        @Body
    </ChildContent>
    <ErrorContent>
        <p class="custom- erreur">Woah, que s'est-il passé ?</p>
    </ErrorContent>
</ErrorBoundary>

Si vous souhaitez le traitement complet, consultez mon article du début de l'été. Il tient toujours (même les références MAUI Man).

Composants dynamiques

Que se passe-t-il si vous souhaitez rendre vos composants dynamiquement lorsque vous ne connaissez pas vos types à l'avance ? Auparavant, Blazor était pénible à travers un arbre de rendu personnalisé ou la déclaration d'une série de composants RenderFragment. Avec .NET 6, vous pouvez rendre un composant spécifié par type. Lorsque vous importez le composant, vous définissez le Type et éventuellement un dictionnaire de Parameters.

<DynamicComponent Type=" @myType" Parameters="@myParameterDictionary" />

Je trouve dynamique composants particulièrement utiles lorsque vous travaillez avec des données de formulaire : vous pouvez afficher des données en fonction des valeurs sélectionnées sans parcourir un tas de types possibles. Si cela vous intéresse (ou si vous aimez les fusées), consultez la documentation officielle.

Préservation de l'état pré-rendu

Malgré toutes les améliorations de performances et de coupe avec Blazor WebAssembly, le temps de chargement initial reste une considération. Pour vous aider, vous pouvez pré-afficher des applications à partir du serveur pour vous aider avec son temps de chargement perçu. Cela signifie que Blazor peut immédiatement restituer le code HTML de votre application pendant qu'il câble ses bits dynamiques. C'est très bien, mais cela signifiait également auparavant que tout état était perdu. Pour conserver l'état, il existe un nouvel assistant de balise persist-component-state que vous pouvez utiliser :

<component type="typeof( App)" render-mode="ServerPrerendered" />
    <persist-component- state />

Dans votre code C#, vous pouvez injecter PersistComponentState et enregistrer un événement pour récupérer et finalement conserver les objets. Lors des chargements suivants, votre méthode OnInitializedAsync peut récupérer les données de l'état persistant. Si elle n'existe pas, elle obtiendra les données de votre méthode d'origine (généralement un service quelconque).

Pour le voir en action, consultez la Documentation Microsoft.

Mises à jour C# 10

En plus de .NET 6, nous avons également une nouvelle version de C#—C# 10. Elle est livrée avec quelques nouvelles fonctionnalités intéressantes, telles que les espaces de noms à portée de fichier, les utilisations globales, les améliorations lambda, les modèles de propriétés étendus, les vérifications d'arguments nuls et bien plus encore. Consultez le billet de blog de Joseph Guadagno pour plus de détailsainsi que le billet de blog de Microsoft.




Source link