Fermer

novembre 29, 2023

Packages NuGet essentiels (partie 2)

Packages NuGet essentiels (partie 2)


Voici cinq packages supplémentaires qui vous aideront à démarrer votre apprentissage dans ASP.NET Core.

Les packages NuGet jouent un rôle essentiel dans le développement d’ASP.NET Core, offrant un moyen simple de gérer les dépendances, d’améliorer l’efficacité, de garantir la sécurité et d’accélérer le processus de développement, ce qui les rend indispensables pour créer des applications Web modernes et robustes et gagner du temps et des efforts.

Dans le première partie des packages NuGet essentiels pour les débutantsnous avons exploré cinq packages qui contribuent à simplifier le développement d’une application Web en générant automatiquement des bases de données et des tables, en enregistrant les informations, en validant et en documentant.

Dans cette deuxième partie, nous découvrirons cinq autres packages qui vous aideront à faire évoluer une application, en facilitant sa maintenance et en garantissant sa qualité.

À la fin de l’article, vous pouvez développer des applications Web robustes et de bonne qualité dans ASP.NET Core à l’aide de cinq packages NuGet : Dapper, RestSharp, Newtonsoft.json, XUnit et Humanizer.

Conditions préalables

  • Pour créer l’application, vous devez avoir .FILET version 7 ou supérieure installée.
  • Vous avez également besoin d’un terminal pour exécuter les commandes .NET.

Création de l’application et installation des packages NuGet

Pour l’exemple de cet article, nous allons créer une API minimale. Vous pouvez accéder à l’application le code source ici.

Pour créer le modèle de base de l’API, exécutez la commande ci-dessous dans le terminal :

dotnet new web -o CustomerManagement

Ouvrez l’application avec votre IDE préféré. Cet article utilise Visual Studio Code.

Créons maintenant les classes qui représenteront l’entité de l’application. Dans le projet, créez un nouveau dossier appelé « Modèles » et, à l’intérieur, créez les classes et l’enregistrement ci-dessous :

namespace CustomerManagement.Models;

public class Customer
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
    public Address Address { get; set; }

    public Customer(Guid id, string name, string email, Address address)
    {
        Id = id;
        Name = name;
        Email = email;
        Address = address;
    }
}
namespace CustomerManagement.Models;

public class Address
{
    public Guid Id { get; set; }
    public string Street { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string PostalCode { get; set; }
    public string Country { get; set; }
    public Guid CustomerId { get; set; }

    public Address(Guid id, string street, string city, string state, string postalCode, string country, Guid customerId)
    {
        Street = street;
        City = city;
        State = state;
        PostalCode = postalCode;
        Country = country;
        CustomerId = customerId;
    }
}
namespace CustomerManagement.Models;

public record CustomersByCountryDto(Guid Id, string Name, string Email);

Installons maintenant le premier package NuGet, un excellent ORM pour travailler avec des données, Dapper.

1. Pimpant

Pimpant est un logiciel open source mappage objet-relationnel (ORM) bibliothèque développée pour .NET qui vise à faciliter l’accès et la manipulation des données dans les bases de données relationnelles grâce à une alternative légère et performante aux frameworks ORM traditionnels.

Dapper est largement utilisé car il permet aux développeurs d’exécuter des requêtes SQL directement dans leurs applications, mappant les résultats aux objets C# de manière efficace et rapide. Grâce à ses capacités de réflexion et de métaprogrammation, Dapper minimise les frais généraux et améliore l’efficacité, ce qui en fait un choix populaire pour les projets nécessitant des performances optimisées dans les applications .NET.

Alors, utilisez la commande ci-dessous pour installer Dapper dans le projet :

dotnet add package Dapper

Un point important est que dans cet exemple, nous utiliserons MySQL comme base de données, vous devez donc disposer d’un serveur MySQL exécuté dans votre environnement local. Cet article ne vous apprend pas comment configurer MySQL localement, mais il existe plusieurs tutoriels sur Internet expliquant comment procéder. Le référentiel du projet GitHub dispose d’un fichier de configuration Docker si vous préférez utiliser MySQL dans un conteneur Docker.

Un autre package NuGet requis est MySql.Data, utilisé pour effectuer des opérations SQL sur la base de données MySQL. Ensuite, utilisez la commande ci-dessous pour télécharger les dépendances MySQL.Data dans le projet.

dotnet add package MySql.Data

Pour utiliser Dapper, créons une classe de référentiel pour nous connecter à la base de données. Créez ensuite un nouveau dossier appelé « Data » et à l’intérieur, créez l’interface et la classe ci-dessous :

using CustomerManagement.Models;

public interface ICustomerRepository
{
    Task<List<CustomersByCountryDto>> FindByCountry(string country);
}
using System.Data;
using CustomerManagement.Models;
using Dapper;
using Microsoft.Extensions.Options;
using MySql.Data.MySqlClient;

namespace CustomerManagement.Data;

public class CustomerRepository : ICustomerRepository
{
    private readonly IDbConnection _db;
    public CustomerRepository(IOptions<ConnectionString> connectionString)
    {
        _db = new MySqlConnection(connectionString.Value.ProjectConnection);
    }

    public async Task<List<CustomersByCountryDto>> FindByCountry(string country)
    {
        string query = @"select 
                            c.id,
                            c.name,
                            c.email
                        from customers c
                        inner join addresses a
                        on c.id = a.customerId
                        where a.country = @Country";

        var customersByCountry = await _db.QueryAsync<CustomersByCountryDto>(query, new { Country = country });
        return customersByCountry.ToList();
    }
}

Notez que dans le code ci-dessus, nous transmettons la chaîne de connexion à la base de données au constructeur de classe et créons une méthode pour renvoyer les données des clients de la base de données.

Notez également que nous déclarons le code SQL dans une chaîne et le transmettons au serveur Dapper. QueryAsync() méthode à exécuter.

La base de données et les tables n’existent pas encore, vous pouvez donc utiliser le script SQL ci-dessous pour créer la base de données et les tables, et insérer des exemples de données. Exécutez-les simplement sur votre serveur MySQL local.

  • Script pour créer la base de données et les tables

CREATE DATABASE IF NOT EXISTS customer_db;


USE customer_db;


CREATE TABLE IF NOT EXISTS customers (
    id CHAR(36) PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    email VARCHAR(100) NOT NULL
);


CREATE TABLE IF NOT EXISTS addresses (
    id CHAR(36) PRIMARY KEY,
    street VARCHAR(100) NOT NULL,
    city VARCHAR(50) NOT NULL,
    state VARCHAR(50) NOT NULL,
    postalCode VARCHAR(20) NOT NULL,
    country VARCHAR(50) NOT NULL,
    customerId CHAR(36) NOT NULL,
    CONSTRAINT fk_addresses_customers FOREIGN KEY (customerId)
    REFERENCES customers(Id)
    ON DELETE CASCADE
);
  • Script pour insérer les données

USE customer_db;


INSERT INTO customers (id, name, email)
VALUES
    ('ba7991a3-22c3-473b-8421-676b714c2181', 'John Doe', 'john.doe@example.com'),
    ('8bc247b0-bfa8-44d9-b1ff-0533655d74c9', 'Jane Smith', 'jane.smith@example.com'),
    ('81f4a9ef-2cc3-422d-89fd-6ba7c4a5fda3', 'David D. Clifford', 'david.cli@example.com');


INSERT INTO addresses (id, street, city, state, postalCode, country, customerId)
VALUES
    ('b41a07a6-6cfc-4195-8579-c6bf0b605ea1', '2592 Boundary Street', 'Jacksonville', 'Florida', '32202', 'USA', 'ba7991a3-22c3-473b-8421-676b714c2181'),
    ('6b155fb2-3be8-4fdc-8c00-947670d28644', '456 Elm Avenue', 'Hythe', 'Alberta', '67890', 'Canada', '8bc247b0-bfa8-44d9-b1ff-0533655d74c9'),
    ('a432b04c-c380-46f9-bbc2-7b68240c557d', '1224 James Martin Circle', 'Columbus', 'Ohio', '43212', 'USA', '81f4a9ef-2cc3-422d-89fd-6ba7c4a5fda3');

L’étape suivante consiste à ajouter la chaîne de connexion et la configuration de la classe du référentiel. Dans le fichier « appsettings.json » présent à la racine du projet, ajoutez le code ci-dessous. N’oubliez pas de le modifier avec vos informations d’identification MySQL.

"ConnectionStrings": {
  "ProjectConnection": "host=localhost; port=3306; database=customer_db; user=YOURMYSQLUSER; password=YOURMSQLPASSWORD;"
  },

Maintenant dans le fichier « Program.cs », ajoutez les lignes de code suivantes juste en dessous de l’endroit où la variable « builder » est créée :

builder.Services.AddTransient<ICustomerRepository, CustomerRepository>();
builder.Services.Configure<ConnectionString>(builder.Configuration.GetSection("ConnectionStrings"));

La dernière étape pour tester l’API consiste à créer un point de terminaison pour accéder au référentiel et renvoyer les données. Toujours dans le fichier « Program.cs », ajoutez le code ci-dessous :

app.MapGet("/v1/customers/by_country/{country}", async ([FromServices] ICustomerRepository repository, string country) =>
{
    var customers = await repository.FindByCountry(country);
    return customers.Any() ? Results.Ok(customers) : Results.NotFound("No records found");
})
.WithName("FindCustomersByCountry");

Pour tester l’application, exécutez simplement la commande ci-dessous dans le terminal :

dotnet run --urls=http://localhost:5000

Si vous accédez dans votre navigateur à l’adresse http://localhost:5000/v1/customers/by_country/USAvous aurez le résultat suivant :

Exécuter l'application

Notre API est fonctionnelle et renvoie correctement les données, mais imaginez que vous deviez appeler le point de terminaison /v1/customers/by_country via une autre API. Comment cela se ferait-il ? Il existe plusieurs façons, et l’une des plus simples et des plus directes consiste à utiliser un package NuGet appelé RestSharp.

2. Reposez-vous

ResteSharp est un package NuGet qui rend la communication avec les API RESTful plus simple et plus efficace. Grâce à son ensemble de fonctionnalités avancées, RestSharp permet aux développeurs d’envoyer facilement des requêtes HTTP telles que GET, POST et DELETE et prend également en charge la manipulation de données dans des formats standard tels que JSON et XML.

De plus, la bibliothèque facilite la sérialisation et la désérialisation des objets, rendant plus fluide l’intégration des applications avec les services Web en convertissant automatiquement les données entre les formats d’objet et les structures de données.

RestSharp permet aux développeurs de se concentrer sur la logique des applications tandis que la bibliothèque gère les aspects complexes de la communication inter-API.

Pour implémenter RestSharp, nous allons créer une nouvelle API. Utilisez donc la commande ci-dessous dans le terminal :

dotnet new web -o CustomerProcess

Ouvrez ensuite le projet avec votre IDE et exécutez la commande suivante dans le terminal pour télécharger la dépendance RestSharp dans le projet :

dotnet add package RestSharp

Implémentons maintenant la communication avec l’API que nous avons créée précédemment. Pour cela, dans le projet « CustomerProcess », remplacez le code existant dans le fichier « Program.cs » par le code suivant :

using RestSharp;
using Microsoft.AspNetCore.Mvc;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddTransient<IRestClient, RestClient>();
var app = builder.Build();

app.MapGet("/v1/get_customers_by_country/{country}", async ([FromServices] IRestClient restClient, string country) =>
{
    var request = new RestRequest($"http://localhost:5000/v1/customers/by_country/{country}", Method.Get);
    var response = await restClient.ExecuteAsync(request);

    if (response.IsSuccessful)
        return Results.Ok(response.Content);
    else
        return Results.BadRequest($"Error: {response.StatusCode}");
});

app.Run();

Dans le code ci-dessus, nous créons la configuration RestSharp via le AddTransient<IRestClient, RestClient>() méthode. Ensuite, nous définissons un point de terminaison pour accéder à l’API, qui crée un nouvel objet de type RestRequest en passant le chemin de l’API créée précédemment.

Dans les scénarios du monde réel, les routes API externes sont généralement accessibles via des fichiers avec une extension « .env », mais pour simplifier les choses, dans cet exemple, nous déclarons la route directement dans l’objet.

Enfin, nous utilisons RestSharp ExecuteAsync() méthode pour exécuter la requête et renvoyer le résultat.

Pour tester, assurez-vous que l’API du projet « CustomerManagement » s’exécute sur le port 5000, puis exécutez la commande suivante dans le terminal du projet « CustomerProcess » :

dotnet run --urls=http://localhost:5054

Ensuite, dans votre navigateur, rendez-vous à l’adresse suivante :

http://localhost:5054/v1/get_customers_by_country/USA

Et vous devriez avoir le résultat suivant :

Accéder à l'API avec RestSharp

Notez que nous pouvons accéder facilement à l’API qui renvoie les données client en transmettant la route d’accès à RestSharp. Dans le scénario post, nous n’avons qu’une seule API, mais imaginez si nous en avions des dizaines. Il serait très simple de mettre en œuvre plusieurs requêtes.

Dans cet article, nous examinons simplement une implémentation simple de RestSharp, mais de nombreuses autres ressources sont disponibles. Si vous le souhaitez, vous pouvez les découvrir sur le site officiel de RestSharp.

3. Newtonsoft.Json

Malgré sa simplicité, Newtonsoft.Json est très utile, car il facilite le travail des développeurs Web qui doivent gérer quotidiennement les données de requêtes et de réponses.

De plus, la possibilité de personnaliser le processus de sérialisation et de désérialisation, ainsi que des fonctionnalités avancées telles que la prise en charge de LINQ, font du package un outil polyvalent et puissant pour manipuler les données JSON dans une variété de scénarios de développement.

Pour télécharger NewtonSoft.Json dans le projet « CustomerProcess », utilisez la commande suivante :

dotnet add package Newtonsoft.Json

Maintenant, toujours dans le projet « CustomerProcess », créez un nouveau dossier appelé « Models » et, à l’intérieur, créez l’enregistrement ci-dessous :

namespace CustomerProcess.Models;

public record Customer(Guid Id, string Name, string Email);

Puis dans le fichier « Program.cs », remplacez le code existant par le code suivant :

using RestSharp;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using CustomerProcess.Models;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddTransient<IRestClient, RestClient>();
var app = builder.Build();

app.MapGet("/v1/get_customers_by_country/{country}", async ([FromServices] IRestClient restClient, string country) =>
{
    var request = new RestRequest($"http://localhost:5000/v1/customers/by_country/{country}", Method.Get);
    var response = await restClient.ExecuteAsync(request);
    var customers = JsonConvert.DeserializeObject<List<Customer>>(response.Content);

    if (response.IsSuccessful)
        return Results.Ok(customers);
    else
        return Results.BadRequest($"Error: {response.StatusCode}");
});

app.Run();

Notez que dans le code ci-dessus, nous recevons les données de l’API du projet « CustomerManagements » et transmettons la réponse à la méthode Newtonsoft.Json : JsonConvert.DeserializeObject<List<Customer>>(response.Content) et renvoyer l’objet JSON dans la réponse API.

Testons maintenant et voyons la différence. Exécutez les deux projets et dans votre navigateur, accédez à l’adresse http://localhost:5054/v1/get_customers_by_country/USA à nouveau dans votre navigateur. Vous aurez maintenant les données formatées, car Newtonsoft.JSON désérialise l’objet.

Désérialiser les données

4. Unité X

UnitéX est une bibliothèque de tests unitaires largement utilisée dans l’écosystème .NET.

Grâce à une approche simple et extensible de l’écriture et de l’exécution de tests, XUnit devient une excellente option pour le développement piloté par les tests (TDD), en plus de prendre en charge des fonctionnalités avancées telles que les tests paramétrés et le partage de contexte entre les cas de test, ce qui en fait un choix populaire pour les projets. de toutes tailles.

Pour en savoir plus sur certaines fonctionnalités de XUnit, créons une classe avec une méthode pour valider les données client dans le projet CustomerProcess. Créez un nouveau dossier appelé « Services » et, à l’intérieur, créez une nouvelle classe appelée « CustomerService.cs » et mettez-y le code suivant :

using CustomerProcess.Models;
namespace CustomerProcess.Services;

public class CustomerService
{
    public string ValidateCustomer(Customer customer)
    {
        string errorMessage = string.Empty;
        if (string.IsNullOrEmpty(customer.Name))
            errorMessage += "Customer name cannot be null or blank";

        if (string.IsNullOrEmpty(customer.Email))
            errorMessage += "Customer email cannot be null or blank";

        return errorMessage;
    }
}

Créons maintenant un projet de test. Par définition, ASP.NET Core dispose déjà d’un modèle pour implémenter un projet de test XUnit. Pour le créer, exécutez simplement les commandes ci-dessous :

dotnet new xunit -n CustomerProcessTest
cd CustomerProcessTest
dotnet add reference ../CustomerProcess.csproj

Lors de l’exécution des commandes ci-dessus, un projet de test portant le nom « CustomerProcessTest » a été créé. Lorsque vous l’ouvrirez, vous remarquerez qu’il existe un fichier portant le nom « Test1.cs ». Renommez-le « ValidationTest », puis remplacez le code existant par le code ci-dessous :

using CustomerProcess.Models;
using CustomerProcess.Services;

namespace CustomerProcessTest
{
    public class ValidationTest
    {
        [Fact]
        public void ValidateCustomerValid()
        {
            
            var customer = new Customer(Guid.NewGuid(), "John", "john@mail.com");
            var service = new CustomerService();

            
            string errorMessage = service.ValidateCustomer(customer);

            
            Assert.Empty(errorMessage);
        }

        [Fact]
        public void ValidateCustomerInValid()
        {
            
            var customer = new Customer(Guid.NewGuid(), string.Empty, string.Empty);
            var service = new CustomerService();

            
            string errorMessage = service.ValidateCustomer(customer);

            
            Assert.NotEmpty(errorMessage);
            Assert.Contains("Customer name cannot be null or blank", errorMessage);
            Assert.Contains("Customer email cannot be null or blank", errorMessage);
        }
    }
}

Notez que, dans le code ci-dessus, nous créons deux méthodes de test. Tous deux ont le [Fact] attribut pour indiquer à XUnit qu’ils doivent être exécutés. Il est courant de trouver la structure Organiser> Agir> Affirmer dans les tests unitaires-où dans Arrange nous définissons les variables et les objets, dans Act le test est exécuté et dans Assert le résultat est vérifié.

Dans cet exemple, dans la première méthode, nous validons si un client est valide. Dans ce cas, la chaîne « errorMessage » doit être vide. Dans le deuxième test, nous vérifions s’il est invalide ; dans ce cas, la chaîne doit être renseignée et avec les messages d’erreur correspondants.

Pour exécuter les tests, ouvrez simplement un terminal dans le projet « CustomerProcessTest » et exécutez la commande dotnet test et vous devriez avoir le résultat suivant :

Résultat du test

5. Humaniseur

Humaniseur est un package NuGet très utile pour les applications ASP.NET Core car il facilite le formatage des données, les rendant plus lisibles et conviviales.

Les fonctionnalités d’Humanizer incluent le formatage des nombres et des quantités, le formatage de la date et de l’heure, la pluralisation et la singularisation et la capitalisation, entre autres, qui aident les développeurs à formater les nombres, les dates, les heures et les quantités d’une manière plus naturelle et compréhensible, sans avoir besoin de mettre en œuvre des méthodes et des méthodes complexes. les fonctions.

Ensuite, dans le terminal du projet « CustomerProcess », exécutez la commande suivante pour télécharger l’Humanizer dans le projet :

dotnet add package Humanizer

Explorons maintenant certaines des fonctionnalités de Humanizer.

Formatage des nombres

Avec Humanizer, nous pouvons transformer des nombres écrits dans leur intégralité. Par exemple, le nombre 1000 devient mille.

Pour ce faire, dans le fichier Programme, ajoutez une référence à l’Humanizer : using Humanizer;. Ajoutez ensuite le code ci-dessous :

int number = 1000;
string formattedNumber = number.ToWords();
Console.WriteLine(formattedNumber);

Maintenant, si vous exécutez la commande dotnet run vous obtiendrez le résultat suivant :

Formatage des nombres

Formatage de la date et de l’heure

Pour formater les dates et les heures, utilisez simplement les méthodes d’extension :

  • date.Humanize() pour indiquer le moment présent
  • pastDate.Humanize() pour indiquer un moment dans le passé
  • futureDate.Humanize() pour indiquer une heure dans le futur

Donc pour tester les fonctions de formatage de la date et de l’heure, ajoutez le code suivant :

DateTime date = DateTime.Now;
string humanizedDate = date.Humanize();
Console.WriteLine(humanizedDate);

DateTime pastDate = DateTime.Now.AddHours(-2);
string humanizedPastDate = pastDate.Humanize();
Console.WriteLine(humanizedPastDate);

DateTime futureDate = DateTime.Now.AddDays(1);
string humanizedFutureDate = futureDate.Humanize();
Console.WriteLine(humanizedFutureDate);

Exécutez le dotnet run commande à nouveau, et vous aurez le résultat suivant dans la console :

Formatage de la date et de l'heure

Durée de formatage

Une autre fonctionnalité importante de Humanizer est l’affichage des dates en fonction d’une plage horaire. Par exemple, ajoutez le code ci-dessous au projet puis exécutez dotnet run.

TimeSpan.FromMilliseconds(2).Humanize();
TimeSpan.FromDays(1).Humanize();
TimeSpan.FromDays(16).Humanize();

Notez que l’Humanizer a transformé les données rapportées en millisecondes, jours et semaines :

Délai de formatage

Formatage de la taille du fichier

Humanizer permet de manipuler des informations concernant la taille des données telles que Ko, Mo et Go de manière simple. Implémentons quelques fonctions et voyons comment cela fonctionne. Alors, ajoutez le code ci-dessous au projet :


long sizeInBytes = 1024;
var KBSize = sizeInBytes.Bytes().Humanize();
Console.WriteLine(KBSize);

sizeInBytes = 2097152;
var MBSize = sizeInBytes.Bytes().Humanize();
Console.WriteLine(MBSize);

sizeInBytes = 3221225472;
var GBSize = sizeInBytes.Bytes().Humanize();
Console.WriteLine(GBSize);

sizeInBytes = 5497558138880;
string TBBytes = sizeInBytes.Bytes().Humanize();
Console.WriteLine(TBBytes);

Maintenant, si vous exécutez la commande dotnet run vous obtiendrez le résultat suivant :

Taille des données de formatage

Conclusion

Dans cette deuxième partie des packages NuGet essentiels pour les débutants, nous avons vu cinq packages importants qui aident les développeurs à créer des applications de qualité et à gagner du temps en utilisant leurs précieuses ressources.

Ainsi, chaque fois que vous développez une nouvelle application et fonctionnalité, envisagez d’utiliser les packages NuGet car ils peuvent vous aider à relever presque tous les défis.




Source link

novembre 29, 2023