L'architecture d'un ASP. Application NET Core (architecture propre) | Trevoir Williams | Skillshare
Recherche

Vitesse de lecture


1.0x


  • 0.5x
  • 0.75x
  • 1 x (normale)
  • 1.25x
  • 1.5x
  • 1.75x
  • 2x

L'architecture d'un ASP. Application NET Core (architecture propre)

teacher avatar Trevoir Williams, Jamaican Software Engineer

Regardez ce cours et des milliers d'autres

Bénéficiez d'un accès illimité à tous les cours
Suivez des cours enseignés par des leaders de l'industrie et des professionnels
Explorez divers sujets comme l'illustration, le graphisme, la photographie et bien d'autres

Regardez ce cours et des milliers d'autres

Bénéficiez d'un accès illimité à tous les cours
Suivez des cours enseignés par des leaders de l'industrie et des professionnels
Explorez divers sujets comme l'illustration, le graphisme, la photographie et bien d'autres

Leçons de ce cours

    • 1.

      Introduction

      1:30

    • 2.

      Comprendre l'architecture nette

      7:03

    • 3.

      Ce que nous allons construire

      4:22

    • 4.

      Configuration de solution

      2:55

    • 5.

      Créer le projet de domaine

      6:08

    • 6.

      Créer le projet d'application

      7:14

    • 7.

      Mise en œuvre Implementing

      12:19

    • 8.

      Créer des requêtes avec MediatR

      16:18

    • 9.

      Finalisation des demandes pour MediatR

      7:42

    • 10.

      Créer des commandes avec MediatR

      12:35

    • 11.

      Finir des commandes avec MediatR

      21:39

    • 12.

      Ajouter des valeurs

      27:27

    • 13.

      Ajouter des exceptions et des objets de réponse personnalisés.

      13:14

    • 14.

      Refactorisation et considérations supplémentaires

      9:39

    • 15.

      Aperçu des sections

      1:46

    • 16.

      Ajouter du noyau d'entité

      5:37

    • 17.

      Mise en œuvre de couches de persistance

      15:27

    • 18.

      Ajouter des projets d'infrastructure (Service e-mail)

      15:59

    • 19.

      Créer et configurer et configurer l'application

      11:44

    • 20.

      Mettre en œuvre des contrôleur API

      14:56

    • 21.

      Finition des contrôles API

      4:29

    • 22.

      Données d'origine en tableaux

      4:47

    • 23.

      Examinez le soutien de Swagger

      8:26

    • 24.

      Test d'unité - Aperçu des sections

      3:23

    • 25.

      Ébaucher des tests d'unité pour le code d'application

      28:25

    • 26.

      Configuration du projet ASP.NET MVC

      2:14

    • 27.

      Utilisez NSwag pour le code de client API

      8:35

    • 28.

      Configuration des clients et code de base

      14:18

    • 29.

      Service de gestion de police de police

      12:11

    • 30.

      UI

      27:55

    • 31.

      Ajouter une authentication Json Web Token (JWT)

      36:55

    • 32.

      Ajouter l'authenticité au projet Web

      30:35

    • 33.

      Gestion de la décharge

      18:50

    • 34.

      Gestion des demandes de congé - Partie 1 - Employé

      20:53

    • 35.

      Gestion des demandes de congé - Partie 2 - Administration

      24:29

    • 36.

      Unité de travail pour des opérations en lots

      8:40

    • 37.

      Gestion d'exception API

      13:36

    • 38.

      Expirer le jeton

      8:40

    • 39.

      Expirer le jeton

      13:51

    • 40.

      Améliorer la vérification des données

      5:54

    • 41.

      Conclusion

      1:03

  • --
  • Niveau débutant
  • Niveau intermédiaire
  • Niveau avancé
  • Tous niveaux

Généré par la communauté

Le niveau est déterminé par l'opinion majoritaire des apprenants qui ont évalué ce cours. La recommandation de l'enseignant est affichée jusqu'à ce qu'au moins 5 réponses d'apprenants soient collectées.

194

apprenants

--

À propos de ce cours

Aperçu

Créer une application modulaire, testable et maintainable NET Core nécessite une base solide. La création d'une architecture d'application nécessite de nombreuses questions car les décisions précaires, auront un impact sur facilement facilement l'application et maintenir.

Toutefois, à l'échelle de long terme, les applications doivent être conservées et dans ce cas, étendue. Entre sa conception et la façon dont le code est écrit, n'est pas vraiment possible, donc l'application doit être remaniée.

Pourquoi Architecture SOLIde ?

Lorsque nous parlons d'architecture SOLID, nous faisons des questions n'est pas une tâche simple. Les décisions prises début du processus peuvent avoir un impact important sur la suite, la maintenance et la testabilité jouent un rôle important. L'adoption de ces pratiques peut également contribuer à éviter des odeurs de code, à refactoriser le code et à faciliter un développement agile plus efficace.

SOLID représente pour :

  • S - Principe de responsabilité unique

  • O - Principe ouvert

  • L - Principde l'appartenance Liskov

  • I - Principe de ségrégation d'interface

  • D'- Principe d'inversion de dépendance

Dans ce cours, vous explorez des principes architecturaux fondamentales fondamentales qui vous aident à créer du code maintainable Ensuite, vous découvrirez comment configurer une architecture d'application en monde réel avec ASP.NET Core. Vous apprendrez ensuite à brancher différents blocs communs comme des email, une authentification, et une base d'une connexion pour intégrer d'autres services tiers en fonction des besoins.

Lorsque vous terminez ce cours, vous aurez les compétences et les connaissances nécessaires pour créer une application de base ASP.NET Core nécessaires pour architecte, du monde réel et d'entreprise. Applications NET Core

Créer une base solide dans . Architecture nette 5 netdes Architecture :

  • Apprendre des architecture propres ou des bonnes pratiques en matière Learn

  • Apprendre la séparation de responsabilité des demandes de commandement (CQRS)

  • Mise en œuvre du motif Mediatr

  • Ajouter des services d'e-mail à l'aide SendGrid

  • Approche de conception axée sur le domaine de l'architecture de logiciels

  • Gestion et Routage efficaces

  • Test d'unité

  • Gérer les erreurs mondiales avec des Middleware d'intérieur et personnalisé

  • Ajouter des Adding à l'aide de valorisation fluent

  • Créer un . Application NET Core Core et MVC UI

  • Implémenter JWT(JSON Web Token

Contenu et aperçu

Pour suivre ce cours, vous devrez avoir quelques connaissances Développement NET Core et C #.

C'est un cours énormé. Plus de 10 heures de contenu premium, mais vous avez réussi à mettre en valeur un ensemble d'activités connexes basées sur chaque module de l'application en cours. Nous verrons également les erreurs de dépannage et de troubleshooting au fur et à mesure que, nous allons également en cours, nous utiliserons les meilleures pratiques, l'écriture et la compréhension efficace de la raison de développeurs font les choses à la manière. Vos connaissances développeront étape par étape, tout au long du cours, et vous serez challenged

Nous ne faisons pas les choses de la première fois, ce n'est pas la réalité de l'écriture de code. Nous faisons des erreurs et les soulignons et les fix autour d'eux. Nous développerons en ce cas avec des compétences en utilisant des outils et des techniques de débogage. À la fin du cours, vous aurez terminé dans Visuel et aurez été examiné des erreurs de logique et de syntaxe seront autant de qualités de votre nature, ce sera la seconde nature pour vous travailler lorsque vous travailler. Environnement NET. Cela permettra d'utiliser vos nouvelles compétences apprises en pratique et vous impressionnera votre patron et vos collègues de vue.

Le cours est complet avec des fichiers de travail reçus sur GitHub, avec l'inclusion de certains fichiers afin de vous faciliter la replicate le code à montrer. Vous pourrez travailler avec l'auteur pendant chaque lecture et vous recevrez un certificat vérifiable de compléter.

Rencontrez votre enseignant·e

Teacher Profile Image

Trevoir Williams

Jamaican Software Engineer

Enseignant·e

Compétences associées

Design Plus de design Architecture
Level: Intermediate

Notes attribuées au cours

Les attentes sont-elles satisfaites ?
    Dépassées !
  • 0%
  • Oui
  • 0%
  • En partie
  • 0%
  • Pas vraiment
  • 0%

Pourquoi s'inscrire à Skillshare ?

Suivez des cours Skillshare Original primés

Chaque cours comprend de courtes leçons et des travaux pratiques

Votre abonnement soutient les enseignants Skillshare

Apprenez, où que vous soyez

Suivez des cours où que vous soyez avec l'application Skillshare. Suivez-les en streaming ou téléchargez-les pour les regarder dans l'avion, dans le métro ou tout autre endroit où vous aimez apprendre.

Transcription

1. Introduction: Salut les gars, bienvenue à mon tout nouveau cours, noyau ASP.Net, architecture solide et propre. Je suis votre instructrice, Travolta Williams. J' ai plus de 10 ans d'expérience en tant qu'ingénieur logiciel et conférencier. Dans ce cours, nous allons examiner un certain nombre de choses. Nous allons envisager de mettre en œuvre des principes solides et architecture propre dans une application ASP.NET Core. cours de route, nous allons travailler avec des outils avancés comme médiateur ou l'API ascendante ou Fluent pour la validation, nous allons construire Global Exception Handling and logging. Je vais regarder le modèle C QRS, qui est un modèle merveilleux qui maintient notre code séparé et en taille de bits est pour une intégration et une extensibilité maximales. À la fin de ce cours, nous allons comprendre comment effectuer des tests unitaires, comment intégrer des services tiers dans une application et comment nous pouvons le déployer à des fins de production. Cependant, les conditions requises pour ce cours incluent Visual Studio 2019 et dotnet five, ou la dernière version. Au moment où vous suivez ce cours, tout ce que nous allons faire est à l'épreuve de l'avenir et ces principes peuvent être transférés dans les dernières versions sans problème. Pour tirer le meilleur parti de ce cours, je vous recommande d'avoir une certaine quantité de connaissances en programmation C Sharp et dotnet ainsi que des connaissances en développement de bases de données. Quoi qu'il en soit, je vais rendre le contenu très débutant convivial et vous devriez avoir absolument aucun problème à suivre le long et savoir que vous avez toutes les informations dont vous avez besoin. Je te verrai bientôt dans le cours. 2. Comprendre l'architecture nette: D' accord, nous avons donc examiné les principes qui régissent une architecture d'application propre. Voyons maintenant ce que nous entendons exactement par architecture propre. Parce que l'architecture propre ne signifie pas nécessairement un bon logiciel. Le bien est très relatif à celui qui le regarde. Par exemple, si vous avez été chargé de développer un système de gestion des chefs de file pour le département RH et que vous l'avez fait, et que les RH sont heureuses, alors c'est un bon logiciel. Cependant, si vous ne l'avez pas fait en suivant ces principes, alors cela pourrait être considéré comme un mauvais logiciel, mais pratique le développement de logiciels en général, par votre équipe ou quel que soit votre successeur lorsqu'ils essaient de maintenir cette application. L' architecture propre n'est donc pas nécessairement directement proportionnelle aux bons logiciels. Cela dépend de qui est le destinataire et à quel moment. Discutons donc de tout ce qui va dans le développement de logiciels et les différents types d'architecture afin que nous puissions pleinement apprécier quand nous aurions besoin d'intensifier nos considérations de conception un peu plus et ce que les avantages et les inconvénients de ce sont. Donc, le premier que nous voulions examiner serait tout dans une architecture unique. Et je vais tout dans une architecture, c'est plus facile à livrer. Elle peut être stable et considérée comme une solution à long terme. Tout dans une architecture pourrait facilement être quand nous avons éraflé à toute nouvelle marque est dotnet Core application. Ou si c'est la première fois que vous faites ASP.Net Core, vous êtes probablement plus familier avec Ruby on Rails ou larve ou jungle. Une fois que vous avez cette mise en page générale du projet, cela pourrait facilement être considéré comme une architecture tout-en-un. Vous avez tous les dossiers et tout ce que vous avez à faire est de créer vos fichiers, créer votre plein fait que la séparation des préoccupations juste là et tout est bon, le logiciel fonctionnera. Cependant, il est certainement difficile d'appliquer des principes solides. Plus vous devez emballer dans cette architecture tout en une seule plus les odeurs de code et les mauvaises pratiques qui pourraient devoir être compromises. Très bien, alors qu'il grandit, il devient plus difficile à maintenir et sa testabilité. Et quand nous sommes assis cette stabilité, nous entendons comme avec le débogage et par test d'unité d'extension, la possibilité de tester deux unités de tout cela dans une architecture. Cette capacité diminue au fur et à mesure que les rôles d'application. Ensuite, nous voulons examiner l'architecture en couches. Et toute architecture en couches est une étape avant tout dans une seule où au lieu de séparer nos modules ou nos morceaux de code et de fichiers, désolé, par dossiers, nous commençons à chercher à créer des projets et à référencer ces projets. Donc, dans ESP dotnet Core et dans ses obligations en général, vous pouvez développer des bibliothèques de classes où vous mettez toutes vos classes et vous faites simplement référence à elles comme vous le devez. Et puis tu finirais avec des couches différentes. Vous avez une couche qui traite des choses de l'interface utilisateur. Vous avez une couche qui a besoin avec la logique métier. Et vous avez une couche qui taxe l'inflammation entre la base de données et la logique métier. Et puis vous vous retrouvez avec une couche de notre application. Maintenant, il est plus facile, certainement d'appliquer des principes solides et il est plus facile de mintoner des bases de code plus grandes. Cependant, cela accède toujours à une application car toutes ces couches sont encore quelque peu dépendantes les unes des autres. Donc, nous ne tirons toujours pas pleinement parti de l'ensemble du principe d'inversion de dépendance, ainsi que de l'ensemble du principe de couplage lâche. Et maintenant, nous regardons le seul sur l'architecture qui est largement enseigné comme architecture propre. Maintenant, quand nous parlons uniquement de l'architecture, nous parlons de différentes façons de voir les couches. Et à ce stade, nous voulons soutenir tout type d'application. Vous voulez avoir tout très modulaire afin que nous puissions mettre dans un nouveau module sans perturber le reste de la base de code. Nous pouvons prendre le module automatique et nous pouvons faire des changements et tester plus facilement sans perturber les parties existantes de l'application. Donc, quand nous parlons de l'architecture Odeon, nous parlons peut-être d'avoir une application client pour l'interface utilisateur. Il peut s'agir d'une application Web ASP.NET. Il pourrait s'agir d'une application mobile. Nous parlons à la fois d'avoir des services API qui seront au-dessus de l'obligation sur le noyau. Et ces services d'API, une fois de plus, seraient open source. Cela ne se soucie pas vraiment de ce qu'est le client et les risques sont ce que nous allons utiliser. Mais ça ne se fiche pas si c'est un client mobile, ça ne se fiche pas si c'est un client web, un client blazer, et de la colère d'un client, C'est juste taxier les données de la base de données à celui qui écoute. Et Buck, non, les tests deviennent beaucoup plus faciles à faire parce que nous pouvons tester les différentes couches indépendamment et ensuite nous pouvons tester comment les couches interagissent les unes avec les autres. Donc, si quelque chose est introduit pour briser l'une de ces interactions existantes, alors nous pouvons le détecter plus facilement. Et à partir du début null pour l'infrastructure, nous parlons du module. Nous parlons donc de journalisation de l'accès aux données. Si nous avons plus d'une base de données que nous devons traiter, nous devrions être en mesure de mettre dans une toute nouvelle couche pour parler pour annuler la base de données sans perturber quoi que ce soit que l'architecture existante faisait avec l'ancienne base de données. Nous pouvons mettre dans la journalisation, nous pouvons mettre dans la cartographie, les validations. Tout peut entrer et notre commode sans perturber notre application. Donc, contre, cependant, il y a une courbe d'apprentissage parce que vous avez besoin de savoir ce qui était bizarre et il y a différentes interprétations de ce genre d'architecture. Donc, vous pouvez voir différentes saveurs. Si vous lisez deux ou trois sources différentes, vous verrez deux ou trois implémentations différentes de son ennemi. Je me demande lequel est celui que je devrais utiliser ? Bien sûr, le contexte détermine beaucoup de ce que vous et d'autres développeurs faites, les décisions que vous prenez dans votre architecture. Et donc, vous savez, vous avez juste à utiliser cela, juste obtenir les connaissances et utiliser votre contexte comme guide et d'autres inconvénients à ce genre d'architectures que cela peut prendre beaucoup temps parce qu'il y a beaucoup de leurs beaucoup plus de dossiers qui seront jeu quand nous pourrions faire quelque chose avec deux dossiers maintenant, il en faudra probablement cinq. Cependant, une fois de plus, les avantages seraient que nous avons un tapis lâche et plus de testabilité. Donc, avec tout cela dit, soyez prudent. Toutes les applications n'ont pas besoin d'une architecture propre. Un bon logiciel répond aux besoins de l'entreprise et un logiciel maintenable augmente la durée de vie du logiciel. Vous devez donc trouver un équilibre en tout temps. Ne voyez pas que chaque projet que vous avez à faire va avoir besoin d'une architecture propre, démarre petit et s'étendre au besoin. 3. Ce que nous allons construire: Bienvenue de retour. Dans cette vidéo, nous allons jeter un oeil à l'application que nous voulons construire ou reconstruire. Donc, sur mon écran, j'ai un système de gestion de plomb qui a été construit avec une vitesse sur elle core 3.1. Et vous voyez toutes les choses qui ont été implémentées à l'intérieur de cette solution. Maintenant, il a l'air bien et il fait ce qu'il a été conçu pour faire. Il a fourni des capacités de gestion des congés au service des RH. Vous pouvez trouver le code source pour cette application sur mon compte GitHub et vous pouvez rechercher le dépôt de gestion de tirets, dash dotnet core. En fait, c'est l'application qui a été construite dans mon cours, complète ASP.NET Core and Entity Framework Development. Pourquoi était-ce parfait pour les débutants ? C' est vrai avec beaucoup d'odeurs de code et de façons inefficaces d'écrire le code qu'un débutant peut ramasser. Mais alors que vous obtenez de plus en plus intermédiaire à avancé, vous commencerez à réaliser qu'ils sont de meilleures façons de faire ces choses. Et c'est exactement ce dont nous discuterons dans ce cours. Maintenant, je vais juste prendre et regarder la structure du projet. Et encore une fois, il est complètement facultatif de le télécharger. Vous pouvez simplement suivre, mais je vais vous montrer certains des points faibles de l'architecture et certaines des décisions qui ont été prises lors du développement de cette application. Premièrement, vous verrez que cela n'a qu'un seul projet. Maintenant, si vous vous souvenez plus tôt quand nous avons regardé les différents types d'architectures de projet, cela tomberait directement dans cette architecture tout en une, où que ce soit dans un seul projet, facile d'accès. Donc, une fois de plus, pour les débutants, c'est bien parce que vous voulez des vues, vous obtenez les vues que vous voulez que j'aille aux données. C' est toute leur séparation des préoccupations à ce stade est limitée et limitée à seulement des dossiers. Cependant, dans l'ensemble, et quand vous voulez ajouter plus de choses, ce projet peut devenir très gros lorsque vous essayez de l'étendre, donc il sera bon de le sortir. Une autre chose que notre odeur de code que nous voudrions aborder est la répétition du code. Donc, même en construisant nos modèles de données, vous verrez que nous répétons certaines des propriétés. Nous avons l'ID là, nous avons l'ID ici encore, ces petites choses dans certains des contrôleurs, nous répétons le code quand nous n'avons pas nécessairement besoin de le faire. Et puis pendant que nous sommes sur le sujet des contrôleurs, il y a ce que nous appellerons les contrôleurs de graisse ici. Donc, nous faisons beaucoup de logique métier, beaucoup de traitement ici dans le contrôleur, ce qui le rend très lourd. Vous voulez donc obstruer ces processus de logique métier loin de vos contrôleurs. Maintenant, en dehors des raisons de développement qui justifient la reconception et la ré-architecture de cette application d'un point de vue commercial ou commercial, un, HR veut étendre cette application comme elle est construite, non ? Non, il est assez difficile de le faire sans bouleverser le code existant. C' est 1, 2, ce n'est pas très testable dans son état actuel. Donc, même si nous essayons de l'étendre, nous allons avoir plus de propriétaires de tests parce que nous devons faire plus de tests de régression et de tests manuels à ce sujet. Et puis troisièmement, lorsque nous le faisons dans une vague d'architecture propre, nous avons en fait la possibilité de l'étendre à différents types d' applications clientes et potentiellement déployées en tant que logiciel en tant que service où l'API exécute toutes les logique métier et l'interaction avec la base de données et l'application cliente est complètement anonyme que nous avions. Cette application cliente aurait pu être une application MVC, il aurait pu être une application blazer, il aurait pu être une application mobile. C' est donc l'une des raisons de la proposition de valeur pour lesquelles la clé et l'architecture peuvent être mises en œuvre. Donc, pour revenir à ce que nous avons dit tout à l'heure, bon logiciel est un logiciel qui fait son travail, n'est-ce pas ? Non, c'est un bon logiciel. Le département RH est calme, heureux avec elle et comment il fait, ce qu'il doit faire. Cependant, quand ils commencent à demander plus de choses, nous réalisons sur notre technique dit qu'il devient un peu plus difficile de l' étendre, de le modifier, de le tester. Donc, là où nous la protégeons afin que nous puissions toujours fournir toutes les fonctionnalités que le département RH souhaite tout en conservant la capacité de la maintenir de manière très efficace. Dans notre prochaine leçon, nous commencerons à mettre en place la solution pour notre nouvelle architecture. 4. Configuration de solution: Bienvenue de retour. Dans notre première leçon pratique, nous allons mettre en place notre solution. J' ai donc Visual Studio 2019 ouvert. Si Visual Studio 2019 n'est pas déjà installé, vous pouvez facilement accéder à Visual Studio dot Microsoft.com barre oblique VS et télécharger l'édition de la communauté. L' édition communautaire est gratuite pour un usage éducatif et individuel. Bien sûr, si vous l'êtes, si vous êtes un commercial que vous êtes censé obtenir la version professionnelle ou la version d'entreprise. Une fois que vous l' avez téléchargé, un installateur vous sera présenté. Et ce dont vous avez vraiment besoin de cet installateur, c'est à tout le moins la charge de travail ASP.NET et de développement web. Donc en le cochant, vous indiquez que vous voulez que cela fonctionne. Vous verrez toutes les charges de travail disponibles. Vous pouvez les prendre si vous le souhaitez. Bien sûr, plus vous en prenez, plus vous devez télécharger. Mais pour ce cours, vous avez vraiment juste besoin de celui-ci qui vous donnera tous les outils nécessaires pour n'importe quelle application Web ASP.Net ainsi que dotnet cinq. Donc, une fois que vous avez terminé cette installation ou si vous l'avez déjà installé et continuez avec moi. Et nous allons créer de nouveaux projets. Donc, ce que nous allons faire est de créer une solution vide. J' ai dans mes modèles de projet récents. Mais si vous le faites en plus de cela, vous pouvez toujours rechercher une solution vide dans cette zone, puis vous obtiendrez une solution vide ne contenant aucun projet. Donc c'est ce que nous voulons et nous allons appeler ce projet H sont des points de gestion des congés. Maintenant, il n'y a pas de raison particulière pour que je l'appelle comme ça. C' est une application de gestion de plomb est en cours de construction pour le département RH. Si elle était en cours de construction pour une entreprise, alors vous voudriez probablement dire que l'entreprise point le type de système. Donc, si vous voulez, vous pouvez aller de l'avant et utiliser mon nom ou changer ce nom en conséquence. Mais une fois que vous avez mis un nom valide, vous pouvez aller de l'avant et cliquer sur Créer. Maintenant, nous n'écrirons aucun code dans cette leçon, mais nous allons mettre structure du projet comme nous en avons besoin pour la durée de ce cours ou de tout ce projet. Donc, la première chose que je vais faire est d'ajouter un dossier et je vais appeler celui-ci SRC, abrégé pour la source, et un autre dossier que nous allons appeler tests. Maintenant, sous SRC, je vais ajouter quelques dossiers supplémentaires. Je vais appeler celui-ci l'API, parce que c'est ce qui va interagir avec notre application cliente. Je vais en avoir un autre appelé core, une autre appelée structure infra, et enfin, une pour l'interface utilisateur. C' est tout ce qu'on fait pour cette leçon. On est juste en train de mettre en place la structure du projet. Donc, quand nous reviendrons, nous commencerons à créer les différents projets qui iront dans chacune de ces sections. 5. Créer le projet de domaine: Très bien les gars, bienvenue. Dans cette leçon, nous allons créer nos projets de domaine. Donc, nos projets de domaine vont sous notre dossier principal à l'intérieur de notre application, nous pouvons aller de l'avant et ajouter un nouveau projet. Et ce que nous allons faire, c'est l'ajouter en tant que bibliothèque de classes, bibliothèque Docx C-Sharp de type dotnet standard. Très bien, donc il n'est pas dans un tribord permet le partage de code sur de nombreuses plates-formes différentes. Donc, nous allons juste l'utiliser pour toutes nos bibliothèques de classes. Et nous l'appelons domaine de gestion de congé de point HR car il sera utilisé pour stocker tous nos objets de domaine ou classes d'entités qui sont traduits dans nos tables de base de données. Pour que je puisse aller de l'avant et toucher Next. Et le cadre cible ici est la norme dotnet 2.1. Allez-y et appuyez sur Créer. Maintenant, une fois que cela est fait, nous obtenons notre classe par défaut une, que nous pouvons réellement supprimer et ensuite commencer à remplir avec nos classes. Donc, en revenant à notre projet sur GitHub, juste rapidement, vous verrez que les classes de domaine ont été conservées à l'intérieur du projet dans un dossier appelé data. Nos classes de domaine comprenaient donc l'allocation des congés, les demandes de congé et le type de congé. Si vous voulez, vous pouvez aller de l'avant et les récupérer, mais je les traverserai de toute façon. Donc, si vous jetez un oeil rapide à ces classes, vous verrez que chacune a un ID, et nous avons aussi un tas de propriétés dans chacune d'elles. Donc, lorsque les propriétés de ce type de répété incluraient date créée entre le type feuille et l'enregistrement d'allocation feuille. Et puis c'est incohérent parce que la gestion des congés ou désolé, demandes de congé n'ont pas vraiment cela. Nous allons donc corriger certaines de ces incohérences, en plus de réduire les répétitions entre elles. Donc, je vais commencer par les types de feuilles. Donc, je vais juste aller au projet, cliquez sur Ajouter une nouvelle classe. On l'appelle le type de feuille. Et je vais rendre ce forum public Non, à l'intérieur du type feuille, ce que nous allons avoir nos champs pour ID, nom, jours par défaut, et ils ont chacun créé. Maintenant, j'ai spécifié que le champ de date, comme la date créée est vraiment un champ d'audit et cela doit être un téléphone à travers les différentes classes. Donc, je vais juste aller de l'avant et ajouter toutes les classes d'entités afin que vous puissiez faire une pause, répliquer cela. Pour la demande de congé, nous allons avoir un champ ID, début et dates de fin, type feuille. Les données demandées, requêtes, commentaires, date, axon, et approuvées sous la forme d'un booléen nullable, et annulées sous la forme d'un booléen. Donc, vous pouvez aller de l'avant et répliquer ça. Non, si vous comparez cela avec ce qui est sur la référence GitHub, il y a quelques champs manquants, lesquels nous ne sommes pas tout à fait prêts pour l'instant sous la forme de l'employé, ce qui serait des données liées à l'utilisateur. Nous n'avons pas encore cela, donc nous n'accordons pas la priorité à ce que nous puissions introduire cela plus tard par le biais de certaines migrations. Sachez que la troisième entité que nous allons ajouter est l'allocation des congés. Et pour celui-ci, nous allons avoir l'ID, le nombre de jours, la date de création, le type de congé, ID de type feuille et la période. Encore une fois, j'ai en quelque sorte omis les champs liés aux employés aussi. Ces annotations de données. Maintenant, en termes de répétition des champs par rapport à la nécessité d' avoir une cohérence avec au moins le visa doit être répété, à savoir la date de création. Habituellement, lorsque nous parlons d'audit, nous voulons avoir la date de création, qui l'a créée, la date de modification, et qui l' a modifiée pour la dernière fois, n'est-ce pas ? De cette façon, nous pouvons garder une trace de tout ce qui se passe à travers elle comme presque tous baisés. Nous résoudrions en fait certaines choses avec tout le référencement à l'employé et ainsi de suite avec ces sentiments de vérification. Donc, ce que je vais faire est d'introduire un autre dossier dans ce projet de domaine. Et je vais appeler ce dossier commun. Et puis à l'intérieur de commun, j'aurai une classe que je vais appeler cette entité de domaine. Personne ne sait que mon entité de domaine de base a, eh bien, il est bon d'avoir tous les champs de base que je connais chaque classe ou chaque entité de domaine va avoir besoin. Je vais en faire une classe abstraite afin qu'elle ne puisse pas être instanciée seule. Cependant, il peut être hérité par tout le monde. Donc, cela va être ID parce que chaque table va avoir besoin d'un ID. Je vais également avoir pour d'autres champs, un pour la date créée, puis créé d'ici là une date et heure pour les données de dernière modification et un autre pour la dernière modification par. Maintenant, avec cette entité de domaine de base, je peux savoir que tout le monde hérite. Je peux juste revenir à ma classe d'entité réelle et la laisser hériter de l'entité de domaine de base, y compris toutes les références manquantes en utilisant le point de contrôle. Et là, vous voyez que ces champs que j'ai l' allocation de congé INSEAD qui ont les mêmes noms que ceux dans basés sur une entité sont allumés. Ça veut dire que je n'ai pas besoin de les répéter. D' accord. Ça a l'air un peu plus propre. Bon, donc je vais laisser des demandes que je fais de même. Allez-y et héritez inclure les références manquantes et puis tout d'un coup je n'ai pas besoin de voir l'ID ici non plus. Et puis dans le type de feuille, je fais juste la même chose, y compris les références manquantes. Et puis je peux supprimer tous les champs répétés. Donc sont basés sur une entité nous donne accès à certains champs qui sont censés répéter à travers chaque entité que nous voulons tous qu'ils aient ces. D' accord. Donc, avec tous ces changements apportés, allons de l'avant et appuyez sur Control Shift et B pour faire une construction et nous avons une construction réussie. Nous pouvons donc passer à la prochaine tâche. 6. Créer le projet d'application: Salut les gars, bienvenue. Dans cette leçon, nous discuterons de notre couche de base d'application. Maintenant, le but de cette couche est de s'asseoir entre notre application, l' application étant tout ce qui voudrait accéder à la base de données et à la base de données. Donc, dans cette couche sera définir tous ces paramètres d'accès pour médier entre l'application appelante et la base de données elle-même. Donc, ce projet sera placé directement à l'intérieur de notre dossier principal. Alors allons de l'avant et ajoutons une nouvelle bibliothèque de classes. Et je voulais appeler ceci points RH, laisser l'application point de gestion. Allez-y et ajoutez-le encore une fois, nous utilisons dotnet juste en dessous de 2.1 et allez-y et créez. Donc maintenant que nous avons notre bibliothèque de classes, je vais supprimer la classe par défaut, puis je vais ajouter deux nouveaux dossiers à ce projet. Donc le premier sera la persistance et ensuite les systèmes de chiffrement, nous allons avoir un autre dossier appelé contrats. Donc, à l'intérieur des contrats, nous allons définir toutes les obstructions pour nos dépôts. Maintenant, le jury est sur les meilleures façons de mettre en œuvre cela. Encore une fois, il ya quelques opinions est l'architecture proposée, et il ya quelques opinions et quelques opinions sont mises en œuvre en fonction du contexte. Mais je vais juste expliquer pourquoi nous utilisons le modèle de dépôt. Donc, dans le, en accord avec les principes secs, nous ne voulons pas répéter trop souvent les requêtes. En outre, vous pouvez avoir des opérations spécialisées que vous devez effectuer sur l'un de ces objets de domaine. Donc, lorsque vous définissez un référentiel par objet de domaine, vous pouvez avoir des guillemets personnalisés ou des méthodes personnalisées à l'intérieur de ce référentiel pour ceux-ci, n'est-ce pas ? Non, nous n'implémentons pas le référentiel, mais nous définissons simplement le contrat. Donc, le contrat ici, le premier sera une interface et je vais l'appeler référentiel générique ij. J' ai dit cours ici, faire un cours. Mais même si vous faites preuve de prudence que vous pouvez simplement en faire une interface publique. Maintenant, nous allons dire à cette interface qu'elle sera implémentée par rapport à une classe appelée T. Donc, nous utilisons juste génériques en accord avec le dépôt générique de nom afin que n'importe lequel de nos objets de domaine puisse être utilisé pour accéder aux fonctionnalités liées à la base de données via cette interface. Donc, certaines des méthodes que nous allons implémenter dans cette interface incluent une getMethod, donc nous avons la tâche T. Et puis vous pouvez simplement aller de l'avant et inclure toutes les bibliothèques manquantes. Nous allons aussi avoir une tâche, obtenir tout ce que celui-ci revient. Je ne lis que des listes, savoir si c'est la première fois que vous voyez ce type de données. Habituellement, et personnellement, j'utilise généralement une liste ou un nihilist ou l'un de ces types de données Collection les plus populaires que j'ai lus sur une liste. C' est l'avantage qu'il le garde dans un état en lecture seule afin qu'il ne puisse pas être modifié une fois qu'il a été extrait des mésons de données envoyés. Donc moins de camionnage et moins d'opérations liées à la base de données après le pool de données. Donc, nous allons le regarder dans quelques-uns, mais c'est le type de données que j'utilise. Encore une fois, vous auriez facilement pu utiliser n'importe quel autre type de collection de type T aurait pu être une liste, aurait pu être une collection. Mais puis j'ai lu sur la liste sert le but que je voulais. Nous allons avoir la tâche d'ajouter sur où aussi Linda ont des tâches à mettre à jour et à supprimer. Donc, vous voyez que les référentiels génériques non seulement pour t, mais c'est aussi un générique en termes de fonctionnalité fournit qui sont les fonctions brutes de base et standard. Il y a aussi une convention de nommage où les gens mettraient le mot asynchrone parce que vous pouvez voir où tout en utilisant des tâches ici. Donc, certaines fois, vous verrez alors le définir comme un évier. Il est donc évident que ce sera une fonction asynchrone. Donc tu ne pourrais pas suivre cette convention de nom si tu veux. Je ne vais pas le faire, pour que nous puissions aller de l'avant. Maintenant, la chose avec le référentiel générique est qu'une fois de plus, c'est juste les fonctions brutes génériques que chaque table de base de données peut avoir besoin d'effectuer. Cependant, lorsque vous avez quelque chose de spécifique à quitter l'opération d' allocation ou une opération de demande de congé, vous ne pouvez pas construire le sel et le code peut devenir missy si vous essayez de le construire dans certaines parties de l'application. Donc, ce que nous allons faire est dans des référentiels spécifiques à des commentaires basés sur notre référentiel générique ou pour étendre notre fonctionnalité générique, mais spécifique à l'un de nos objets de domaine. Donc, je vais juste revenir aux contrats et je vais ajouter un nouvel élément sous la forme d'une classe une fois de plus, mais ce sera vraiment une interface et je vais l'appeler, je quitte le dépôt de requête. Une fois cela créé, nous en faisons une interface publique. Et puis je lui ai fait savoir qu'il étend le dépôt générique et il est spécifique à notre type de demande de congé de classe. Très bien, donc la demande de congé est notre domaine. Rappelez-vous que c'était relatif au type t. Donc c'est le T que nous passons, mais vous verrez ici qu'il ne sait rien sur dire 70. Nous devons donc ajouter une référence au domaine de gestion des ressources humaines. Donc, vous pouvez voir qu'en toute honnêteté, cela n'a pas tout à fait fonctionné pour moi quand j'utilise leur côté, juste passer aux dépendances. Laissez-moi le faire à nouveau, désolé, dépendances au projet ou chez un ami. Et puis je prends juste la référence aux objets de domaine. Cliquez sur OK. Et puis je peux savoir, inclure cette déclaration en utilisant ici. Très bien, donc à l'intérieur de ce dépôt, alors si nous avons des fonctions spécialisées relatives à seulement laisser les requêtes, alors nous pouvons les définir ici avec la modélisation du référentiel générique et sans les autres référentiels spécifiques en ayant besoin de le voir, nous voulons que tout soit contenu en un seul endroit. Donc, en suivant cet exemple, je vais juste aller de l'avant et défendre les autres dépôts. Je laisse l'allocation et je quitterai les dépôts de type. Donc, une fois que cette activité est terminée, nous finissons avec deux autres interfaces. Nous avons donc notre référentiel générique. Nous avons ou je quitte le référentiel d'allocation, qui est en train d'implémenter ou d'hériter ou autre référentiel générique I relatif à l'allocation de congé. Et puis nous avons encore cela pour le type de feuille avec je laisse dépôt de type étendant générique par rapport à laisser le type. Donc c'est vraiment ça pour cette leçon où ils tiennent les contrats. Et ces contrats sont dans les forums de ces interfaces. Parce que rappelez-vous que nous ne voulons pas interrompre directement avec le code lorsque nous appelons ce que nous allons traiter avec les abstractions de cette façon, nous pouvons faire des changements de code sans perturber trop la citation du client - application latérale. 7. Mise en œuvre Implementing: Salut les gars, bienvenue. Dans cette leçon, nous allons être assis mappeur automatique. Sachez que si vous ne savez pas ce qu'est la tige d'automne, ce n'est pas un problème. C' est vraiment juste une bibliothèque qui nous aide à convertir entre un type de données à un autre. Plus simple, non ? Donc, le contexte derrière pourquoi il sera utile est que nous allons implémenter le modèle de médiateur dans une vidéo suivante. Mais ce médiateur ou modèle agira comme un mécanisme de messagerie entre ce qui vient de l'usine et ce qui doit aller à la base de données. Il est, en général, mauvaise pratique d'interagir directement avec les objets du domaine, au moins avant d'arriver au dépôt. Cela signifie que nous ne devrions pas permettre à toute application appelant et au client, toute application qui parle à notre application sur le noyau de nous envoyer directement ou directement des objets hors du type d'objet de domaine. Au lieu de cela, nous créons une obstruction. Nous créons donc des objets de transfert de données ou des modèles de vue. Vous pouvez les appeler l'un ou l'autre, mais ce sont vraiment juste des croisements qui ressemblent à l'objet de domaine, mais ont des restrictions basées sur l'opération. Donc, l'opération d'édition a des exigences différentes de peut-être une opération de création. Et donc vous présenteriez l'id 1 et id ne serait pas présenté dans l'autre. Encore une fois, tout ce que vous avez, ce sont des obstacles pour cela. Vous pouvez obtenir granulaire ou vous pouvez le garder général. C' est à vous de voir. Le point est alter mapper aidera à la conversion entre la obstruée ou conviviale de cet objet et la version conviviale de base de données de cet objet. Cela va favoriser le couplage lâche tout au long de notre application. Donc, avec tout ce qui dit, la configuration ne va pas être très compliquée pour celle-ci, ce que je vais faire à l'intérieur de ce projet d'application est créer un nouveau dossier et nous allons juste l'appeler des profils cependant. Profile est fondamentalement juste un fichier de configuration pour tunnel automobile qu'il est autorisé à convertir entre un type de données à un autre. Donc je vais créer une nouvelle robe à l'intérieur de ce dossier. Et je vais appeler ça le profil cartographique. Et puis je dois vous présenter et je vais le rendre public bien sûr, mais je dois aller à NuGet et chercher notre bibliothèque de mappeurs d'autel. Donc je vais juste faire un clic droit sur l'argent. Tu peux avoir la bibliothèque ? Et puis je vais chercher l'auteur ultime. Et celui qui m'intéresse est l'ultime extension Bardot pour l'injection de dépendance. Nous viendrons avec toutes les dépendances, y compris la bibliothèque PR ultime de base et tout ce nécessaire afin qu'il puisse être utilisé pour l'injection de dépendance en conséquence. Donc je vais juste aller de l'avant et installer celui-là. Bien sûr, accepter et autoriser tous les problèmes qui surviennent une fois qu'il est installé. Au lieu de mapper le profil, je vais le laisser hériter d'une classe appelée profil. Et cette classe est appelée dans Auto Mapper Library. D' accord, donc on a la configuration du profil. C' est bien. Eh bien, la prochaine chose que je vais définir serait mes objets de transfert de données. J' ai donc créé un nouveau dossier à l'intérieur de ce projet d'application. Et dans ce dossier, j'ai quelques fichiers. Un, j'ai un fichier commun ou un dossier autre avec un fichier commun appelé détail de base. Donc similaire à haul et nous sommes assis à bord des objets de domaine, nous avons un commun et puis où l'entité de domaine de base, qui avait des propriétés de base qui devraient être sur tous ces objets de domaine. C' est de la même façon que je viens de faire des détails basés. Et la propriété commune serait ID. Je n'ai pas besoin de la date créée et ainsi de suite avec les DTL, c'est juste pour l'audit, donc c'est en arrière-plan. Donc, ce que j'ai vraiment besoin de partager entre eux serait l'identité. Et puis à l'intérieur de chacun de ces, que je n'ai pas encore fait, j'aurai alors d'autres propriétés que je sais que chacun d'eux doit avoir pour réussir à circuler des informations utiles pour moi. Donc, cette partie est aussi facile que d'aller quitter le type et de prendre les propriétés que vous connaissez, vous voudriez permettre à votre application ou à vos utilisateurs de pouvoir l'interrompre. Donc, cela laisserait des demandes. Ce sont toutes les propriétés obligatoires. Je suis juste littéralement, comme vous le voyez, je suis juste en train de copier et coller la partie difficile était vraiment juste de définir les détails de base et de laisser l'héritage mettre sur ces identifiants et pas les détails, parler aux détails. Donc, vous voyez ici que le type de feuille est conservé. Vous voyez que le type de feuille est en cours de conservation. Vous ne laissez pas le DTO connaître le domaine. Très bien, donc cela devrait être de type feuille DTO, et cela devrait également croire que DTO, et en règle générale, détaille les vitesses et les DTL. Automne savoir supérieur est ce qui permettra la conversion entre l'un ou le DTO et le domaine. Donc, au lieu de cartographier le profil, nous allons avoir un constructeur. Ainsi, vous pouvez simplement enregistrer la baignoire CTO, baignoire qui génère notre constructeur. Et puis je vais avoir une ligne qui indique Créer une carte. Et créer peut être dire entre une source et une destination. Donc T source serait, disons juste que la demande de congé serait ma source. C' est l'objet domaine. laisser la demande, DTO, et ce serait mon objet de transfert de données. Très bien, donc nous créons une configuration de mappage entre la demande de congé et le DTO de demande et fermons juste avec les parenthèses. Et puis je peux étendre cela à nouveau et lui dire qu'il peut inverser MOP. Et le PR ultime est variable car j'ai vu des applications où les gens mettent une certaine quantité de logique métier en automne en haut lui-même lorsque vous travaillez avec applications complexes et probablement inter-domaines, vous voulez probablement un domaine ou un détail pour pouvoir convertir en objets de domaine sur un ensemble et en objets de domaine sur un autre. Vous pouvez donc avoir plusieurs configurations de mappage d'un objet à un autre. Vous pouvez également créer des convertisseurs personnalisés pour voir ce membre va directement dans ce membre correspondant de l'autre côté, il y a un certain nombre de choses que vous pouvez faire avec cela. Cela pourrait être tout un cours en soi. Mais aujourd'hui, nous allons simplement rester simple avec nos exigences de configuration simples. Donc, nous avons laissé un endroit et ensuite nous avons le DTO correspondant. Et puis finalement, nous avons le type de feuille. Maintenant, je tiens à signaler quelque chose qui a fait allusion tout à l'heure, mais je tiens à le mentionner encore une fois. Il y a des moments où vous voulez obtenir un peu plus granulaire ou avoir des détails spécifiques à un certain but. Alors regardons les demandes de congé. Laisser le détail des demandes a un certain nombre de champs. Le but d'un DTO est de limiter le nombre de champs. Donc, réduisez la surpublication et sont en cours d' affichage ou de fournir trop d'informations à l'utilisateur. Donc, ce que j'essaie de voir, c'est que dans le cas où vous voulez voir une demande de congé , toutes ces données deviennent pertinentes. Mais dans le cas où vous avez vraiment besoin de la lister ou afficher une liste de toutes les demandes de congé. Vous n'avez probablement pas besoin de toutes ces données que l'utilisateur n'a pas besoin de voir toutes ces données lorsqu'il demande seulement la liste. Ils n'auront certainement pas besoin de voir les commentaires à ce stade. Ils n'ont probablement pas besoin de voir l'action de date approuvée ou annulée lorsqu'ils sont en vente. Donc, dans ce cas, ce qui a tendance à se produire, c'est que vous voulez probablement le sortir un peu plus. Donc, parfois, vous vous retrouverez avec un dossier à l'intérieur des détails. Et ce dossier serait spécifique à peut-être laisser la demande. Et puis à l'intérieur des demandes de congé, vous avez tous les détails qui diffèrent. droite. Donc ouais, laissez les détails de la demande. C'est très bien. Celui-ci serait pour les détails ce que bien, peut-être que j'ai un autre détail spécifique à la liste. Donc, vous auriez la liste des requêtes D2, qui oui, il aurait aussi le BSD TO. Mais alors il a beaucoup moins de propriétés en elle. Donc, vous avez probablement juste besoin de taper feuille la date à laquelle elle a été demandée et si elle n'a pas été approuvée ou non. D' accord. Donc, encore une fois, tout est relatif à ce que vous pensez avoir besoin de fournir. Mais je vois juste que dans cette situation, vous ne voulez probablement pas mettre chaque chose dans un détail et ensuite toujours utiliser ce détail chaque fois qu'une demande est faite, peu importe à quel point leur demande est minuscule ou le peu de données dont il a vraiment besoin dans cette situation. C' est donc le but du DTO. Donc, en fait, avec ces changements, je ne sais pas, j'ai cassé du code. Tout d'abord, permettez-moi de mettre à jour l'espace de noms sur ce détail des demandes de congé. Donc c'est qu'il sait que c'est un nouvel emplacement et puis je dois mettre à jour ma cartographie pour savoir qu'il a des demandes de congé, liste, DTO, déchiré un bateau aussi. Alors allez-y et mettez-les à jour. Et puis faisons une construction ou je construis un succès. La dernière chose que nous allons faire ici est la configuration de la méthode d'enregistrement de la collecte de services IA. Donc, le but de ceci est, eh bien, en accord avec l'injection de dépendance, nous voulons être en mesure d'avoir tous nos composants, tous nos composants injectables définis au lieu du niveau d'application. Mais alors n'importe quelle application cliente peut aller de l'avant et simplement appeler la méthode et la faire enregistrer en elle-même. Quand on sera là, tu le verras, mais je ferai ça correctement ? Et aussi ce serait des applications, des services, l'enregistrement. Donc, cela va être une classe statique publique et il va avoir une méthode que je vais appeler public static void Configure Application Services, qui prend un paramètre de collection de services AI. Donc, nous pouvons simplement aller de l'avant et inclure les références manquantes. Et puis à l'intérieur de cela, nous obtenons à voir les services dot add, auto, mapper. Ou je dirais que si vous êtes familier avec dotnet Core et l'injection de dépendance, vous verrez que c'est juste un service appelé action que vous auriez vu dans le fichier de démarrage pour n'importe quelle application dotnet Core. Donc, le fait est que nous l'abstrayons pour juste ce projet de sorte que lorsque nous avons cette application dotnet Core, nous pouvons simplement appeler cette méthode. Et puis il allait de l'avant et enregistrer chaque service qui est défini à l'intérieur de cette méthode. Donc, nous ajoutons le mappeur automatique et puis je vais dire point d' assemblage, obtenir l'assemblage en cours d'exécution. Allez-y et ajoutez les références manquantes. Maintenant, si vous êtes familier avec automatique ou que vous avez travaillé avec elle avant, mais que vous n'êtes pas nécessairement familier avec cela. Vous seriez probablement plus familier avec voir quelque chose comme le type d' un alors trouverait le profil de cartographie et alors cela nous permettrait d'enregistrer ce profil a la configuration supérieure d'automne en général. La chose avec ceci est que pour chaque profil de mappage que vous avez, vous devez probablement répéter cette ligne. Et vous, en fonction de la taille de votre application, vous pouvez vous retrouver avec plusieurs profils de mappage parce que j'ai vu où vous pouvez avoir des profils de mappage par objet de domaine et pr, pr appairage d'objet de domaine de détail basé sur le nombre de bases de données sont des domaines qui sont présents, n'est-ce pas ? Ainsi, vous êtes même au niveau de l'application, une application ou une application cliente peut avoir exigences de mappage différentes d'une autre, de sorte que vous les gardez séparés. Donc, mon point est qu'en disant que le point d'assemblage obtient l'assemblage d'exécution, il va juste traverser pour chaque profil de mappage qui a cet héritage à peu près et cela fonctionnera juste. Très bien, pas de moyen plus facile de le voir. est ainsi que nous enregistrons notre supérieur d'automne dans notre injection de dépendance. Et c'est la mise en place d'un mappeur d'automne en général. Donc, si nous construisons et qu'il est réussi, alors nous revenons ensuite et continuons notre configuration d'application. 8. Créer des requêtes avec MediatR: Bienvenue les gars. Dans cette leçon, nous allons implémenter deux modèles qui nous aident à promouvoir le couplage lâche à travers notre application. Il s'agit du modèle médiateur et du modèle C QRS. Sachez que le motif médiateur est considéré comme un modèle comportemental car il vous permet de définir exactement comment un ensemble d'objets interagissent les uns avec les autres. En termes plus simples, vous faites une demande et vous obtenez un résultat basé sur votre demande. Chaque fois que vous faites cette demande, vous pouvez vous attendre à ce type de résultat qui est une sorte de cohérence qu'il vous aide à mettre en œuvre. Il vous aide également à obstruer toute cette logique associée à cette requête de l'application appelante. Maintenant, pour voir le modèle QRS et voir QRS est abrégé pour commande et Query Responsibility Ségrégation. Il vous aide à séparer les opérations de lecture et d'écriture de n'importe quel magasin de données. Donc, dans la commande name et query commande est tout ce qui va augmenter les données, toute opération d'écriture, toute opération de mise à jour. Et une requête est que je lise les données. Donc, vous pouvez toujours savoir que lorsque vous faites quelque chose qui va augmenter les données, c'est une commande. Si vous lisez des données, c'est une requête. Alors commençons. Nous allons passer au nouveau get d'abord, et nous allons prendre le paquet médiateur, ce qui est intéressant, écrit par la même personne qui nous a donné tout le mappeur. Et c'est Jimmy BullGuard. Donc, nous allons aller de l'avant et installer ça. Et une fois que cela sera fait, nous reviendrons à notre méthode de configuration des services d'application et nous allons apporter quelques modifications ici. Donc certains d'entre eux étaient des oublis de ma part au départ, et je m'excuse. Donc, nous changeons ça d'une voix à un service IA appelé électron, c'est un. Et puis nous ajoutons ces deux lignes. Nous voyons des services dot add mediator, assembly, dot gif exécution assembly, juste laisser le mapper automatique et nous retournons des services. Donc, pour le terme immédiat ADD, il suffit d'aller de l'avant et d'inclure les références manquantes. Et on y va. C' est donc à quoi cette méthode d'enregistrement de service ou de collecte de services IA devrait ressembler. Maintenant que nous avons fait cette partie, revenons en arrière et nous recueillons nos pensées et réfléchissons ce que nous devons faire, nous devons mettre en œuvre les modèles PQRS. Donc, le CQ sont des taches sont, et une fois de plus sépare les commandes des carrières. En d'autres termes, nous avons besoin d'un dossier pour les commandes, nous avons besoin d'un dossier pour nos requêtes. Soit la commande ou la requête sera gérée par ce que nous appelons un gestionnaire. Donc, lorsque vous faites une requête, elle est gérée et le gestionnaire sera soit une commande pour augmenter les données, soit quelque chose à renvoyer des données. Donc, vous voyez qu'il y a beaucoup de pièces mobiles à ce stade. Et c'est pourquoi cela peut avoir autant d'opinions sur la façon dont il est mis en œuvre. Donc, une fois de plus, je ne prescrit pas une méthode d'implémentation ou une structure de dossiers, mais je vous aide juste à le visualiser. Vous pouvez le modifier en fonction de vos besoins. Mais c'est le monde entier est allé l'aborder tellement qu'il crée un nouveau dossier à l'intérieur de ou projet d'obligation, je l'appelle fonctionnalités. Et puis à l'intérieur des fonctionnalités, nous allons avoir des dossiers par type de domaine. Et la raison pour laquelle je dis type de domaine est que la fonctionnalité de l'application est relative à ce que vous allez faire contre notre objet de domaine contre les actes de ceux-ci, n'est-ce pas ? Donc, je vais le faire en morceaux basés sur la table ou les tables caractéristiques spécifiques que l'application offre. Commençons donc par un simple type de congé. À l'intérieur des fonctionnalités, nous allons avoir le type de congé. Je vais juste réaliser ce type de feuilles. Et puis à l'intérieur du dossier types de feuilles, je vais avoir quelques autres dossiers. Je vais avoir des gestionnaires de requêtes, puis à l'intérieur des gestionnaires sur quand avoir des commandes et des requêtes. Et c'est la structure de dossiers avec laquelle je vais travailler. Maintenant, comme je l'ai dit, les opinions divergent en attente. Une structure polaire pourrait sembler. Certaines implémentations auraient en fait le niveau supérieur pour le mannequin dans le nom de la fonctionnalité. Et puis ils auraient des commandes et des requêtes. Et puis à l'intérieur des commandes ou des requêtes, il y a où ils auraient toutes les requêtes ou auraient un dossier, désolé, par requête, disons à l'intérieur de la requête, ils auraient un dossier pour la requête spécifique, disons obtenir le type feuille ce sera la requête. Donc, à l'intérieur de cela, vous avez la bonne demande de type feuille, obtenez le type de feuille RequestHandler et le BTO spécifique à celui-ci. Donc, une fois de plus, il y a plusieurs façons que vous pouvez voir cela implémenté, mais les concepts restent les mêmes. Vous voulez juste vous assurer que vous pouvez identifier les commandes différemment de vos requêtes et que vous savez où sont vos demandes. Les demandes sont relatives à un 100. Alors maintenant que nous avons la structure des dossiers en place, commençons avec un peu de codage. Donc, à l'intérieur des requêtes, la première requête que je veux est d'obtenir la liste de type feuille. Donc, en nommant la convention sage, vous voulez toujours impliquer à quoi sert la demande ou quel genre de demandes dans le nein, n'est-ce pas ? Donc, obtenez la liste de types de congé et je vais spécifier des demandes. D' accord. Donc obtenir la demande de liste de type feuille. Et c'est une classe publique et il va hériter des requêtes d'E/S. C' est donc la courtoisie du médiateur, et il va se demander à quoi cette demande devrait s'attendre en retour ? Donc, quand je demande en utilisant ce type de données, que dois-je récupérer ? Eh bien, vous ne devriez pas récupérer une feuille de liste de type DTO, car une fois de plus, objets de transfert de données R1 entreront et ce ne serait jamais les objets de domaine. C' est donc ce que nous demandons. Il peut y avoir des moments où vous pouvez avoir des paramètres qu'ils peuvent mettre dans des requêtes et ainsi de suite. Mais c'est très simple. Je ne vais pas entrer dans aucune de ces complications pour l'instant. C' est donc notre première demande. Ensuite, nous avons besoin de quelque chose pour traiter ce genre de demandes. Maintenant, il s'agit d'une requête GET qui lui fait une requête. Donc, à l'intérieur de la section du gestionnaire, je vais aller dans le dossier des requêtes et je vais dire ajouter une nouvelle classe et je vais appeler celui-ci les gestionnaires de requêtes. C' est donc ma convention de dénomination. J' ai donc une requête par un nom, puis j'ajoute juste le gestionnaire. Donc, nous allons aller de l'avant et l'ajouter en tant que classe publique, qui va hériter encore une fois du gestionnaire de requêtes, avec la permission du médiateur. Et puis je demande le gestionnaire dit, Ok, ce qui les demande idéalement largeur, donc sa requête est les requêtes GET. D' accord, donc c'est la convention de dénomination que j'aime utiliser. Et plus que cela, voyez-vous beaucoup cette convention de nommage parce que alors vous pouvez spécifiquement lier notre requête à un gestionnaire par cela de la même manière, un est la requête, autre est le gestionnaire de requête. Ainsi, vous pouvez aller de l'avant et inclure les références manquantes. Donc, il dit ce que demande que ma manipulation et ce que je dois m'attendre à revenir. Donc, le type de retour de la demande devrait être le type de retour. Vous avez été ici. Donc, il est prévu de retourner le type de congé DTO. Ce que j'ai répertorié hors du diabète de feuilles. Bon, maintenant que c'est fait, nous avons toujours notre ligne rouge. Cette ligne rouge est parce que nous avons besoin d'implémenter l'interface. Donc presque automatiquement, nous obtenons effectivement une méthode ici qui dit géré. Il obtient la requête en tant que paramètre. Et puis voici où nous écrivons tout le code à gérer chaque fois que cette requête arrive. Maintenant, avant de commencer à traiter toute demande ici, nous avons quelques dépendances. Premièrement, nous devons pouvoir parler à la base de données. Maintenant, nous n'avons rien mis en œuvre, mais nous avons nos contrats de persistance. Ce sont donc des contrats qui vont réellement parler à la base de données. Donc, nous n'interagissons toujours pas directement avec le domaine ici. Bon, donc je dois injecter les références manquantes. Donc, en utilisant S3 ou baignoire, baignoire, je vais obtenir le constructeur, puis je vais injecter et je laisse le dépôt de type. Donc, je vais juste aller de l'avant et ajouter des références manquantes. Et puis l'ayant tapé dans le constructeur, je peux savoir, dire créer et affecter un champ. Bon, on y va. Et j'ai tendance à utiliser le trait de soulignement parce que j'aime voir le trait de soulignement. Donc, je sais que c'est définitivement le domaine privé dans la classe, donc c'est ma convention de nommage. Vous n'avez pas nécessairement cause que vous voyez que le code généré automatiquement ne vous a pas donné de trait de soulignement, donc c'est bien. Maintenant, une autre chose que je voudrais injecter est que je mapper, parce que j'ai besoin de faire un mappage quand j'obtiens les données de la base de données, lorsque ce référentiel renvoie les objets de domaine, je dois les convertir en détails pour envoyer le Buck. Donc, j'ai besoin de constructeur automobile aussi, donc je suis supérieur, inclure des références manquantes aussi aller de l'avant et injecté ou crée NSA sur le terrain. Et on y va. Donc, nous avons tout injecté et prêt. Maintenant, pour implémenter ce code de gestionnaire, ce que je vais faire est d'exécuter une requête sur le référentiel de type feuille. Donc, je vais dire que var feuille fetch est égal à 08, laisser dépôt de thérapie point obtenir tout. C' est une attente. Cela signifie donc que cette méthode doit être asynchrone. Et puis vous verrez que la seule erreur disparaît au moins. Et puis ce que nous devons retourner est la liste de type feuille ETL. Donc, je vais dire retour mappeur dot map. Et puis c'est là que cela est utile dans les détails de type feuille, mais c'est une liste de type feuille D2 ou autre. Et ce que je mapperai dans ce sera la liste des objets de domaine provenant de la requête. Et voilà. Tout le monde est heureux. Donc jamais demander de dire que je veux les listes de types de feuilles, alors nous avons le gestionnaire disant, Ok, je peux gérer cette demande pour vous. est donc ce que nous entendons en définissant le comportement des applications ou en définissant la manière dont les objets se rapportent les uns aux autres. Cette demande sera toujours liée à ce chasseur. Je crois que si vous l'essayez, plusieurs gestionnaires pour les mêmes requêtes, vous rencontreriez effectivement des erreurs d'exécution à cause d'une certaine ambiguïté. est ainsi que nous arrivons à définir clairement que lorsque vous avez fait cette demande, vous pouvez toujours vous attendre au comportement. Maintenant, regardons une autre requête et ce sera toujours une requête. Mais cette fois, je veux une lance. Type de feuille. Donc, je disais que vous pouvez voir des demandes ou vous pouvez finir avoir des champs ou des propriétés à l'intérieur de ses demandes qui seront nécessaires pour gérer l'opération spécifique. Et si nous voulions obtenir le type elif, pas la liste entière, mais le détail du type feuille. Donc je vais créer une autre question. Et celui-ci va être bon. Laissez les demandes de détails de type. Encore une fois, n'oubliez pas de le rendre public. Maintenant, dans cette situation, je vais ajouter la propriété et je vais dire id. Donc, nous obtenons le détail ce qui signifie que nous voulons un enregistrement spécifique. Et la meilleure façon de spécifier un enregistrement est d'envoyer l'ID. Nous avons donc besoin d'un gestionnaire pour cette requête. Donc, je vais ajouter ce gestionnaire et l'autre classe ou obtenir les demandes de détail de type 100. On y va, le rendre public. Non, une étape que j'ai manquée à l'intérieur des demandes que j'avais besoin d'hériter de I demandes. Et il ne s'attend qu'un DTO de type feuille cette fois, n'est-ce pas ? Tant de demandes DTO, aller de l'avant et se rencontrer à toutes les références manquantes. On y va. Donc, le gestionnaire va maintenant hériter du gestionnaire de requête et aller de l'avant et ajouter des références manquantes. Il va traiter les demandes de bonnes demandes de détails de type de congé, et il est prévu de retourner ETL de type. Donc, une fois que toutes ces références manquantes ont disparu, allez-y et implémentez l'interface, puis nous commençons par cela. Maintenant, nous allons avoir besoin des mêmes injections que pour lesquelles nous avons dû utiliser. Je vais juste accélérer cela et copier et coller ce code et juste changer le nom du constructeur et aller de l'avant et ajouter toutes les références manquantes. Et une fois que vous avez fait tout cela, vous pouvez commencer sur le code spécifique. Donc, dans cette situation, je dirais que le type var leave est égal à et nous sommes avec l'appel de méthode. Donc, laissez point de dépôt obtenir et obtient son attente d'un ID. J' ai donc l'objet de requête ici à l'intérieur des méthodes gérées par le portail. Je peux maintenant dire demande point i e. Ok , encore une fois, où enseignons-nous ? Donc, cet espacement, mais je vous montre juste que c'est comme ça que vous utiliseriez ces champs dans votre requête, dans votre référentiel générique ou proche, désolé. Ainsi, lorsque vous avez des méthodes spécifiques définies à l'intérieur du référentiel de type feuille, vous pouvez avoir des champs plus spécifiques pour vos requêtes qui sont nécessaires pour gérer ces types d'opérations. Donc, une fois que nous avons obtenu cela, la prochaine chose que nous devons faire est de retourner les objets DTO de type feuille. Donc, je vais dire mappeur, mappé dans le détail de type feuille et nous mappons le type. Donc, une fois de plus, seulement les détails. Maintenant, une chose à noter est que dans les gestionnaires qui ont une séparation claire entre les commandes et les requêtes. Mais dans les demandes, il n'y a pas de séparation claire. Donc, lorsque les demandes commencent à être créées pour les commandes, nous devons compter sur nos yeux. On en a deux. Nous ne sommes pas fatigués pour ne pas être confus quant à la demande d'eau. Et je ne pense pas que ce soit, c'est très efficace. Donc, je vais avoir des commandes à l'intérieur de mes requêtes, et je vais aussi avoir des requêtes. Je sais donc que chaque fois que je veux des demandes, du chagrin et des demandes de renseignements, je sais exactement où aller. Et la même chose pour les commandes. Donc, comme je l'ai dit, ils diffèrent la structure des dossiers. Certaines personnes auraient encore une fois dit les types de congés. Et puis ils auraient eu les ordres. Et puis au lieu des commandes qui auraient les différentes commandes avec toutes les ressources nécessaires pour cette commande spécifique, le détail, le gestionnaire, la requête, le tout dans ce sous-dossier. Alors que vous cassez cette inodore que vous allez avoir besoin de plus de fichiers, plus de dossiers parce que vous voulez voir une séparation claire autant que possible. Une fois de plus, dit que cela est implémenté est relatif au créateur. Donc, je vais juste déplacer mes requêtes que j'ai créées jusqu'à présent dans ce dossier spécifique. Et bien sûr, après la mise à jour de cet espace de noms. Et une fois que je fais cela, je vais aller de l'avant et mettre à jour mes gestionnaires pour connaître le nouvel emplacement de leurs requêtes correspondantes. Donc, avec tout cela, aube, je vais faire une construction et construire a été couronnée de succès et vous voyez comment tout se passe ensemble. Donc, si vous le souhaitez, vous pouvez aller de l'avant et implémenter les autres fonctionnalités que nous avons commencé avec les types de feuilles. Vous pouvez au moins implémenter les opérations différentes, les deux lectures ou les deux lectures ou les deux requêtes relatives à l'allocation de congé et relatives à la demande de congé. 9. Finalisation des demandes pour MediatR: Bienvenue les gars qui continuent dans la même veine de mettre en place nos requêtes pour nos fonctionnalités supplémentaires. Donc, nous l'avons déjà fait pour les types de feuilles. Et l'affectation consistait à le faire pour les demandes de congés et les allocations de congés. Donc j'ai déjà fait ça et je vais juste te guider. Donc si vous ne l'avez pas terminé, j'irai assez lentement et vous expliquerai tout ce que je fais pour que vous puissiez le répliquer. Si ce n'est pas le cas, alors nous pouvons juste comparer les notes et n'hésitez pas à me faire savoir si vous avez fait quelque chose de différent de la façon dont je l'ai fait. Donc, le premier, Commençons par les allocations de congés. J' ai donc les requêtes et j'ai le, ce que j'ai les gestionnaires et les demandes, et j'ai les requêtes dans l'une ou l'autre. Maintenant, en suivant la norme jusqu'à présent, vous verrez que ou les quêtes ressemblent assez à ce qu'elles ressemblaient pour un type de feuille. Nous avons la demande détaillée d'allocation de congé, qui prend l'ID. Et j'en ai aussi un pour la liste. D' accord, donc dans la requête est, j'ai une petite surprise pour vous. Je ne sais pas si vous l'avez fait de cette façon, mais je vous expliquerai exactement ce qui a été fait différemment. Donc, bien sûr, nous incluons le bon bonjour, Le dépôt d'allocation de congé plutôt que le dépôt de type feuille parce que nous avons affaire à des emplacements Levi droit. Maintenant, en termes de gestion, vous verrez que j'ai ici une méthode que nous n'avons pas traversée dans notre, dans notre configuration de dépôt. J' ai l'allocation des congés avec des détails. Sachez le but de moi en spécifiant ceci est que lorsque nous obtenons les détails de l'allocation de feuille et si vous avez besoin d'un rappel ou d' allocation de congé a effectivement une propriété de navigation de type feuille, ce qui signifie que si je voulais montrer Quel congé a, quel nombre de b après, montrer le nom de cette icône de feuille, montrer l'ID qui est inutile, n'est-ce pas ? Ou le client ou un autre contrôle de l'identifiant, ils auraient besoin d'une certaine quantité de détails du type de feuille de leur côté. Donc, quand je dis avec des détails, le but de cette méthode est de faire inclure cette propriété de navigation et tout de sorte qu'au moment où je reçois mais que l'allocation de congé, j'aurais toute cette logique ne sont prêts et tout ce que j'ai à faire est de cartographier et de revenir. Donc, à ce stade, je vais juste faire une pause et 0 que vous verrez modèle de conception parfois où ils font réellement toute cette logique complexe ici dans le gestionnaire. J' ai donc vu où ils se connecteraient directement au contexte ici dans le gestionnaire. Et puis faites toutes ces requêtes brutes ici dans le gestionnaire massages, puis retournez enfin ce dont ils ont besoin pour revenir. Donc, c'est un motif de conception que vous pourriez voir. Et l'autre est l'endroit où nous abstraction de toutes ces logiques et de ces requêtes complexes et de la logique métier. Et puis mythos pour le dépôt. Non, je ne dis pas que l'un est meilleur que l'autre parce que j' avais l'approche a ses avantages ou ses inconvénients en termes de fabrication de méthodes qui traitent spécifiquement d'un scénario comme obtenir l'allocation de feuille avec les détails. En termes de cela, il pourrait être bon de le mettre dans notre dépôt, une méthode où vous avez une référence directe à l'endroit où ce type d'opération de retour d'art logique se produit parce que vous devrez peut-être réutiliser ce même type de logique dans plusieurs gestionnaires. Donc, cela réduirait réellement la répétition des mêmes types de requêtes et des mêmes types d'inclusions et tout sur plusieurs gestionnaires. Si vous l'avez juste dans un espace de dépôt. L' inconvénient pour les dépôts, cependant, est-ce que c'est à cause de la façon dont les choses spécifiques peuvent obtenir ? Oui, nous avons les trucs génériques, mais évidemment ce n'est pas une commande générique que chaque fonctionnalité de notre domaine m'objet, utilisent de la même manière. Nous devons avoir une méthode spécifique et ensuite nous allons probablement finir dans un trou de lapin d'avoir beaucoup de méthodes spécifiques dans notre dépôt. Donc, c'est l'un des sites don't, le modèle de référentiel sait, comme je l'ai dit, si vous faites tout ici dans le gestionnaire, cela fonctionnerait. Mais encore une fois, les inconvénients de cela est que vous devrez peut-être répéter ce type d'opération sur plusieurs gestionnaires. Et puis vous finissez par répéter du code à plusieurs endroits. Et puis la modification pourrait devenir difficile à long terme. Donc c'est la surprise Alpha. Donc, si vous jetez un oeil à notre interface, vous verrez ici qui est en fait avoir à la fois pour la liste et pour l'individu. Maintenant, le jury ne veut pas savoir si vous avez besoin des deux. La raison pour laquelle j'ai inclus le 14 et la liste, bien sûr, est que dans la liste, les allocations de congé, Je veux montrer le nom du congé et le d, Le nom du congé et le nom du type de feuille morte et le dy. Donc, je devrais inclure les détails ici. Et puis, si vous visualisez l'un d'eux, vous voudriez voir les détails aussi. Donc je viens de faire ça et j'ai fait la même chose. Et quand vous travaillez avec beaucoup d'entre nous, vous devez naviguer rapidement. Donc, je vais juste utiliser cette flèche bleue en haut ici pour synchroniser magasin ce document est rapidement, puis laisser des demandes. Vous voyez que j'ai des méthodes similaires parce que dans les demandes de congé, nous devons savoir quel type de congé est demandé. Et si je regarde la liste, vous voudriez voir ce type de feuille a été demandé à cette date, et cetera. D' accord. Maintenant, en ce qui concerne nos demandes de congé, j'ai une autre surprise de diapositive et j'espère que vous l'avez déjà fait. Mais les requêtes sont à peu près les mêmes. Mais en termes de demandes plutôt, mais en termes de type de retour, vous remarqueriez que j'ai obtenu demande détaillée de demande de congé montrant les demandes de congé DTo, cependant, pour la liste et nous avons discuté pourquoi nous ferions séparer les détails plus tôt. Nous avons des détails de la liste des demandes de congé. Donc, la liste est de déterminer une liste des détails spécialisés pour la liste. Et puis les détails retournent le détail avec beaucoup plus de détails dedans. Pour les requêtes. Problèmes similaires pour la liste des demandes de congé, gestionnaire de demandes. Bien sûr, il retourne la liste des demandes de congé DTO. Et le gestionnaire ressemble à des mots assez similaires appelant un référentiel de requête de suppression et appelant les requêtes get leave avec des détails similitudes. Lorsque nous regardons le gestionnaire de détails, c'est la même chose sauf que nous retournons juste le détail des demandes de feuille, le laboratoire qui a mis en place cela, vous avez peut-être remarqué que vous obtenez beaucoup de lignes rouges lorsque vous 're types mal appariés. Et si vous aviez le mauvais type de données ici ou le mauvais type de demande référencé, tout se casserait. Donc c'est très, très strict. Si vous m'avez dit que la demande attend DTo de demande de type leave, vous ne pouvez pas mettre d'autre type de données ici dans ce gestionnaire que vous dites devrait traiter cette requête. D' accord, donc tu peux être très, très prudent à ce sujet. Et une fois que vous vous habituerez au modèle, ces choses viendront plus naturellement. Je ne peux attribuer que si c'est un peu frustrant au départ. Mais une fois de plus, vous avez le code à référencer afin que vous puissiez toujours faire une pause quand vous en avez besoin et répliquer ces bits de code dans votre application en conséquence. Maintenant, dans notre prochaine leçon, nous allons envisager la mise en place de notre première commande. Et la commande une fois de plus augmenterait les données dans la base de données. Nous allons donc regarder ce qu'il faut pour configurer, créer une commande pour l'un de nos objets de domaine. 10. Créer des commandes avec MediatR: Bienvenue les gars. Dans cette leçon, nous allons jeter un oeil à la configuration des commandes. Donc, les commandes augmentent encore une fois les données et nous allons commencer par ou créer la commande. Maintenant, si vous regardez mon Explorateur de solutions, vous remarquerez que j'ai quelques fichiers supplémentaires et que j'ai un dossier D2L restructuré. Laisse-moi juste effondrer tout le reste pour que tu puisses te concentrer sur cette section. Donc, dans les premières étapes de la planification de ce type d'architecture, vous allez toujours changer les choses parce qu'il est bon de l'obtenir directement de null par opposition à plus tard lorsque vous avez beaucoup de fichiers différents et plus, pour , les mises à jour lorsque vous déplacez, ces autres fichiers appartiennent. Donc, dans les premières étapes de la mise en place des détails, j'avais indiqué que vous voudriez probablement avoir un dossier pour les détails et ensuite avoir les différents types de détails dedans. Donc, nous avons fait cela avec les demandes où nous avions les demandes de congé D2 et supprimer les détails de la liste des demandes au lieu de laisser le dossier de demande. Donc, je viens d'étendre ce concept aux autres détails où j'ai un dossier d'allocation de congé et un dossier de type elif et nomme cette feuille ce détail profond. Laisse-moi juste corriger ça. Donc, à l'intérieur de ces dossiers, nous allons avoir les différents détails. Et encore une fois, il n'est pas absolument nécessaire qu'il ait plusieurs détails ou détails spécifiques à un but. Mais je vais vous montrer pourquoi il est bénéfique de le faire parfois. Donc, avec le type de feuille, le risque est faible. On a des détails sur les feuilles. Tout ce qu'il nécessite est un nom et le nombre de jours par défaut. Pour moi, c'est tout simplement suffisant. Ces données courent très peu de risque de surpasser notre sous-exposition quoi que ce soit pour l'une des opérations que nous pouvons créer facilement en utilisant ce détail, nous pouvons lister facilement et nous pouvons examiner les détails. C' est très simple. Cependant, en ce qui concerne les demandes de congé, nous avions discuté que les demandes de congé DTO contiennent beaucoup plus de détails. Dans un paramètre de liste, nous n'avons pas besoin de beaucoup de détails. Vous avez vraiment juste besoin des détails du type de feuille demandé, la date à laquelle elle a été demandée, et si elle est approuvée. Maintenant, dans le Create, nous n'avons plus besoin de demander au consommateur de fournir tous ces détails. Parce que si vous comparez créer des demandes de congé dentaire, nous n'avons vraiment pas besoin de l'option de date. Et quand quelqu'un crée une demande de congé, quand je demande un congé, il n'y a pas d'actions de date. Donc, cela n'a pas besoin d'être fourni. La date demandée qui peut être indiquée par nous, par le système. Nous n'avons pas besoin d'obtenir cela de l'utilisateur ou du consommateur. Date de début et de fin courte. Ce sont des éléments essentiels. Nous devons connaître le type de feuille. Nous n'avons pas besoin de connaître l'objet entier du type feuille. Nous avons seulement besoin de l'identifiant de celui qui est demandé. Et à ce moment-là, il n'est ni approuvé ni annulé. Donc, je peux avoir un détail spécifique et comme je parle, je vois que j'ai fusion supplémentaire cela, mais j'ai un créer des demandes de congé DTo, qui va avoir la date de début, la date de fin, l'identifiant de la feuille mourir en cours de demande. Et une fois de plus, le système peut voir la date demandée. Et je dois en faire un nullable. Je vais donc profiter de cette occasion pour ajuster ça. Donc, cela doit être nul, mais je n'ai pas besoin de l'expéditeur dans le Crée. Je prends tout ensemble, crée dans la demande de congé, je vais le rendre nul parce que règle de déduction signifie vraiment quand a-t-il été approuvé ou annulé. Droit ? Et puis de même, je vais juste le faire jusqu'au domaine. Encore une fois, il est bon de voir ces choses tôt et de les ajuster parce que nous avons encore créé la base de données, donc nous n'avons pas à nous soucier de cette extraction trop. D'accord ? C' est pourquoi j'ai un DTO spécifique pour créer la demande de congé, différent de la liste, différent des détails. Dans un autre, lorsque nous avons l'allocation de congé et la désaffectation a un certain nombre de ceux-ci, les détails du type de feuille qui est lié à elle, identificateur et la période. C' est similaire à la demande de congé. Je n'ai pas besoin des détails du type de feuille au type de moment de la création. Donc, lorsque nous parlons de surpublication, cela signifie que nous donnons à l'application cliente la possibilité de fournir trop de données. Et puis c'est là que le piratage et les mauvaises données et les personnes introduisant des anomalies dans votre base de données, c'est ainsi que cela se produit. C' est donc un bon moyen de restreindre ce qui peut arriver sur une opération. Alors sachez ça. Avoir une bonne compréhension de la raison pour laquelle nous avons plus de détails introduits. Jetons un coup d'oeil aux commandes. Donc, je vais commencer par la plus facile, qui est les commandes de type feuille. Je vais aller à la demande et je vais créer une nouvelle classe. Et ce Gaumont va être très spécifique créer une demande de type feuille. Donc, c'est la demande de créer un type de feuille et est allé de l'avant et de l'ajouter et en faire une classe publique. Et puis celui-ci hérite comme nous le savons de la demande. Et il reviendra, je vais le faire retourner un entier 0. Cet entier sera. Le nom ou désolé, l'ID de la valeur ou l'enregistrement a été créé. Très bien, alors vous créez, nous allons juste vous dire l'ID de ce que vous créez. Nous ne savons pas ce que le client peut avoir besoin de faire après la création, mais nous leur donnons, mais l'ID enregistré, il doit aller à la page de détails par la suite. C' est à eux de décider, mais nous vous disons que c'est réussi. Voici l'ID du nouvel enregistrement. Maintenant, dans la commande, ce que nous allons avoir, comme nous savons que mon null est notre gestionnaire correspondant pour cette requête. Donc, nous héritons de je demande gestionnaire. Et je demande le gestionnaire va implémenter la demande de type create leaf. Allez-y et incluez tout ce qui manque. Et il verra qu'il retourne un entier. Maintenant, lorsque nous implémentons l'interface, vous verrez que nous obtenons cette tâche renvoyant un entier et notre gestionnaire. Maintenant, revenons un peu à leurs demandes. Et il y a peu de modèles que vous pourriez voir dans la demande de création. Un modèle est que les gens écriraient réellement tous les champs que lorsque vous êtes sur le point de créer un enregistrement pour cette année, envoyant les demandes pour créer un enregistrement pour ce type. Ils mettraient dans les champs de la demande réelle pour voir ce sont les frais que vous êtes autorisé à envoyer avec la demande. Et puis à ce moment, cette demande sert essentiellement le but de mes détails que je viens de définir ici. Non, personnellement, je n'aime pas mélanger et assortir. Je n'aime pas avoir de détails ici, mais quand c'est je crée, j'ai les champs ici. Et puis, vous savez, je ne sais pas où aller et je dois changer ce qui se passe parfois je ne me souviens pas. Au lieu de cela, je garde tout à un niveau de détail et la demande est vraiment juste un mécanisme pour transférer les données. Donc, le DTO représente les données et la demande est juste ce transport. Avec tout cela dit, je vais présenter notre propriété dans cette demande de congé type DTO. Donc, cette propriété est ce que le consommateur va remplir avec la demande et l'envoyer. Donc, dans notre commande, nous savons que nous disons demander le diabète de feuilles de points, c'est là que se trouvent les données. Donc, bien sûr, si nous allons interagir avec les types de feuilles et le mappeur automatique, alors nous aurons besoin de nos suspects habituels dans notre constructeur pour être injectés. Et pour la vitesse à nouveau, ceux-ci retournent à l'un des gestionnaires existants et simplement copier-coller, changer le nom du constructeur. Et puis nous incluons simplement les références manquantes. D' accord, pour travailler plus intelligemment, pas plus dur. Maintenant que nous avons tous les outils dont nous avons besoin, comment configurer notre gestionnaire pour créer cet enregistrement ? Mais avant de passer à autre chose, je vais faire un léger ajustement. Donc un autre modèle que vous verrez, et je pense que je vais l'utiliser cette fois juste parce que c'est pour moi, c'est plus propre au lieu de demandes. Donc, quand nous avons affaire à des commandes, non, ce ne sera pas notre demande parce que je demande est quand vous demandez quelque chose, cette commande est quand vous dites quelque chose. Tu veux une commande. Donc, au lieu de nous en utilisant la requête dans le nom ici où nous disons créer la commande de type feuille. Très bien, Donc en renommant la source, je peux charger l'IntelliSense pour le renommer à travers le tableau, mais je vais renommer le fichier manuellement. Donc, nous avons créé des commandes de type feuille, donc nous savons avec certitude que celle-ci est une commande et c' évidemment que le gestionnaire est censé porter toute sa commande. Donc, Command Enter, ok, et mettre à jour toutes les autres références sont sur l'endroit. Donc je pense que c'est en fait plus propre et plus facile sur les yeux. C' est une distinction entre ce que je demande des classes sur ce que nos classes de commande résolvent pour notre opération. Ce que nous allons faire est de définir le type de feuille à être égal à. Et puis nous allons juste utiliser le mappeur automatique pour mapper dans les types de congé. Donc, nous mappons du détail à l'objet de domaine cette fois-ci le nôtre. Donc mappeur Dartmouth type feuille, entrelacés tapotez notre recherche à point de demande de type feuille BTO. D' accord, alors allez-y et incluez tout ce qui manque. On y va. Donc maintenant, nous disons que le type de congé est égal pour m'obtenir la version baladée de cela dans l'objet de domaine. Ensuite, nous effectuons notre, cela va dire que le type de congé est égal à et nos poids sur nous allons appeler notre dépôt de type feuille point ajouter des blocs de méthode, non ? Alors rappelez-vous qu'il renvoie réellement l'objet ou quelque chose du même type de données, n'est-ce pas ? Donc, laisser le type va maintenant être mis à jour parce qu'après Entity Framework, qui est ce que nous allons utiliser comme notre RM. Après avoir fait son opération va mettre à jour l'ID. Donc, nous retournons l'objet avec l'ID mis à jour et savons que nous avons cet ID. Nous pouvons dire retour, type de congé, ID de point. On y va. Alors sachez que cette commande a été gérée. Nolan, on le regarde, on voit que ce n'était pas si compliqué à faire. C' est juste trois lignes où obtenir la requête avec les données. Et puis nous allons le mapper dans les objets du domaine. Nous allons alors patrons ou dans un référentiel ou pour que l'opération se produise. Et puis nous retournons juste l'idée et c'est tout pour la commande create leaf type. Donc, vous pouvez juste faire une pause ici et lui demander de le faire avec les autres. Je vais le faire et ensuite on pourra comparer les notes. D' accord, donc j'ai sauté de l'avant et je suis allé de l'avant et j'ai implémenté les commandes qui créent des commandes pour les deux autres objets de domaine. Donc, si vous regardez attentivement, vous voyez que c'est à peu près la même citation à part les noms et les dépôts impliqués, c'est à peu près le même code. C' est donc le gestionnaire de commande d'allocation de laisser. Vous pouvez faire une pause, vous pouvez le répliquer si nécessaire. Mais c'est notre gestionnaire de création et notre quête de carrière. Il suffit de prendre cela créer le détail de l'allégation de congé au lieu du détail de l'allégation de congé. D' accord. De même pour la demande de congé, même code, même structure, non ? Et puis la commande, il suffit de prendre le détail des demandes de congé pour créer le détail de la demande. Donc, vous voyez que tous ces types de choses ressemblent très. Ainsi, vous pouvez aller de l'avant et répliquer ceux dans votre code. Et quand nous reviendrons, nous regarderons les autres commandes qui incluraient la mise à jour et la suppression. 11. Finir des commandes avec MediatR: Très bien les gars, bienvenue. Comme vous l'avez remarqué, mon écran est vide. Dans cette leçon, nous allons parler d'ajouter les gestionnaires de mise à jour et de suppression et tous les actifs qui les accompagnent. Donc mon écran est vide parce que j'ai ajouté beaucoup d'actifs et je vais les parcourir un par un avec vous et vous pouvez aller de l'avant et les répliquer. Mais je veux que nous comprenions les décisions que nous prenons à ce stade car il s'agit de décisions cruciales. Et ce genre d'architecture, les choses que vous y mettez, toutes basées sur la décision. Encore une fois, ils sont relatifs à ce sur quoi vous travaillez, votre équipe et à l'application globale sur ce que vous espérez accomplir. Alors commençons par regarder les détails. Où sont-ils ? parcouru les détails et nous les avons séparés par des dossiers afin que nous puissions voir tous les détails relatifs à un type de domaine assez facilement. Mais à ce stade, nous avions un VT0 pour le type de feuille, et nous avions dit que, d'accord, était à faible risque parce qu'il pouvait être utilisé pour de nombreuses opérations différentes. Je l'ai depuis divisé en deux. Et la raison en est que vous avez créé tab2 feuille différent du type feuille D2 et tous. Pourquoi ? Parce que le détail de type feuille hérite du détail de base et de base D2, rappelez-vous nous donne l'ID, connaître le risque de cela. Et une fois de plus, le but du détail est de réduire ce que nous appellerons sur l'affichage. Si je crée un type de feuille, je n'ai pas besoin d'un ID. Je ne veux pas donner au consommateur la possibilité de fournir une pièce d'identité parce que cela donnerait juste des problèmes. Je leur donne exactement ce dont ils ont besoin pour traverser leur opération. J' ai donc créé un nouveau détail pour le type de feuille où ils n'obtiennent que le nom et les actes par défaut. Ils ne peuvent pas fournir de champ ID. détail du type de feuille peut être utilisé pour tout le reste, pour l'édition , pour l'affichage parce que bien, il a ces champs ainsi que BCE, qui est l'ID. Maintenant, comme vous pouvez finir par obtenir de plus en plus de détails et que vous avez l'impression de répéter à travers les différents détails, alors vous pouvez envisager d'avoir un dossier commun à l'intérieur de ce sous-dossier déjà pour définir cette propriété est que ce détail doit avoir de toute façon. Donc, tout tab2 feuille qui viendra avec la plupart des hafnium et il doit avoir des jours par défaut. Vous pouvez définir une classe de base si vous en avez besoin. Bon, maintenant nous pouvons passer à l'allocation des congés, avoir trois détails sur l'allocation des congés à ce stade, et je vais signaler une erreur que j'ai commise dans l'un d'eux. Cette erreur a été d'avoir créé des détails d'allocation de congé héritant de ce détail. Très bien, donc tu dois faire attention à ces choses si nous essayons d'être stricts. C' était donc une erreur de ma part. Créer des détails d'allocation de congé une fois de plus devrait avoir absolument aucune référence à une clé primaire quelle qu'elle soit. Mais alors nous avons besoin des autres champs. Cependant, les mises à jour doivent avoir accès au DTO de base pour nos besoins de mise à jour. Maintenant, il se peut que nous disions, ok, eh bien, encore une fois, créer ce détail de base dont tout le monde hérite. Ou nous pourrions simplement mordre la puce et dire que nous allons utiliser 14 créer ou mettre à jour si l'ID est fourni et nous savons que c' une mise à jour si elle n'est pas empêchée et nous supposons que je crée, ceux-ci pourraient facilement être des arguments que je ne vois pas, Non, je ne vois pas oui. Cela dépend de la granularité que vous voulez obtenir et ce sont vos décisions à prendre en fonction de votre contexte. Je ne fais que souligner les différences et les risques en conséquence. Donc je vais les briser comme ça. Non Pour la demande de congé passe par un autre niveau. Donc, nous avons le détail de la demande de congé où familier avec cela. Nous avons le détail de la liste qui a déjà établi pourquoi c'est différent. Nous avons le Create qui est encore une fois incorrectement, au moins dans mon contexte héritant de cela, que je vais caractériser null. Et puis je dois avoir mis à jour le détail de la demande différent des détails d'approbation de la demande de congé modifié ? Non, tu vas demander. D' accord. Alors pourquoi avoir les deux ? Parce que les deux parlent d'augmenter les données. D' accord. Eh bien, encore une fois, c'est une question d'hôte trompé que vous voulez être donc la mise à jour sert à permettre à l'utilisateur ou au consommateur de permettre à l'utilisateur final de mettre à jour ses demandes. Ils voulaient peut-être changer les dates de début ou la fin, peut-être qu' ils ont choisi des vacances quand cela aurait dû choisir malade. Peut-être qu'ils veulent mettre de nouveaux commentaires ou qu'ils veulent simplement l'annuler. Donc, je leur donne exactement ce qu'ils peuvent faire en utilisant ce DTO s'ils envoient leur demande de mise à jour. Ce sont les seules choses qui peuvent être mises à jour. Cependant, modifier l'approbation de congé. Demander, désolé, laisser le détail de l'approbation de la demande, désolé, aurait seulement la possibilité de changer. C' est approuvé DSR null. Donc, l'approbateur dit vraiment oui ou non. Je veux dire, si vous aviez plus de champs comme des commandes supplémentaires et tout ce que vous pourriez ajouter dans DTO. Bien sûr, ils devraient être présentés les objets de domaine. Mais mon point est que j'utilise les détails ici pour m'aider à appliquer certaines règles métier et certains comportements que mon application est capable de désactiver. Et, et encore une fois, j'ai vu des situations où il ya un plat D sarcelle et des décisions sont prises dans le 100 qui en fonction des données présentes, peut-être dans la demande sont dans le détail. C' est le genre d'opération à effectuer. Cela dépend donc de combien vous voulez casser ETL pour avoir ce niveau de granularité. Donc, vous savez, si c'est une approbation demandée, sachez exactement à quel gestionnaire aller. Ou vous pouvez avoir un gros gestionnaire de commandes qui prend les données et un tas d'instructions if pour voir si c' est, si l'ID est présent, alors s'il n'est pas présent, alors il, Mais alors si elle est présente et que ce drapeau n'est pas null, puis supposons qu'il s'agit d'une approbation. Tu pourrais le faire comme ça, mais je ne le fais pas comme ça. Je préfère savoir que lorsqu'il s'agit d'une demande d'approbation, j'ai cette commande d'approbation de changement. S' il s'agit d'une mise à jour, il s'agit d'une commande de mise à jour et de savoir exactement où aller pour faire quoi. Donc maintenant que nous avons cette explication détaillée hors du chemin, je vais sauter sur les fonctionnalités, les dossiers dans les futures, dans les allocations de congé et les types de congé au moins j'ai déjà défini les nouveaux gestionnaires et leurs commandes. Jetons donc un coup d'oeil à la plus simple. Nous avons donc la commande update leave type. Et cette commande pour le type de feuille prend juste nos requêtes héritent de la quête d'Eric comme nous le savons, mais ensuite il retourne ce que nous appellerons une unité. Donc, si vous passez juste au-dessus, vous devez voir que c'est une construction fournie par un médiateur qui ne représente rien comme le vide, non ? Pas de contenu. Donc, dans la conception de l'API, lorsque vous faites une mise à jour, vous retournerez généralement à 202, si je ne me trompe pas, ce qui est court pour aucun contenu. Ça veut dire que ça a réussi, mais je n'ai rien à te montrer. C' est essentiellement ce qu'est l'unité. Et puis nous prenons ce type de feuille DTO comme propriété. Je n'ai pas encore implémenté les commandes dans les gestionnaires, donc nous pouvons le faire ensemble. Je montre juste que nous avons même construction pour la commande d'allocation de congé de mise à jour, où nous prenons le détail de l'allocation de congé de mise à jour et retournons cette unité. Et nous avons cette commande définie en conséquence, également vide. Donc nous allons faire ces deux-là ensemble parce que c'est assez simple. Ensuite, nous allons passer un peu de temps à explorer les demandes de congés et les règles d'affaires là-bas. Maintenant, le flux de travail de notre gestionnaire, et je vais commencer par le gestionnaire de commande de type feuille. Très bien, le flux de travail ici est que nous devons vouloir récupérer l'enregistrement original pour mettre à jour cette origine sont nécessaires et puis trois, envoyer tout à la base de données, puis retourner l'unité, ou au moins quelque chose pour dire qu'il était réussi. Donc deux approches. Premièrement, vous pouvez utiliser le référentiel pour avoir cette méthode spécifique, car dans le cas des demandes de congé, il peut y avoir des méthodes spécifiques. Et une fois de plus, tu descends ce jouet de lapin. Avoir des méthodes très, très spécifiques dans chaque dépôt le long de la ligne. Ou vous pouvez simplement faire la plupart du travail à l'intérieur d'un gestionnaire, ce qui est pour de toute façon. D' accord. Donc, je vais juste dire que le type de congé var est égal à laisser le dépôt de type, Git. Et puis nous regardons dans la demande, en regardant dans la feuille pour regarder la carte d'identité. Maintenant, un autre modèle de conception que j'ai vu est quand il s'agit d'une commande de type leaf update, ils utiliseraient le type leaf normal, disons celui qui n'a pas l'ID, mais ensuite mettre la propriété ID dans la requête ou la commande afin que nous, lorsque vous effectuez la mise à jour pour inclure l'ID à l'intérieur de cet objet. Et puis le détail est juste lui-même. Il y a tellement de façons de le faire. Et encore une fois, ceux que vous comprenez ce que vous faites, vous pouvez me faire la meilleure implémentation en fonction de votre contexte. Ici. Le type de congé va être récupéré en fonction de l' ID de la charge utile entrant avec la demande. Et puis nous pouvons voir le mappeur pas MOP. Et puis la carte de points du mappeur va à peu près, dans cette situation, obtenir la requête de type feuille de pensée D2. Et remarquez que je ne spécifie pas, je dois taper cette fois. J' utilise des parenthèses, une carte de points de mappage, des parenthèses ouvertes. Et puis je vois que c'est la source des données. Et je veux que le type de feuille qui vient d'être obtenu de la base de données soit la destination des données. Et j'ai cette ligne verte parce que j'ai échoué sur la ligne. Je m'excuse. Alors on y va. Donc, mapper la carte de points et puis il voit s'il vous plaît juste mettre à jour tout ce qui est sur la droite avec tout ce qui est sur la gauche, cela peut être différent si c'est différent ou non, ceci, s'il vous plaît mettre à jour parce que la mise à jour va envoyer plus. Et c'est pourquoi notre détail doit avoir autant de champs que possible, l'objet de domaine lui-même. C' est bon. Le nom de Dava va avoir des jours par défaut. Nous ne savons pas ce qui a changé, c'est pourquoi nous voyons l'automne supérieur, il suffit de mettre à jour toutes les valeurs. Si ce Blanco le nom, alors nous allons le mettre à jour pour un nom vide. Espérons qu'ils ne l'ont pas fait. Cependant, s'ils n'ont pas changé de nom, alors on s'attend à ce que le même nom revienne. Une fois de plus, on ne peut pas rendre compte de ce qui aurait pu être le menton. Donc, nous voyons juste, s'il vous plaît mettre à jour le type de feuille avec les valeurs correspondantes provenant de l'objet dans la gauche. Et puis nous allons pondérer notre nouvelle mise à jour du dépôt. Et puis c'est là que nous envoyons sur notre correspondance de type feuille ou l'envoyons à la mise à jour. Et puis nous retournons juste la valeur de point unitaire. Et c'est tout. C' est notre opération de mise à jour. Eh bien, j'ai cette ligne rouge ici parce que j'ai int et pas unité. Donc après moi ce changement, tout va bien. Donc, c'est pour l'obésité dans le type de feuille ou quoi ? Type de feuille. Donc, en fait, je vais juste copier ça. Je ne vais pas me donner trop de travail. Je vais sauter pour mettre à jour l'allocation des congés. Et la seule chose que nous allons faire différemment ici est qu'au lieu d'utiliser le référentiel de type feuille, je vais utiliser le référentiel d'allocation de congé. Au lieu de voir le type de feuille DTO, je vois l'allocation de congé BTO. Et au lieu d'appeler le type de feuille d'objet, je l'appelle allocation de laisser, tout le reste est à peu près standard et à peu près le même. Et cela va gérer notre demande de mise à jour. D' accord, donc j'ai terminé les commandes leave request pour mettre à jour LaCo, nous voyons non que ce n'est pas si compliqué ou donc j'ai fait la commande update leave request et le gestionnaire correspondant. Donc, notre gestionnaire de commandes de requêtes de congé pris de l'unité de retour de commande. Et il est juste de connaître la différence une fois de plus, est le dépôt utilisé, mais c'est à peu près la même opération. Maintenant, une chose que vous pourriez vouloir considérer est les règles commerciales spécifiques, la nôtre, ce genre d'opération. Donc oui, le code, il ressemble le même, mais lors de la mise à jour d'une demande de congé, il peut y avoir d'autres choses qui doivent se produire. Droit. Donc, dans le cas de la modification, la demande, changement et l'approbation de la demande de congé où nous sommes seulement approuvés ou non. Nous devons également définir l'action dont nous avons besoin pour probablement mettre à jour d'autres choses. Donc, je pense que vous serez bon si nous avions une fonction spécifique dans notre dépôt pour gérer la demande de changement. Maintenant, le truc cool à propos des demandes est que nous n'avons pas nécessairement à avoir notre demande par heure de demandes par tout le temps. Je pourrais en fait réutiliser la même requête et le même gestionnaire pour gérer ce genre d'opération. Alors regardons cette situation. Donc, à l'intérieur de la mise à jour, leave , not leave allocation, excuses, à l'intérieur de la commande de demande de congé, nous pourrions avoir les demandes de congé DTO, mais je pourrais aussi avoir une propriété de changement de type congé approbation DTO. Donc, cette requête est capable d'avoir l'un de ces objets. Maintenant, dans le gestionnaire, je peux prendre une décision et appeler la méthode appropriée basée sur cela parce que c'est toujours une commande de mise à jour, non ? Donc, à l'intérieur de ce gestionnaire de commande de mise à jour, je peux mettre un peu plus de logique. Je peux voir si le détail de la demande de congé de point de requête n'est pas égal à null, alors c'est la route que je souhaite prendre. Je peux voir d'autre. Et je vais l'accélérer très explicite avec ceci d'autre parce que je ne sais pas si peut-être à l'avenir j'aurai peut-être d'autres règles commerciales. Donc, je vais juste me contenter de ces deux situations explicites où c'est soit que ce devrait être else-si des excuses, sinon, si sinon si le point de requête change, l'approbation de demande D2 n'est pas égale à null, alors faites ça, n'est-ce pas ? Et puis les heures supplémentaires allaient essayer de routine un retour. Donc, je vais prendre tout cela et dire que vous effectuez cette opération lorsque le détail des demandes de congé n'est pas égal à null. Cela signifie donc que celui qui consomme celui qui interrompt avec ce gestionnaire qui envoie sa demande doit s'assurer que le remplissage. Les champs appropriés en fonction de ce qu'ils veulent. Certains montrant juste une saveur différente parce qu'il pourrait aller le RequestHandler peering pour chaque situation, chaque scénario, mais alors vous pouvez en quelque sorte les empaqueter ensemble, comme je l'ai dit, le gestionnaire. Certaines personnes ont mis beaucoup de logique métier dans cette section. Encore une fois, c'est à vous de décider. Donc, si l'approbation de demande de congé de changement DTO n'est pas égale à null, nous avons une décision à prendre. Qu' est-ce qu'on va faire exactement ? Nous savons que nous avons récupéré et laissé des demandes dans un sens ou dans l'autre. Nous ne allons pas faire la cartographie complète que nous voulons vraiment faire est finalement appelé les mises à jour bateaux avec d'autres choses qui se passent. Donc, je vais appeler les attentes, laisser les demandes, le dépôt, changer le statut d'approbation. Non. Qu'est-ce qu'on fait ? Je pourrais lui donner la carte d'identité. Je pourrais lui donner l'objet de requête de congé, ainsi que le statut auquel il devrait être changé. Il y a un certain nombre d'approches que nous pouvons adopter. Non. On parle toujours de répéter le code, non ? Disons que je fais ça, je vais chercher les demandes de congé. Et puis cela serait relatif à la modification, l' ID de détails d'approbation de la demande. Et puis je peux dire donner à cette opération les demandes de congé qui ont été récupérées aussi. Valeur du champ de détail de l'approbation, qu'elle soit approuvée ou non. D' accord. Non, je répète cet appel pour obtenir une demande de congé. Non, je ne peux faire cet appel que si c'était la demande que le TOR a modifié le détail des demandes de congé qui est arrivé parce que si cela est connu, alors je ne peux pas obtenir cet ID. Et si c'est nul, donc après prendre une décision. Donc tu vois toutes ces autres choses ? Non. Ok, refactorisons. Donc, pour nous faciliter la vie, nous allons revenir au commandement. Et puis je suis allé dire, eh bien, non, je vois une bonne raison de jusqu'à ce que le consommateur inclue la carte d'identité. L' ID doit être présent dans ces deux sens, mais inclure l'ID ici. Donc, lorsque vous incluez l'ID là, je peux facilement dire l'ID de point de requête à l'extérieur du bloc if. Et puis je sais que j'ai les demandes de congé qui doivent être modifiées. Maintenant, si c'est que l'ensemble des détails GameOver, alors très bien. Je sais exactement quoi faire si c'est juste la demande de changement. Je n'ai pas besoin d'aller le trouver spécifiquement, mais alors je l'ai déjà et je peux simplement passer le statut d'approbation. Donc, cette méthode peut être implémentée dans notre dépôt Je vais quitter. Et je vais juste le rendre nul. Donc c'est juste cette tâche. Et les paramètres seraient DV, request et un booléen. Eh bien, il doit être booléen nullable du statut d'approbation. D' accord, alors quand on appelle ça, on passe juste ces deux commandes correctement. C' est donc une façon d'écrire le code. Je suis sûr que vous êtes probablement assis là et dire, d'accord, on aurait probablement pu le faire de cette façon ou je dois le faire de cette façon pour ma situation, c'est bon. Mais tant que nous comprenons la flexibilité que nous avons quand il s'agit de tout ce pipeline de gestionnaire de requêtes et comment nous pouvons gérer différents scénarios. Nous pouvons utiliser le gestionnaire unique pour gérer les différents scénarios potentiels basés sur la demande, fonction des données fournies dans la demande. Et, vous savez, vous n'avez pas à avoir d'appairage pour chaque scénario que vous pourriez avoir, mais vous pouvez avoir un gestionnaire pour couvrir plusieurs scénarios. Bon, donc maintenant que vous en avez le coup, je veux que vous alliez de l'avant et implémentez la suppression des communes et des gestionnaires. J' ai donc fait ça. Et nous avons la commande Delete leaf type, qui hérite des requêtes d'E/S. Donc, remarquez que je n'ai pas de demande et de type de données la dernière fois que nous utilisons les unités. Donc, c'est juste le 0 que vous n'avez pas nécessairement à mettre sur ce type de données s'il n'est pas censé retourner quoi que ce soit. Donc, cette commande delete aura un paramètre pour l'ID. Et puis à l'intérieur du gestionnaire, tout ce que nous faisons est de récupérer le correctement basé sur l'ID, puis nous l'envoyons à la suppression et ensuite nous retournons juste l'unité. Et à ce stade, c'est le thème général du centre commercial. C' est la même chose pour la demande de congé. Sachez si vous allez réellement exposer la fonctionnalité pour supprimer une demande de congé. C' est entièrement à vos règles métier, car il se peut qu'il n'y ait pas de suppression ferme, ce n'est qu'une suppression douce ou une suppression signifie vraiment annuler, n'est-ce pas ? Donc ce serait juste qu'il signalerait juste qu'il a été annulé, ignoré, mais garder le dossier. Donc je vous montre juste comment mettre dans la fonctionnalité. Mais encore une fois, les règles commerciales et leur application sont relatives à votre situation. C' est donc tout pour configurer les gestionnaires de suppression et de mise à jour pour nos objets de domaine. Et à peu près c'est l'essentiel de l'ensemble du modèle de médiateur couplé avec le C QR est pulvérisé. Alors que nous continuons, ce que nous allons explorer est de rendre ça un peu plus à l'épreuve des balles parce que c'est ça ? Sachez que tout peut arriver, n'importe qui peut venir et créer n'importe quoi, et il n'y a pas de règles réelles pour gouverner ce qui est valide par rapport à ce qui est invalide. Donc, nous allons essayer de regarder tout ce que nous gérons les données invalides arrivant et comment nous pouvons les rendre un peu universels et infaillibles. 12. Ajouter des valeurs: Très bien les gars, bienvenue. Dans cette activité, nous mettrons en place la validation de nos détails et de nos commandes. Maintenant, avant de passer à autre chose, il y a des chariots rapides sur nous que je voulais faire pour le code que j'ai écrit dans la commande update leave requests. J' avais utilisé par inadvertance les détails des demandes de congé. Donc, si c'est dans la mise à jour, alors vous devriez être adopté feuille détail de demande. Donc, si vous avez attrapé cette erreur et que vous l'avez fait à vous-même, alors félicitations à vous. Si ce n'est pas le cas, alors vous pouvez aller de l'avant et vous rencontrer. Ça me change. Pas de problème. Maintenant, ce dont nous parlons quand nous, sur le sujet de la validation, c'est la possibilité de nous assurer que les données que nous recevons avant qu'elles ne pénètrent dans la base de données sont bien valides car en l'état actuel, il n'y a rien ici qui nous empêche de commettre, invalider une base de données de jouets. Et une chose qui est très, très, très importante est l'intégrité des données. Vous ne voulez donc pas créer deux enregistrements avec des données vitales manquantes allocation de congés. On ne sait pas quel type de congé. Il est toujours plat à cela, donc vous voudrez le valider et ensuite rejeté bien sûr, s'il ne répond pas aux normes. Maintenant, quand vous êtes habitué à MVC et pensez-vous que la validation TBL et vous voyez que sur les modèles, nous pourrions facilement mettre nos annotations de données, ce qui est très vrai. J' ai trouvé cela utile. Mais alors, quand vous voulez étendre au-delà de ceux par défaut, vous devez commencer à construire de vieilles extensions et du sel, ce qui est, ce qui est également très bon. Mais dans ce programme particulier, nous allons utiliser des validations fluides, qui est une bibliothèque qui nous permet d'utiliser la syntaxe fluide et des règles très, très puissantes et des structures de validation appartiennent à nos propriétés dans notre classes. Bon, donc pour commencer, on va sauter sur le nouveau Git et je suppose qu'il est assez recherché pour parler. Et vous voyez tous ces merveilleux résultats de recherche surgir. Pas de point d'information. La documentation pour cette bibliothèque est très bonne et vous pouvez la trouver sur le site Web pour invalidation dotnet, et vous verrez comment nous pouvons étendre cela et le masser et l'utiliser à sa pleine capacité pour aider à leurs besoins de validation. Donc, je vais aller de l'avant et installer cette bibliothèque pour les extensions d'injection de dépendance. Et une fois que cela est fait, nous pouvons fermer NuGet puis passer à notre configuration. Mais une chose à noter, je ne pense pas avoir mentionné ça avant. Lorsque vous cliquez sur ces fichiers CSB, vous voyez réellement quels paquets sont installés sur leur version. Autrement dit, si vous connaissez le nom exact du paquet et la version que vous voulez, vous pouvez en fait coller aligné comme ceci à l'intérieur de votre build blob de fichier CSV et il obtiendra automatiquement ce paquet de NuGet pour vous. C' est donc une façon que vous pouvez également installer, résoudre ces paquets à l'avenir. Commençons donc par nos validateurs. Sachez que je me demande où mettre ces validateurs, je vais tout effondrer. Donc on peut voir tous nos dossiers compressés, d'accord ? Et bien sûr, nous avons les détails. Les détails sont là où nos validations doivent se produire parce que ce sont eux qui sont coincés à voir l'inflammation en notre nom. Nous n'avons pas besoin de valider ceux qui sont utilisés pour les requêtes. C' est un peu inutile, non ? Parce que les opérations de lecture n'ont pas besoin de validations. Les bonnes opérations ou les opérations d'augmentation, cependant, le font. Donc je vais, dans un des dossiers, laissez-moi commencer par le plus facile. Je vais ajouter et nouveau dossier. Et je vais juste appeler ça des validateurs. Et puis à l'intérieur de cela, j'ajouterai une nouvelle classe. Et puis celui-ci va être créer un validateur de type feuille D2. Bien sûr, pour le rendre public. Et puis je vais le laisser hériter d'un validateur abstrait. Et puis je vais passer le nom de la classe exacte à laquelle il est relatif. Donc, je vais juste aller de l'avant et inclure toutes les références manquantes. Et puis il ajoute que l'utilisation de la bibliothèque de validations fluentes et ensuite nous sommes prêts à partir. Donc, ce que nous avons est un constructeur. Donc CTR baignoire, baignoire et nous obtenons ce constructeur et ensuite nous pouvons commencer à définir des règles. Donc, laissez-moi juste jeter un coup d'oeil à la création de feuille de type D2. Que voudrait-on valider à ce sujet ? Eh bien, je voudrais vous assurer que les valeurs de nom fournies correctement. Nous pouvons également probablement limiter le nombre de caractères que cette propriété de nom peut avoir. Vous savez, la plupart d'entre eux ne le savaient pas, et il doit avoir une longueur maximale. Et il voudrait probablement des messages personnalisés pour la situation pour le nombre de jours par défaut, nous pouvons probablement voir qu'il est hostile, être plus, plus d'un, il doit être supérieur à 0, au moins pour le nombre de jours par défaut. Il y a donc un certain nombre de choses que nous pourrions valider. Ce que nous verrons, c'est la règle 4. Et puis vous remarquerez que cela semble juste laisser les mêmes expressions lambda que nous sommes habitués. Et si vous n'êtes pas habitué à eux, c'est bon. On finira par s'habituer à eux. Donc c'est la règle pour et ensuite on peut voir le nom. Et le truc cool à propos de la validation Flint, c'est que vous pouvez enchaîner les choses. Donc vous pouvez enchaîner ça et dire, OK, cette règle et cette règle, cette règle et cette règle. Donc, la règle pour le nom de point P. Est, disons, pas vide. Cela signifie donc qu'il doit avoir une valeur. Et puis je peux dire avec message, donc si elle vient sur m2, alors nous voulons que ce message soit imprimé. Donc je peux faire quelque chose comme ce nom de propriété pour qu'on ne veuille pas parler. Le nom de type doit être votre nom est requis, non ? Parce que je fais de la dynamique. Si nous changeons le nom dans la classe elle-même, alors nous pouvons oublier de mettre à jour le message en conséquence. Donc, en faisant cela, il héritera automatiquement quel que soit le nom ou quel que soit le nom est hors de la propriété, que c'est vraiment aussi. droite. Donc, nous allons dire que le nom de la propriété est requis. C' est notre message de validation. Une autre validation que nous pourrions mettre n'est pas nulle. Donc nous vous informons que cela ne devrait pas être nul. Et j'ai mis mon point-virgule prématurément, si terrible qu'il ne devrait pas non plus être nul. Voyons ce qu'on peut avoir. Nous pouvons également dire que la longueur maximale de la propriété name est peut-être 50. Il ne devrait pas y avoir de type de congé avec un nom qui dépasse 50, non ? Et puis nous pouvons ajouter un autre message à cela avec le message. Bon, donc je te donne juste des idées. Je veux dire, vous avez peut-être des exigences différentes pour votre validation que moi, mais ce sont des directives générales qu'ils peuvent suivre. Donc, regardons le, le point par défaut p est. Donc, par défaut, vous remarqueriez savoir que parce que le type de données est différent, certaines des validations peuvent ne pas nécessairement s'appliquer. Donc, je ne peux pas parler de longueur maximale avec la valeur par défaut est que cela n'a rien à voir avec un entier, n'est-ce pas ? Vous voyez que les flèches ont disparu, donc je vois qu'il doit être présent, mais alors c'est entier, donc il le sera toujours, peu près il sera toujours présent, mais nous pouvons le laisser seul. Mais ça ne devrait pas être vide. Ensuite, il ne peut jamais être nul. Vraiment intuitif car les entiers sont par défaut 0 et les valeurs nulles fournies. Mais on a vu que c'est qu'il doit toujours être supérieur à 0. Et puis je suis sûr qu'il y a moins de. Donc, disons que nous voulons voir dans le système il ne devrait pas y avoir de type de feuille qui est Poutine qui a un nombre quelconque de ces Greta qu'un 100 ou jusqu'à un 100. Et ça doit être au moins un. Ainsi, les différents types de données peuvent obtenir règles différentes et nous pouvons les enchaîner seuls si nécessaire. Nous pouvons mettre nos messages en conséquence afin que je puisse mettre mon message ici avec message ici. Donc, avec ces validations en place sur le type feuille DTO, voyons comment nous pouvons faire pour nous assurer que ces validations nôtres. Donc, dans la commande qui crée le type de feuille, n'est-ce pas, nous obtenons cette feuille, cette BTO de notre objet de commande, non ? Ce que je vais faire avant même de faire le mappage cependant, parce que je ne veux pas gaspiller des ressources sur une opération avec des données invalides. Donc, je vais faire la validation d'abord. Donc, je vais dire que var validator est égal au validateur DTO de type New Leaf. Donc, alors que c'est toujours un détail avant d'essayer de le mapper au type de domaine, je vais appeler ce validateur que je vais dire résultat de validation var est égal à. Et j'attends que mon validateur fasse l'appel pour valider. Et nous avons l'option asynchrone, donc en utilisant l'attente. Et puis nous passons dans l'objet à valider, qui sera un point de requête laisser le type DTO. À ce stade, le résultat de validation va soit avoir des flèches ne sont pas. Donc, je vais voir si le point des résultats de validation est valide, donc nous obtenons qu'il est valide ou non basé sur les règles. Ça va être valide ou non. Si c'est le cas. Disons que si ce n'est pas valide. Et puis pour la lisibilité, je voulais dire si est valide est égal à faux, non ? Parce que parfois, en toute justice, quand nous utilisons juste le signe d'exclamation, parfois quand vous êtes fatigué, émettre même manquer quand vous êtes en train de réviser le code et ainsi de suite. Donc, je vais juste être un très explicite si est valide équivaut à faux, alors je vais simplement lancer une nouvelle exception. Donc, si vous êtes habitué à la gestion des exceptions, l'exception est levée, c'est tout, se bloque essentiellement. Le programme saura plus tard que nous examinerons une meilleure gestion des exceptions et tout cela peut réellement nous aider à écrire un code un peu plus propre. Au lieu d'aider un tas de déclarations if pour vérifier un tas de choses, nous avons juste des exceptions. C' est notre être à travers et stratégiquement pour aider le flux de l'application. Donc, dans cette situation, si ce n'est pas valide, alors nous allons juste lancer une exception. Nous allons examiner comment nous pouvons faire des exceptions personnalisées aussi, qui peuvent être gérées différemment des exceptions fœtales réelles. Donc c'est à peu près tout. Nous ajoutons une validation ici pour nous assurer qu'elle ne va pas plus loin. Il ne va nulle part près de la base de données. Nous ne voulons pas qu'il devienne un objet de domaine s'il n'est pas valide. Maintenant essayons probablement la plus compliquée. Je vais donc vous mettre au défi de régler les validateurs pour l'allocation des congés, ce qui n'est vraiment pas si différent. Vous devez juste vous assurer que le nombre de jours est présent sur Il est supérieur à 0. L' ID de type feuille ne peut pas être nul, il doit également être supérieur à 0. Ensuite, vous pouvez être étendu pour vous assurer que l'ID de type feuille existe dans le système. Parce que si quelqu'un essaie d'usurper et ID de type Central Valley qui n'existe pas dans notre table, alors c'est aussi une flèche de validation que nous pouvons réellement attraper avant d'essayer de valider la base de données. En arrivant à la base de données, nous pouvons le faire pour la période. Donc, je vais vous mettre au défi de le faire, mais nous allons travailler ensemble sur les demandes de congé parce que celui-ci va avoir quelques choses à l'intérieur. Donc, une fois de plus, je vais ajouter un nouveau dossier validateurs, puis laissez-nous commencer avec les demandes de congé Crée, validation DTO. De quoi avons-nous besoin pour valider ? Eh bien, nos dates doivent être valides. Nous devons toujours obtenir l'ID de type feuille, donc nous allons le faire ensemble. Et bien c'est facultatif, alors c'est très bien. Alors passons à celle-là. Donc, il commence avec notre classe crée des demandes de congé validateur de détail. Je le rende public. Et puis j'hérite du validateur abstrait relatif à nos détails de demandes de congé Créer. D' accord, donc j'ai déjà écrit une partie de la citation pour toi et on va le faire. Ce n'est pas terminé parce que je veux que nous fassions certaines parties ensemble, mais la règle de départ doit être inférieure à la fin. C' est maintenant que nous avons vu que nous pourrions également utiliser la valeur scalaire ici. Donc, j'aurais pu mettre un entier, mais alors un entier serait une comparaison incompatible avec le temps. Donc j'aurais pu mettre l'heure de la date, non. droite. Assurez-vous juste que la date de début est pas avant aujourd'hui sont principalement avant aujourd'hui, ce qui n'est pas nécessairement le cas, non ? conséquent, en fonction de la règle métier, vous pouvez effectuer une comparaison en conséquence, mais cette règle métier indique que les dates de début doivent toujours être inférieures à la date de fin. Et puis le message que je peux dire le nom de la propriété doit être avant la valeur de comparaison. Donc, dans notre détail de type feuille de création, nous avions codé en dur le 50, nous avons codé en dur le, l'un et le 0 ici, mais nous pourrions facilement les remplacer et il a parlé sur parson correctement. Nous pourrions facilement remplacer ces zones par des comparaisons. Je vais laisser celui codé en dur pour null, mais je vous montre juste vos options, non ? Donc, je vois que la date de début doit être avant NDI il similitude pour l'Inde il, il doit être plus grand que le nom de la propriété et la valeur de comparaison. D' accord ? Non, par rapport à l'ID de type feuille, j'ai dit que notre validation pouvait prendre un certain nombre de formes. Un, vous voulez vous assurer qu'il est supérieur à 0, ok, très bien. Et d'autant plus important, serait que vous vouliez vous assurer qu'il existe. Maintenant, si nous vérifions simplement s'il existe, même s'ils ont envoyé plus de 0, 0 n'existerait jamais en tant qu'ID de type feuille dans la base de données. Donc on pourrait enchaîner ça, parce qu'on pourrait gaspiller la base de données appelée en faisant ça. Pour que je puisse dire plus grand que. Et puis je vais voir 0. Et puis je vais aussi voir qu'il doit exister. Donc j'utilise ce que vous appelez un délégué ici, et je vais juste effacer tout cela et le retaper à partir de zéro pour que vous puissiez voir exactement ce qu'ils vont dire la plupart des parenthèses asynchrones, ouvertes et fermées, c'est un vu, nous allons donc attendre, mais nous allons ensuite définir un délégué. Désolé, nous ne sommes pas que nous utilisons, nous lui faisons savoir que c'est un délégué asynchrone qui prend quelques paramètres. Dans ce cas, nous avons besoin de l'ID, qui est la valeur. Donc, nous prenons cette valeur comme un paramètre numéro 1. Et puis Tolkien est un jeton d'annulation comme outil de paramètre. Et puis j'utilise une flèche Lambda pour ensuite définir un bloc d'objet ou un bloc de méthode. Donc, ce bloc de méthode est l'endroit où nous allons effectuer cette vérification pour voir s'il existe. Maintenant, vous vous demandez probablement, ok, cela signifie que nous avons besoin d'une base de données appelée comment appeler exactement la base de données à partir d'un validateur ? La chose cool à ce sujet est qu'il nous permet d'injecter directement ou des dépendances. D' accord, donc nous pouvons continuer en injectant notre dépôt afin que nous sachions comment l'injecter le mettra dans le constructeur. Nous pouvons utiliser le point de contrôle pour initialiser le champ. Je suis déjà passé à mes traits de soulignement, ce qui est évidemment facultatif. Mais en utilisant cela, nous pouvons encart de cette fonction déléguée la plus acing vérifier l'existence du dépôt feuille I. Donc deux choses à noter ici sont trois choses. Premièrement, nous injectons le validateur nous permet d' injecter d'autres dépendances comme nos dépôts. C' est un outil. Nous pouvons en fait avoir une fonction personnalisée faisant validation personnalisée pour quelqu'un de taper ce IN pour cela à partir de zéro. Donc, ici, nous voyons un point. La plupart j'aurais mousseline l'async. C' est très bien. Donc, la plupart asynchrone. Et puis parce que nous utilisons async, nous devons laisser le modèle délégué, il est en train d'effacer. Donc, le délégué est quand prendre deux paramètres. Id représentant l'ID même que nous validons ou la valeur que nous validons. Et tolkien serait représentatif du jeton d'annulation que nous utilisons sont lambda R0, puis ouvrir et fermer accolades. Ensuite, à l'intérieur de ces accolades, nous avons notre logique. Donc, la première ligne de notre logique est de vérifier ou de référentiel si le type de feuille existe, puis de retourner qui n'existe pas. D' accord, non, cette fonction que je viens de créer, donc j'ai juste étendu notre dépôt générique pour avoir une méthode qui renvoie un booléen. Il est appelé existe et il faut int id. Donc, cela, vous pouvez l'ajouter au dépôt générique et vous pouvez l'utiliser sur chacun d'entre eux. Mais le fait est que nous pouvons savoir, utiliser cela pour vérifier si quelque chose existe dans une table particulière. Et dans cette situation, c'est une belle chaussure pour vérifier si ou elif type ID existe. Donc, sachez que vous êtes équipé de tenir pour gérer cet ID de type feuille. Je vais vous défier d'aller installer des validateurs pour l'allocation des congés. Hit pause, prendre quelques instants, mettre en place les validateurs Ford allocation de congé et tout autre détail que nous n'avons pas encore regardé. Et puis quand vous revenez un plus, montrez simplement une autre façon que nous pouvons refactoriser notre code pour réduire la répétition. D' accord, donc j'espère que vous avez pris le conseil que vous avez arrêté, vous avez essayé de vous faire et que vous avez eu un certain succès. C' est bien. Mais je veux vous montrer juste un autre niveau que nous pouvons faire ça. Donc, quand nous étions en train de mettre en place les détails, nous avons en quelque sorte réalisé que ce serait finir répéter nos propriétés sur plusieurs détails. Par exemple, le type de feuille de création D2 et le détail du type de feuille, ils ont en fait les mêmes propriétés barre la police. Personne ne s'appuie sur l'ID que nous servons à travers les détails de base. Donc, les règles de validation pour les deux d'entre eux seront en fait les mêmes sauf peut-être celle qui dit l'ID1 au hub de validation pour cela. Donc, parce qu'on a un ID, on ne l'a pas, et le validateur jusqu'à présent a été très fortement tapé parce que lorsque nous avons le détail de type feuille de création, il est seulement quatre pour créer des détails et des mises à jour de type feuille, D2 aurait pour avoir son propre validateur. Donc ce que j'ai fait, c'est de l'étendre un peu. Et c'est ce qu'ils appellent le développement piloté par broche. Cela signifie faire ce que vous pouvez jusqu'à ce que ce ne soit plus pratique, alors vous refactoriser, non ? Donc, quand vous appliquez ces principes solides, parfois vous ne le voyez pas tout de suite. Mais à un certain moment, vous vous rendez compte que cela devient fastidieux ou ce n'est pas pratique, ce n'est pas conforme au principe. Et donc vous refactorisez votre code pour tirer le meilleur parti du principal à ce stade. Donc, à ce stade, nous analysons que nous avons les mêmes règles de validation réparties sur plusieurs fichiers, ce qui est très bien. Ou au moins avoir plusieurs fichiers pour les validations est bien. Mais avoir les mêmes règles répétées peut être dangereux parce que si la règle doit être changée dans l'une, nous pourrions la changer dans l'une je manque l'autre. Nous connaissons ce risque. Donc, ce que j'ai fait est d'avoir une interface qui est une obstruction de nos champs. Très bien, donc comme le détail de type de congé que j'ai créé, je laisse ce détail et cela a les champs que nous savons que le tab2 feuille a besoin d'avoir. Donc, dans le type de feuille DTO, j'ai hérité lié. Je laisse ce détail. Donc, ces deux champs ne sont que les implémentations de ce qui a été défini dans l'interface. De la même manière dans lift IB2, bien qu'il hérite des détails de base, il hérite également du détail de type elif. Donc, laissez que BTO aurait l'ID ainsi que les propriétés provenant de notre interface. Maintenant. Ok, Donc, l'étape suivante est que nous pouvons créer un validateur de détail de type I leave, ce qui signifie que je suis en train de valider contre l'interface. Donc, mes règles ne sont plus directement appliquées au type feuille DTO. Ils pourraient l'être, c'est bon. Mais comme nous l'avons vu, nous devons avoir plusieurs parce que nous devrions avoir un tabul2 pleine feuille sur 14, le Create. Donc, à la place, je peux mettre en place des validations contre l'obstruction. Les deux détails héritent en fait de l'obstruction. Ces règles s'appliqueront donc aux deux. Et puis quand je dois être personnalisé, j'ai ma feuille, ce validateur de détail dans lequel je dis créer feuille. validateur de détail et tout ce que nous savons déjà. Mais alors dans le constructeur, j'appelle simplement une méthode include. Donc, c'est l'API couramment est que nous sommes en train de nous suivre pour avoir des validateurs qui s'appliquent à d'autres choses, s'appliquent à une autre classe. Donc, cela s'applique vraiment à l'interface, ce que je vois quand je fais ce validateur de détail de type feuille, inclure les règles du validateur de détail de type Je laisse. Et puis je peux avoir mes méthodes de costume aussi. Donc, dans le détail de la mise à jour, je pourrais avoir le même type de syntaxe, mais alors ce sont les mises à jour, ce qui signifie que j'ai aussi besoin de notre règle pour. Et puis je peux dire que j'ai besoin d'une règle pour les champs d'ID. Je peux dire « p dot ». Et puis voyez qu'il me donne toutes les propriétés, y compris l'ID parce que c'est contre ce type. Donc, ma validation pour l'ID est qu'il ne devrait pas être nul et qu'il devrait venir avec un nom de propriété de message doit être présent car, bien sûr, lorsque vous mettez à jour, vous devez envoyer l'ID de l'enregistrement que vous mettez à jour, c' est pourquoi nous avons besoin de cette règle de validation pour la mise à jour et c'est pourquoi je devrais avoir le fichier séparé pour la mise à jour. Mais c'est beaucoup plus propre car au moins nous n'avons pas à répéter les règles pour le nom et le type ou le nom. Et la valeur par défaut est, désolé, nous n'avons pas besoin de répéter cela à travers les deux par les données. Donc, vous verrez que fait déjà cela déjà pour la demande de congé et pour l'allocation de feuille, encore une fois, pour la demande de congé, je dois laisser des demandes DTO, et c'est le même code que nous venons de regarder quand nous avons fait les demandes de congé détaillant des données valides avec injection. Et dans ce cas, nous devons l'initialiser et ensuite nous faisons les règles. Mais quand nous regardons dans le validateur de détails de demande de congé crée, nous voyons que nous devons faire l'injection. Donc nous devons encore faire notre injection et nous devons l'initialiser. Et puis nous passons cette injection dans la méthode include car bien sûr, le validateur de détails de requête d'E/S doit avoir cette injection. Donc Kant l'appelle nous devons fournir cette valeur pour le constructeur. Donc c'est juste cette chaîne de marguerites, mais je pense que c'est beaucoup plus propre d'une façon ou d'une autre. Et nous n'avons pas besoin de répéter toutes ces règles à tous les niveaux. Donc, vous remarquerez que la création et la mise à jour semblent très similaires, sauf le fait que la mise à jour a cette règle supplémentaire pour l'ID. Et juste pour la fin, nous avons les détails de l'allocation des yeux. J' ai les tills d'identification, les interfaces ne l'ont pas montré. Donc, tout ce qui est commun à tout le monde, je viens de le mettre dans l'interface et ensuite tout le reste peut être mis directement dans les détails au besoin et validé en conséquence. Mais pour créer une mise à jour, sont toutes les choses dont nous avons vraiment besoin. Nous n'avons pas nécessairement le sens du week-end de la règle de validation sorte de commentaires de demande peut-être limiter la longueur. Nous n'avons pas forcément à faire quoi que ce soit pour annulé. Encore une fois, je vous donne juste les directives. Vos règles et exigences métier peuvent être différentes, mais vous configurez vos validations selon vos besoins. Donc, nos demandes de congé de mise à jour détail hérite de la base, et je laisse les détails des demandes. Nous n'avons pas à le faire pour la liste parce que nous ne validons pas la liste. Nous ne validons pas non plus le détail, mais cela crée doit absolument hériter. Et puis l'approbation de la demande de modification qui prend de ce détail, mais nous ne sommes pas tout à fait à un moment donné, nous pouvons valider cela. Je n'en donne pas la priorité. Mais puis sur mise à jour et créer, nous avons certainement besoin d'avoir déjà, d'accord, non, Pour notre créer un emplacement, donc je laisse l'allocation et puis les deux crée un héritage de mise à jour de je laisse allocation. Donc, je vais juste sauter au validateur d' allocation Je laisse où nous avons des règles pour le nombre de ceux-ci. Celui-ci est donc simple et à mesure que l'application se développe, les règles métier changent. Nous pouvons facilement placer notre validation ici sans modifier les requêtes personnalisées et les autres opérations des clients autour de ces règles métier. Donc règle pour un certain nombre de jours en ce moment, j'ai juste qu'il doit être supérieur à 0. Et mes messages de validation ont été victimes d'une copie et d'un collage. Donc, je vois juste le nom de la propriété doit être supérieur à la valeur de comparaison pour la règle supérieure à pour la période. Donc la période devrait vraiment être l'année, n'est-ce pas ? Donc, pour la période 2020, ce sont le nombre de ceux-ci que vous avez obtenu. C' est les points de pôle de la table d'allocation des feuilles au cas où cela n'a pas été expliqué plus tôt. Donc, la règle pour une période est qu'elle doit être supérieure ou égale au point de temps 10 point année. Et nous pouvons renforcer ça un peu plus pour l'instant, nous allons juste l'utiliser. Donc, nous verrons le nom de la propriété du message doit être après cette année. Et puis nous avons tous vu et écrit ensemble la règle de validation pour l'ID de type feuille et non pour les données valides Create leave allocation détail où il suffit injecter le dépôt de matrice feuille et d' injecter le dépôt de matrice feuille etde l' initialiser et le passer dans notre méthode d'inclusion. Et pour les mises à jour faisaient la même chose, sauf que nous avons aussi cette règle pour l'ID. Donc, c'est vraiment à la validation. Oui, ça a pris du temps pour y arriver. Il y avait des réflecteurs en cours de route, mais je suis sûr que vous pouvez voir comment tout cela se réunit pour réduire une répétition sur plusieurs fichiers et pour aider aussi, garder tout structuré. Donc, une conséquence de ce qui suit, les principes solides bien sûr, est que vous allez finir avec beaucoup d'autres fichiers dont nous avons discuté plus tôt. Mais il se réunit bien et nous aide à réduire le nombre de fois que nous plaçons la même chose à plusieurs endroits. 13. Ajouter des exceptions et des objets de réponse personnalisés.: Hé les gars, bienvenue. La dernière fois que nous étions ici, nous étions assis nos validations pour les gestionnaires et pour nos différents détails. Et en un mot, nous avons réalisé que nous devions mettre quelques règles de sorte que chaque fois que nous obtenons la commande create leaf type avec le create leaf type D2 ou n'importe quel détail. Nous pouvons l'exécuter contre le validateur et ensuite nous retournerions une exception si elle n'est pas valide. Donc, nous aurions dû le faire dans tous les gestionnaires pour la mise à jour et créer tout ce qui a besoin d'une validation devrait avoir le minimum de ces lignes. Donc, je vais juste cliquer sur et vous pouvez juste aller de l'avant et copier au cas où vous n'auriez pas fini ça. Donc c'est pour la mise à jour. Nous avons juste regardé la création pour la mise à jour de type feuille demande complètement à peu près tous ressemblent à la même chose. Très bien, ils valident tous et entrent une exception. Maintenant, je veux parler des exceptions personnalisées et des réponses MRD, non ? Parce qu'à la fin de la journée en ce moment, tout ce que nous faisons c'est de lancer une exception. Une exception peut être levée en fonction de notre lancer manuellement. Il multi peut également être jeté à cause de quelque chose d'autre. Il pourrait être un problème de redirection de base de données, ça pourrait être autre chose, non ? Il est donc toujours bon que l'application consommatrice ou tout ce qui appelle le gestionnaire ait une bonne idée de ce que grâce à cette exception. Donc, la chose cool à propos des exceptions est que vous pouvez les étendre. Donc, le type de données de base pour une exception est l'exception que nous allons lancer ici ce que nous allons créer le nôtre pour les fins spécifiques. Nous allons donc commencer par créer un nouveau dossier dans notre projet. On va appeler ça des exceptions. Et dans cela, nous allons avoir de mauvaises exceptions de requête, non trouvée et exception de validation. Donc, vous pouvez aller de l'avant et créer ce dossier. Et ces trois dossiers, rappelez-vous à moi qu'ils sont publics, bien sûr. Et ce que nous allons faire est de laisser chacun d'entre eux hériter des exceptions d'application. Donc, l'exception est le type de base d'une exception d'application est utilisé comme un type de base pour les exceptions définies par l'application art. Donc, nous allons juste aller de l'avant et laisser chacune de nos classes hériter de cette exception demandée au beurre plus tard quand nous voulons définir que les requêtes qui étaient centrales contre mauvaises, accord, mais pour l'instant nous allons initialisez-le ou lisez le code pour le relier. Donc, tous auront un constructeur. Et pour celui-ci, le constructeur va prendre un message de chaîne et ensuite notre base doit hériter du même message qui est passé la base étant notre extension d'obligation. C' est donc à quoi ressemble cette exception. Exception d'application plutôt. Désolé pour ça. Non, je vais continuer. Nous pouvons faire la même chose pour notre téléphone NAACP, mais alors nous pouvons être un peu plus explicites avec certaines choses. Par exemple, si nous allons voir pas trouvé, nous allons probablement vouloir voir le nom de ce qui était recherché et peut-être la valeur clé. Bon, donc nous passons Nom sur le clavier, alors la base nécessite une chaîne, donc il a trois surcharges. Vous voulez passer une chaîne ici. Donc, nous pouvons simplement transmettre notre message que nous savons que nous voulons imprimer. Et mon message va dire que le nom, quel qu'il soit et sa clé n'a pas été trouvé. Très bien, donc si la recherche de quelque chose, il n'est pas formé par une exception non trouvée, pour l'exception de validation. On va avoir un peu plus de fantaisie. Donc, l'exception de validation va vouloir R, nous allons vouloir qu'il retourne la liste de toutes les choses qui pas avec la requête ou les données qui vont envoyer dans sa quête, non ? Donc je vais avoir une liste de chaînes et je vais appeler ça des erreurs, non ? Et puis dans le constructeur, nous allons avoir les résultats de validation, les données étant transmises. Ainsi, les résultats de validation du résultat de validation proviennent de la validation fluide. Donc, nous allons juste passer cet objet entier là-dedans, il utilise des résultats de validation fluents. D' accord, et puis on peut voir qu'on peut initialiser ou erreurs. Je veux dire, initialisez ça ici. Et puis nous pouvons voir pour chaque erreur de validation dans les erreurs. Ou je peux simplement le raccourcir et dire pour chaque erreur dans les erreurs de point de résultat de validation, nous voulons ajouter cette erreur. Donc, je vais juste dire urls.py. Et puis nous avons juste point d'erreur et nous avons un message d'erreur. On y va. Donc, ce message d'erreur serait tout ce que nous avions configuré dans nos validateurs comme message à renvoyer quand il n'est pas valide. Donc maintenant, nous avons nos exceptions personnalisées. Nous allons vraiment nous concentrer sur l'exception de validation, nodal droit. Et donc, dans nos gestionnaires, nous pouvons réellement mettre à jour cela de lancer une nouvelle exception pour lancer une nouvelle exception de validation. Donc, si le résultat de validation n'est pas valide, nous lançons cette nouvelle exception et nous transmettons nos résultats de validation et vous voulez inclure les références manquantes. Donc vous voyez ici qu'il demande ces livres. Nous savons que nous l'avons défini. Dans nos exceptions personnalisées. Très bien, donc vous pouvez aller de l'avant et mettre à jour chaque ligne qui auparavant jetait juste une nouvelle exception pour savoir jeter cette exception de validation. Rappelez-vous à chaque fois que nous incluons notre exception personnalisée et non la validation des fluides ou la validation des données sur l'art. Alors allez-y et mettez-les à jour tous et assurez-vous d'inclure la bibliothèque du panier. Maintenant, je peux imaginer que vous vous demandez, Ok, alors comment puis-je utiliser les autres exceptions ? Eh bien, regardons l'exception non trouvée. Donc, en C, l'opération de suppression, nous devons trouver l'enregistrement, puis faire la suppression et puis retourner bien, les unités, non, mais que se passe-t-il si nous ne trouvons pas cet enregistrement ? Eh bien, alors c'est une opportunité parfaite où nous disons si l'objet que nous recherchons renvoie null, ou si l'opération retourne null, alors nous lançons l'exception non trouvée. Et que passerons-nous dans l'exception non trouvée ? Rappelez-vous que c'est qu'il faut deux paramètres. Il prend le nom et la clé, pour qu'on puisse facilement dire le nom. Et puis c'est un bon moyen de le garder fortement tapé. Donc, nous cherchons un type de feuille. Donc, nommez les types de feuille ou dites dans le type de feuille avec l'identifiant qui a été transmis n'était pas le téléphone ou d'autres requêtes. ID de point, à droite. On y va. Très bien, alors vous pouvez commencer à décorer vos gestionnaires de suppression avec cette seule ligne. Donc, dans le cas des demandes de congé, ce sera la même chose sauf que nous vérifions si la demande de congé est nulle, et alors ce serait une demande de congé non appelée. Allez-y et mettez à jour. Donc, vous pouvez le faire avec l'allocation des congés aussi. Très bien, donc une fois que vous avez terminé avec cela, alors vous avez réglé une bonne gestion des exceptions au moins ou une gestion personnalisée des exceptions dans votre handless. Maintenant, une autre chose que nous voulions examiner est les réponses des clients. Alors que se passe-t-il quand il y a un résultat positif ? Et même quand il y a des résultats négatifs, non ? Donc, c'est là que votre, vos besoins architecturaux peuvent différer des miens en termes de ce que vous voulez faire. Mais voici un concept. Nous pouvons définir des types de réponse personnalisés ou avoir des réponses de base où nous pouvons retourner des données en fonction de la situation. Donc, si cela échoue, nous pourrions jeter l'exception sûr. Ou nous pourrions avoir une réponse client qui a un faux indicateur de succès, il contient les erreurs de validation. Et donc le client saura toujours que je m' attends à une réponse de ce type de données que nous devrions toujours avoir ces données. Si le drapeau est faux, que je connais le champ informatique, s'il est vrai que je sais qu'il passe. Donc on va regarder quelque chose comme ça. Donc une sorte d'alternative à simplement lancer une exception ou retourner juste l'ID, ce que nous pourrions faire est de définir un nouveau dossier. Donc, nous avons un nouveau dossier ici appelé réponses et inits, nous avons une réponse de commande basée sur des fichiers. Et il aura trois propriétés. Succès, qui est un message booléen, qui est une chaîne, et une liste d'erreurs, si nous avons besoin de renvoyer les erreurs, juste, alors après que nous avons cette réponse de commande de base, nous pouvons l'étendre pour faciliter le opérations spécifiques. Donc, par exemple, un résultat voudra probablement étendre ceci est que nous voulons retourner la certitude à chaque fois qu'un type de feuille est créé ou mis à jour, n'est-ce pas ? Donc, la réponse de base peut ne pas suffire. Nous pouvons donc créer une réponse personnalisée associée aux types de feuilles. Nous avons donc déjà ces requêtes web. Ensuite, vous pouvez créer un autre dossier appelé réponses, puis nous pourrions étendre cela. Je ne vais pas devenir si compliqué. Cependant, ce que je vais faire est juste d'ajouter une autre propriété ici et je l'appellerai ID, n'est-ce pas ? Ou on peut l'appeler ID d'enregistrement. Donc, cela signifie que chaque fois que quelque chose arrive, nous créons, au lieu de simplement retourner l'identifiant, ce que je pourrais faire est, et c'est un énorme changement. Alors passons ligne par ligne et j'aborderai les lignes rouges à mesure que nous y arriverons. Donc au départ, nous disions juste obtenir les résultats de validation, lancer une exception, sinon continuer et puis retourner le levier. Partez. Dans ce cas, laissez l'ID de la demande. D' accord ? Sachez ce que je fais, c'est que je vois d'abord, initialise la réponse, donc nous avons une réponse de base, c'est bon. Ensuite, je vois si le résultat de validation est faux, définissez ces frayons succès pensé à des chutes. Le message que vous pouvez mettre dans un message personnalisé si vous le souhaitez. Et puis les erreurs que nous aimerions remplir avec les mêmes erreurs de validation. Donc, je suis juste de les sélectionner dans la liste des erreurs sont de cette collection d'erreurs. Donc, cette sélection a une ligne rouge parce que j'ai besoin d'une bibliothèque supplémentaire, qui est System.Out liens. Alors assurez-vous qu'on puisse voir ça ensemble. Et puis il obtient juste les messages d'erreur, les met dans une liste, puis cela va dans. Donc c'est un beau liner lui-même le pour chaque boucle droite ? Puis connu plus tard, nous voyons si l'annonce a été réussie et âme, ce qui se passe est que si cela se sent non exceptionnel aurait été par un automatiquement par Entity Framework de toute façon. Donc, si cela ne se produit pas, alors nous obtenons une exception. Donc, il n'arriverait jamais aussi loin si cela ne réussit pas. Alors le succès est vrai. Notre réponse est la création réussie, puis nous définissons l'ID. Donc c'est ce que je vais vous voir dans tout le monde, nous ne retournons que des pièces d'identité, non ? Nous ne renvoyons que l'ID de l'enregistrement nouvellement créé. Vous pourriez avoir une exigence où vous devez retourner l'enregistrement entier. À ce stade, vous pouvez simplement étendre la réponse de la commande de base crée une nouvelle classe appelée il crée la réponse de demande de congé. Et qu'il n'a pas fait mal de cela et lui donner le paramètre DTO pour une demande de congé DTO, vous faites votre mappage, vous le retournez. Comme je l'ai dit, je ne vais pas devenir si compliqué, non ? Non, nous ne pouvons pas regarder cela dans notre leçon de considérations futures ou de considérations supplémentaires, mais je voulais juste faire comprendre ce concept de réponse client. Alors nous retournons la réponse. Maintenant, cela a notre ligne rouge parce que nous avions défini notre commande pour retourner int. D' accord, pour que nous puissions passer à notre commandement. Faites-lui savoir que je demande est censé retourner la réponse de commande de la bête. Très bien, et puis notre erreur apparaîtra et nous sauterons buck et étions bucking ou handler, nous voyons que nous pouvons retourner la réponse dès que nous mettons également à jour le gestionnaire, n'est-ce pas ? Rappelez-vous donc que nous avons cette commande et le type de retour peer-to-peer. Laisse-moi juste mettre à jour ça. Et puis enfin le type sur la tâche pour la poignée. Bon, donc, quand vous voulez changer, modifier vos divs de retour, modifier vos divs de retour c'est tout ce que vous avez à faire toutes ces modifications une fois de plus, non ? Pas de réponse de commande bs. Donc, si vous voulez obtenir granulaire, je continue à dire que vous n'avez pas à obtenir le livre granulaire basé sur vos exigences, vous aurez besoin d'être vous ne pouvez pas avoir besoin. Je ne fais pas une exigence d'or et de créer des réponses de commande pour chaque gestionnaire solitaire ou gestionnaire de commandes que j'ai. En ce moment, je vais juste utiliser la réponse de base. Et je vais également apporter cette modification à la demande de congé pour l'instant au moins afin que vous puissiez voir l'idée de comment vous pouvez avoir des exceptions personnalisées et, ou comment vous pouvez améliorer en haut de vos réponses personnalisées. 14. Refactorisation et considérations supplémentaires: Hé les gars, bienvenue. Il s'agit plus d'une séance d'examen qu'une séance de codage et seulement de quelques considérations supplémentaires. Donc, les gorges ou les activités peuvent avoir mentionné que vous avez des alternatives et que vous avez toujours des alternatives. Que ces alternatives soient bonnes ou mauvaises ou citent sans citation, les meilleures pratiques sont parfois relatives à ce que vous faites et à ce que vous devez accomplir. Cela dit, bien sûr, il y a des principes fondamentaux auxquels vous voulez adhérer indépendamment et ceux qui les auront comme guide, alors vous allez probablement prendre de meilleures décisions. Donc, une chose que nous voulons examiner est la séparation des préoccupations, non ? Donc la séparation des préoccupations nous a conduit à avoir plusieurs projets et beaucoup plus de fichiers que nous avons probablement eu dans d'autres projets car je suis ensemble fait, je pense que nous avons déjà plus de fichiers dans ce projet que nous l'avons fait dans l'ensemble de l'application que nous devons tous les deux reconstruire, n'est-ce pas ? Donc, juste dans ce projet seulement, nous avions plusieurs DTL. Pourquoi avons-nous eu plusieurs détails ? Eh bien, nous voulions ce genre de séparation parce qu'il pourrait y avoir règles commerciales qui régissent ce qui peut se produire sur n'importe quel type d'opération. Alors regardons moi laisser les détails des demandes. Laissez les détails des demandes. Nous en avions une pour la liste qui ne contenait que les données qui étaient absolument nécessaires lorsque nous avons besoin de servir la liste des demandes de congé. Nous avons un DTO qui a tous les champs qui correspondent à ce qui se trouve dans la table. Et cela pourrait être considéré comme le DTO détaillé. Nous avons également eu la mise à jour, qui n'avait que quelques champs requis pour une opération de mise à jour. Nous avions les Crée où nous avions peu de champs pour une opération de création, et cetera. Donc nous les divisons en plusieurs fichiers. C' est donc l'une des conséquences que je voulais dire de l'adhésion à ces principes de séparation des préoccupations. Mais vous allez finir avec beaucoup plus floue que vous n'êtes probablement habitué. Et vous allez devoir les séparer d'une manière que vous pouvez toujours les trouver. J' ai donc commencé avec des détails puis dans les détails, je les ai séparés par le type. Et puis après cela, vous commencez à voir les fichiers vont également configurer les validateurs. Et puis en raison des différentes règles de validation qui pourraient être requises pour les différentes DTU, nous avons plusieurs validations, un sol pour Create, nous avons 14 mises à jour. Mais en même temps, nous avons vu où nous devions nous consolider parce que c'était un peu autoritaire et nous avons commencé à nous répéter. Vous avez donc le principe DRY. En raison du principe DRY, nous avons créé une interface qui avait les champs de base. Permettez-moi donc d'examiner la question de l'allocation des congés en sera peut-être un meilleur exemple. Donc, nous avons, je vais laisser l'allocation, qui a tous les champs qui sont nécessaires pour l'allocation des congés annuels. Alors nous avons nos détails héritant de cette interface, n'est-ce pas ? Donc oui, vous voyez à nouveau l'implémentation ou vous voyez les champs ici. Et encore une fois, ce qu'ils sont vraiment motivés par cette exigence de l'héritage de l'interface. Et puis on pourrait mettre en place un validateur contre l'interface. Donc, tous les champs communs, à droite, réglés par l'interface sont en cours de validation. Et puis les autres validateurs incluent simplement les validations, puis implémentent leurs validations personnalisées selon les besoins. Cela nous aide à réduire la répétition du code. Et encore une fois, au fur et à mesure que votre projet se développe, vous risquez d'oublier de mettre à jour une partie de votre projet lorsque vous effectuez un changement quelque part. une autre chose à noter dans notre validateur, initialement, les initialisations dans nos gestionnaires, et je ne pense pas que je l'ai souligné plus tôt, quelqu'un pour s'assurer que je sais est que lorsque nous initialisons ces validateurs, nous doivent passer dans un objet du type qu'il attend, n'est-ce pas ? Parce que rappelez-vous que ce validateur a besoin du dépôt de type Je quitte et ensuite nous avons le constructeur voyant que j'ai besoin du dépôt de type elif. Donc, il n'y a aucun moyen d'instancier cela sans le transmettre. J' aime bien que nous ayons fait ici. Donc, si vous aviez dirigé la ligne et tout ce temps, je m'excuse, je néglige celui-ci, mais vous pouvez aller de l'avant et le faire parce que ce que vous devez faire est injecté dans le gestionnaire et l'avoir injecté dans le et vous le transmettez simplement de la même manière que, quand nous en avons besoin pour inclure le validateur de base, nous devions faire la même chose. C' est le même principe, l'injection de dépendance. Bon, donc j'espère que ça a éclairci une erreur et si tu n'as pas eu cette erreur, alors je te félicite. Maintenant, une autre chose que nous avons négligée et que nous pouvons aborder savoir est l'inclusion de tous les détails nécessaires pour que toute opération de cartographie réussisse. ce moment, nous avons seulement des mappages pour le similaire, pour demander comme la sarcelle à la liste sont ce sont les seuls le domaine au détail. Donc, bien sûr, nous aurons besoin, une fois que nous effectuerons le mappage, comme dans ce gestionnaire, nous mappons à partir du détail de l'allocation de congé Crée pour laisser les allocations. Cela signifie que nous devons en avoir une représentation à l'intérieur de notre profil cartographique. Ici, j'ai ajouté les mappings supplémentaires, tous ceux pour les demandes de congé que j'aime les regrouper afin qu'ils ne se mélangent pas partout. Et toute l'idée de groupement est un peut probablement juste créer notre raison, notre propre les sections de sorte que vous savez exactement où sont ceux qui sont, ensemble commence ou ville, vous pouvez appeler une telle application grandit. Vous voudrez peut-être faire quelque chose comme ça. D' accord, donc c'est une autre chose que nous devons absolument aborder avant de passer à autre chose. Une des choses dont je veux parler 0 étoiles est notre structure de dossiers. J' avais donc mentionné plusieurs fois que votre structure de dossier peut différer en fonction de votre tempérament ou de votre Outlook ou de votre visuel. Et quatre tiennent ces dossiers doivent être arrangés, non ? J' aime donc penser à voir QRS ou la mise en œuvre de l'hippocampe, nos propres scénarios. Et puis tous les scénarios, nous avons des actifs particuliers qui sont nécessaires. Donc, quand je dis est un scénario, je veux dire, création d'une allocation de congé, c'est un scénario ce qui est nécessaire pour créer et évaluer ? Vous avez besoin de votre gestionnaire de commandes. Vous aurez également besoin de votre objet de commande et vous aurez peut-être besoin d'autres détails. Donc, vous pouvez vouloir créer et inclure simplement, vous pouvez créer un dossier à l'intérieur des allocations de congé qui a peut-être au lieu des fonctionnalités que vous auriez créé l'allocation de congé. Et puis vous avez vos gestionnaires et tous vos actifs à l'intérieur de ce dossier. Ainsi, la structure des dossiers peut différer tant l'organisation est telle que vous pouvez trouver vos ressources quand vous en avez besoin, alors vous êtes sur le bon chemin. Maintenant, pendant que je suis dans la commande Crée leave allocation, une autre chose que vous pourriez considérer, donc vous voyez qu'il y a tellement de considérations, cela n'est pas mis en pierre, n'est-ce pas ? Une autre chose que vous pourriez considérer autre est qu'à l'intérieur de la commande, il est un modèle bien connu de simplement utiliser l'objet de commande pour vos champs pour exécuter les commandes. Au lieu d'avoir un DTO entier à l'intérieur de la commande, vous pouvez réellement mettre les champs du détail à l'intérieur de la commande. Et puis vous validez simplement la commande elle-même, la requête elle-même, l'objet entrant dans le gestionnaire serait juste cet objet. Vous n'auriez pas à dire point de requête, laisser allocation, dto dot ce champ, vous dites juste point de requête ce champ, ce champ, etc. Donc, il y a un certain nombre d'options disponibles pour vous, mais je vais m'en tenir à la détails avec tout ce qui a été dit et fait à titre de conclusion, le noyau ou le projet d'application tel que nous l'avons, contient la fonctionnalité de base de l'application. Donc, vous voyez que tout est abstrait à ce stade. Nous allons passer au module suivant où nous commençons à mettre des citations réelles, de la viande dans les dépôts et toute autre logique applicable. Nous avons regardé comment fonctionne le modèle de médiateur qui favorise le couplage lâche couplé avec le modèle C QRS où nous pouvons savoir exactement quel fichier fait quoi. Et ce gestionnaire va gérer ce comportement, ce scénario. Et nous pouvons nous attendre à cette réponse particulière en raison de ce genre de relation ou de comportement que nous avons mis en place. Nous avons également examiné la mise en page basée sur les fonctionnalités, qui à mon avis vous aide à voir que, d'accord, la fonctionnalité liée aux types de congé, vous pouvez trouver tout à l'intérieur de cela. Et cela pour moi qui aide avec la mise en page. Vous avez peut-être d'autres idées, mais c'est ma recommandation. Et puis nous avons examiné la validation en utilisant l'API Fluent ou la validation fluent. Bon, donc ce sont les choses que nous avons examinées dans ce module. Donc, quand nous reviendrons, nous allons certainement donner un coup de pied et commencer à mettre un peu plus de fonctionnalités. 15. Aperçu des sections: Hé les gars, bienvenue. Dans cette leçon, nous allons démarrer notre module où nous avons mis en place notre couche d'infrastructure que vous vous demandez probablement, d' accord, quelle est la couche d'infrastructure ? Eh bien, un, il va s'asseoir à l'intérieur de ce dossier appelé infrastructure. Et deuxièmement, c'est le projet dans lequel nous allons réellement mettre en œuvre toutes nos obstructions qui ont été définies dans la section principale. Nous allons donc configurer nos contextes de base de données que nous utiliserons Entity Framework Core comme ORM pour communiquer avec notre base de données sous notre application. Mais dans cette couche, vous configurez tout est réglé. En vous enregistrant, nous allons mettre en œuvre les dépôts que nous allons mettre dans la viande réelle, l'application. Alors commençons. Donc, créons deux nouvelles bibliothèques de classes. L' un appelé HR dot DV infrastructure et l' autre appelé HR dot leave management pensée persistance. Connaître le projet de persistance ou couche de persistance, traitera de notre communication avec notre base de données. C' est donc là que notre contexte de base de données ou les bibliothèques EF Core et références, tout cela. Était-ce là au lieu de l'infrastructure, c'est là que nos implémentations vont se poser. Très bien, donc entre ces deux sera implémenter le dépôt. Nous allons mettre en place toutes les implémentations tierces qui sont nécessaires. Et nous allons également mettre en place des services à amorcer dans les services qu'on appelle ça collègues des services AI Sean ou le conteneur d'injection de dépendance pour ASP.Net Core. Rappelez-vous que les bibliothèques doivent être faites. C' est un tonnerre. 2.1. Et vous avez déjà traversé la création tout l'effondrement de la diversité peut suivre les mêmes étapes. Et quand nous reviendrons, nous commencerons par mettre en place différentes couches de noyau de travail ou de persistance. 16. Ajouter du noyau d'entité: Bon, donc on est de retour et on va mettre en place nos projets de persistance. Commençons donc par ajouter une référence à nos projets d'application. Nous avons donc le projet de domaine qui a toutes les entités. Et le projet d'application final a une référence au projet de domaine. Donc, notre projet de persistance va avoir une référence à notre projet d'application démarre afin que nous puissions simplement cliquer sur l'application pour égaler k. et puis c'est une dépendance. Ne pas nous allons aussi passer aux paquets NuGet. Nous allons chercher Entity Framework, mais celui que nous allons obtenir est Entity Framework, Core dot SQL Server. Donc celui-ci, quand il sera descendu, viendra avec toutes les dépendances dont nous avons besoin. Donc, nous pouvons juste aller de l'avant et installer la dernière version stable. Et encore dans vous obtenez, laissez-nous simplement aller de l'avant et rechercher des extensions de configuration et installer Microsoft dot extension n'options point extension de configuration extension. Donc, cela sera utile quand nous allons être assis sur certains de nos trucs. Donc, après avoir fait tout cela, nous pouvons aller de l'avant et créer une nouvelle classe. Et j'ai appelé le mien l'âge, nos contextes BB de gestion de plomb. Donc, créez cette nouvelle classe. Tu peux appeler ça autre chose. Vous pouvez probablement simplement l'appeler gestion des congés, contextes EB ou contextes DVI, c'est bon. Mais il héritera des contextes BB maintenant DVI contextes commentaires pour nous courtoisie de Microsoft dot Entity Framework Core. Nous pouvons donc aller de l'avant et faire cette référence. Et puis nous pouvons rendre notre contexte DB conscient des différentes entités que nous avions définies. Donc, si vous êtes familier avec EF Core, alors vous savez exactement ce que je veux dire. Donc, dans ce dossier, nous avons quelques choses. Nous avons un constructeur où nous initialisons notre contexte DB pour avoir un paramètre de contextes DVI, options de son propre type, et le nom est Options, et nous le transmettons à la base, qui est des contextes DVI . Ensuite, nous avons notre base de données assis par rapport à nos différentes entités. Donc, je peux juste aller de l'avant et inclure les références manquantes pour ceux-ci et tout devrait être tout vert. Ensuite, nous allons remplacer quelques méthodes. Donc, le premier que nous remplissons serait l'équipe de création sur modèle. En fait, il est plus rapide de commencer à taper dessus , puis vous appuyez sur Espace et vous verrez toutes les options. Nous écrasons donc la création de modèle sur. Donc, cette méthode est exécutée chaque fois que la base de données est générée, n'est-ce pas ? Pour qu'on puisse s'asseoir sur certaines règles. Donc la règle que nous allons mettre en place ici pour sûr, au moins, n'est-ce pas ? Non. Si nous voulions voir la base de données, nous pouvons le faire à partir d'ici, mais nous ne sommes pas prêts pour l'ensemencement comme du moins pas encore. Nous voulons appliquer des configurations à partir de l'assemblage. Et puis nous allons dire type de gestion DV, contexte DV. Et je vais dire assemblage de points. D' accord ? Donc c'est tout ce que nous mettons dans notre modèle en créant au moins, n'est-ce pas ? Non. Comme je l'ai dit, si nous voulions ensemencer la base de données avec des configurations spatiales pour les tables, alors nous pourrions toujours à l'intérieur de cette méthode afin qu' ils soient appliqués chaque fois qu'elle est générée dans le modèle de base de données. D' accord, une autre chose que nous voulons remplacer l'estran est notre Sauvegarder les modifications. Quelqu' un à choisir d'enregistrer les modifications avec l'annulation Tolkien comme paramètre. Et je vais équiper ces changements de sauvegarde avec un beau code, un bon code pratique qui va nous permettre de faire un enregistrement d'audit automatiquement. Alors rappelez-vous que nous avions mis en place une entité de base pour chacun de ceux-ci qui est venu automatiquement avec comme un utilisateur créé, sont créés par ou autre, crée une donnée, et cetera. Donc, je vais définir la boucle foreach pour passer par chaque entrée dans les entrées de points de structure de changement. Et nous faisons simplement une entité de domaine basée sur le coût implicite des données. Et je peux juste aller de l'avant et inclure l'instruction using pour cela. Et puis pour chacun, ce que je veux faire est de définir la date, ajouté, date, modifié à tout moment. Donc, je peux toujours voir une fois que vous êtes sur le point de voir un changement, je veux l'entité point d'entrée, le verre de points modifié par nos données de dernière modification, plutôt, nous avons affaire à la date, non ? Non. L' heure. Non. droite. Et puis je suis allé faire une vérification et je vais juste dire si l'état d'entrée est équivalent aux entités, State DOT ajouté, ce qui signifie que c'est des battements en cours d'ajout, c'est un nouvel enregistrement. Ensuite, nous voudrions asseoir le créé à datetime point null. Donc, nous autorisons est notre date créée plutôt, donc nous allons toujours définir le dernier Modifié. Il veut que certaines choses soient changées. Une tension que nous sommes assis l'a modifiée. Mais alors seulement quand il est ajouté à, nous définissons le créé et c'est ce que c'est comme ça. Le code de base le plus basique pour implémenter l'audit que vous pouvez trouver. Encore une fois, cela est automatisé, donc chaque fois que nous appuyons sur Enregistrer les modifications, il fait tout cela. Et puis il a juste causé la base c de g et g est la méthode en arrière-plan. C' est donc tout pour ajouter dans le framework à notre couche de persistance. Quand nous reviendrons, nous commencerons à travailler sur certaines implémentations. 17. Mise en œuvre de couches de persistance: Bienvenue les gars. Dans cette leçon, nous allons implémenter notre couche de persistance. Donc, quand je parle de l'implémentation de la couche de persistance, je fais spécifiquement référence à notre référentiel générique, non ? Donc, nous n'avons que l'abstraction, mais nous n'avons pas de code pour sauvegarder cela. Alors allons-y et faisons-le. Donc, nous ajoutons un nouveau dossier. Et je vais appeler ces dépôts de dossiers. Et puis dans ce dossier, nous allons ajouter une classe qui représentera l'implémentation du référentiel générique par rapport au type T. Cellules dégénérées dans la classe. Comme d'habitude, nous le rendons public, et ensuite nous le rendons par rapport à t0. Et puis il hérite du référentiel générique IJ, qui est également relatif à T où T classe deux-points. D' accord, allez-y et incluez les références manquantes, puis permettez-lui d'implémenter l'interface. Alors je vais écrire le devis et ensuite on le fera ensemble. Maintenant, avant de continuer, j'ai réalisé que j'ai dépassé Zillow, Suisse pour copier et coller le téléphone. On est assis sur l'interface. Donc, comme certains dessins animés pour la mise à jour et la suppression, nous pouvons supprimer le T, non ? Nous ne parlons pas de retourner quoi que ce soit lorsque nous faisons une mise à jour ou une suppression. Donc, ces deux-là ne devraient être que des tâches, sorte que vous pouvez aller de l'avant et faire ce changement. Et cela, bien sûr, affectera notre mise en œuvre. Donc, notre référentiel générique commence par un constructeur qui accepte un paramètre de type contextes DVI gestion des congés. Bien sûr, le contexte DB est essentiellement notre connexion à la base de données. Nous en avons donc besoin dans notre dépôt pour effectuer nos opérations ou ajouter une méthode. Il commence par notre pondération d'un appel de contextes DB pour ajouter un puits où il passe juste dans l'entité EF Core est assez intelligent pour déduire quelle entité est passée par rapport à tous les ensembles DB qui ont été définis dans notre contexte DV. Et par db assis, je veux dire ça. Donc, quel que soit le type de données qui est transmis, il saura si c'est l'un des ensembles de bases de données qui est reconnu. Donc, nous allons juste aller de l'avant et ajouter l'entité, enregistrer les modifications sur le nouveau retour, cette entité. Pour la suppression, une fois de plus, supprimez le paramètre type de la tâche. Mais tout ce qu'il va faire est regarder et le contexte DB, trouver l'ensemble relatif à t0 qu'il est donné et il va supprimer cette entité de ce sit. Très bien, puis après cela, il enregistre les changements. Donc, vous remarquerez que rien ne se passe vraiment jusqu'à ce que vous voyez si les changements se produisent. C' est ce commit final dans la base de données. Nous avons la méthode existe où nous obtenons un ID pour notre dossier. Et ce que je vais faire est de chercher l'entité en utilisant la méthode GET locale, que nous examinerons dans quelques-uns. Et puis nous revenons que ce n'est pas égal à null. Donc, quand ce n'est pas égal à null, alors oui, il existe sinon c'est faux. Bien sûr, dans le ghetto, ce que nous faisons, c'est que nous retournons un appel non pondéré au contexte DB dot set t. Donc, une fois de plus, nous examinons un ensemble spécifique et nous trouvons l'enregistrement relatif à l'ID. D' accord, pour notre j'ai lu sur la liste t, qui est obtient tout ce qui est ce qu'il revient. Tout ce que nous faisons est de regarder dans l'ensemble et nous faisons une liste deux asynchrone sur cet ensemble. Donc, nous obtenons juste tout de cet ensemble et l'envoyons à la liste et retournons cela dans notre guitare pour les mises à jour, ce que nous faisons est de définir l'entrée dans l'état pour le modifier afin que l'EF Core, nous allons commencer à le suivre et ensuite, nous allons de l'avant et sauvegardons les changements. Donc, c'est à peu près tout pour notre implémentation pour le référentiel générique. Bon, maintenant que notre référentiel générique est implémenté, nous devons maintenant implémenter nos référentiels spécifiques pour pouvoir aller de l'avant et les ajouter. Donc, à partir du référentiel de type feuille, nous allons regarder à quoi ressemble l'implémentation. J' ai donc créé le référentiel de type feuille. Il s'agit d'une classe publique appelée référentiel de type feuille, héritant de l'implémentation du référentiel générique par rapport au type feuille. Très bien, et puis nous allons de l'avant et disons que c' est aussi d'hériter du dépôt de type elif. Donc, les lignes rouges indiquent quelques choses ici. Premièrement, nous devons apporter l'espace de noms manquant à, nous devons mettre dans l'implémentation réelle ceci, ce cygne, à droite, cette interface n'avait pas de méthodes supplémentaires, donc c'est bien pour null. Et puis cela se plaint parce que nous devons avoir le contexte DB présent. Pour le référentiel générique. Alors rappelez-vous que lorsque vous héritez de quelque chose qui a une dépendance, vous devez également mettre cette dépendance dans l'héritier. C' est donc une solution simple. Nous obtenons juste le constructeur et ensuite faisons notre injection de dépendance. Et c'est pour le contexte DB, bien sûr, mais alors nous devons aussi laisser la basse noter qu'il peut également utiliser ce contexte DB qui est injecté. Et c'est tout pour le dépôt de type feuille. Donc, le contrat n'avait pas de méthodes supplémentaires. n'y a rien de plus à mettre en œuvre. Et parce qu'il hérite du référentiel générique par rapport au type de feuille. En utilisant cette implémentation, nous avons accès à toutes les méthodes qui ont été définies ici. Maintenant, regardons quelques plus compliquées. Alors regardons les demandes de congé. Laisser le référentiel de requêtes sans cela semblent dépendantes exigences. Nous devons donc nous assurer que nous injectons le contexte DB possible aux abeilles. Allez-y et incluez les espaces de noms manquants, puis nous devons implémenter l'interface. Donc, cette interface avait en fait quelques méthodes, en plus. Nous avons eu le statut d'approbation de changement, nous avons eu des demandes de congé avec des détails, et nous en avons ajouté une autre pour obtenir des demandes de congé avec des détails par ID. Peu de choses se passent dans cette affaire. Donc, les implémentations ici seront différentes des implémentations génériques car elles sont spécifiques à certaines opérations liées aux demandes de congé. Donc, les implémentations sont les suivantes. Pour la demande d'approbation de modification, nous obtenons un paramètre de demandes de congé et de statut d'approbation. Nous définissons l'état approuvé de la quête de levier à n'importe quelle valeur elle est venue et le paramètre. Et puis nous définissons les contextes db et non les demandes de congé d'entrée. Donc, vous voyez que cette fois n'est pas une entité, ce n'est pas générique. C' est très spécifique parce que nous sommes dans ce dépôt spécifique. Donc, nous définissons l'état d'entrée ou l'état d'entité, modifions pour cette demande de congé, puis nous enregistrons les modifications afin qu'il commence à le suivre et puis verra si le changement en conséquence. Maintenant, vous voyez qu'il s'agit d'une opération très spécifique par opposition à la mise à jour générale où nous ne pouvons pas tenir compte de ce qui est modifié. Donc, nous avons juste mis tout pour le modifier et le laisser camionner. Encore une fois, ce ne sont que des idées parce que vos règles d'entreprise sont peut-être beaucoup plus compliquées ou que l' opération que vous devez effectuer à l'intérieur du dépôt est beaucoup plus compliquée que de se contenter d'un seul champ. Donc, vous pouvez avoir besoin d'une fonction spécialisée pour cela. Maintenant, pour les demandes de congé get avec la méthode details, tout ce que nous faisons vraiment est d'interroger la table des demandes de congé. Donc var demandes de congé est égal à attendre les contextes DVI pas laisser les demandes. Et puis nous incluons le type de feuille. Donc, nous ne voulons pas nécessairement toujours inclure le type de feuille. On ne sait pas dans quelles circonstances on peut en avoir besoin. Donc, nous avons celui-ci relatif aux détails qui sont nécessaires à côté de l'enregistrement pour le générique régulier qui n'inclut pas est juste de retourner des données de la table. Donc, cette fois, nous incluons des détails. Il pourrait s'agir de ce type de feuille, il pourrait y avoir plus d'inclusions que vous pourriez avoir besoin. Et puis nous les poussons tous sur les listes. Et puis nous revenons pour la dernière où nous recevons seulement une demande de congé avec des détails basés sur la carte d'identité. Nous faisons quelque chose de similaire, sauf que nous faisons l'inclusion et ensuite dx dans le premier ou par défaut étaient l'ID de file d'attente correspond à l'ID Boston. Maintenant, nous faisons d'abord notre défaut ici par opposition à la recherche, un puits que nous avons fait dans le dépôt générique en raison de la façon dont ces méthodes fonctionnent, vous ne pouvez pas faire une inclusion lorsque vous faites une recherche, cela ne fonctionne tout simplement pas. Donc, quand vous devez faire une inclusion, vous devez utiliser le premier ou le single ou par défaut, celui avec lequel vous vous sentez le plus à l'aise. Et puis nous retournons la demande de congé qui a été trouvée. Donc, nous pouvons sauter pour quitter l'allocation et nous voyons que c'est une implémentation relativement similaire. Nous avons des méthodes similaires. Donc, j'ai mis ces méthodes ici juste pour souligner que vous pouvez avoir des méthodes personnalisées dans ces dépôts. Vous ne pouvez pas nécessairement en avoir besoin dans votre application, utilisez-les comme vous en avez besoin. Je conserve également cette ligne rouge parce que dans le cas où vous entrez dans tout ce dont vous avez besoin est d'inclure cette référence, ce EF Core et alors c'est bon. D' accord, donc il nous reste une activité majeure et on en a fini avec la couche de persistance. Et c'est de configurer la classe d'enregistrement pour la persistance. Donc juste des services d'application locaux, distribution Hadar. La persistance en aura certainement besoin. Alors allez-y et ajoutez cette nouvelle classe. J' appelle les services persistants ou la distribution. Ce devrait être une classe statique publique. Et puis dans ce que nous aurons. Une méthode qui renvoie je sert de collection et nous l'appelons configurer les services persistants. Donc, bien sûr, comme d'habitude, allez de l'avant et installez n'importe quelle autre instruction d'utilisation qui sont nécessaires. Et puis à l'intérieur de cette méthode, ce que nous allons faire est d'écrire du code pour errer. Vous stockez le contexte DB, et ajoutez notre outil de référentiels, la collection de services. Et c'est cette méthode complète de, bien sûr, ce que les lignes rouges parce que toujours l'amour de vous montrer ce que Redlands me existe et comment vous pouvez les résoudre. Mais c'est à quoi cette méthode doit ressembler. Ainsi, vous pouvez aller de l'avant et commencer à inclure dans les instructions using qui sont manquantes. Donc, tout d'abord, nous avons le contexte services.js ADB où nous passons dans le type qui est les contextes db quittent le contexte DB de gestion et les options point SQL Server. Alors rappelez-vous les contextes DB que nous lui avons dit que nous devons, dans le contexte DB sur la création du modèle, nous lui avons dit que ce serait désolé, dans le constructeur, n' est-ce pas ? Nous avons pris des options de contextes BB. Donc, ces options proviennent vraiment de toutes les options qui sont définies ici, une distribution. Donc, nous allons de l'avant et utilisons EF Core pour l'utilisation de la configuration SQL Server arrive parce que nous allons passer la configuration de l' application cliente qui implémente ce qu'on appelle le bootstrapper des services. Et donc nous aurons certainement besoin de passer. Ce n'est pas un conflit. La configuration I doit être la configuration des extensions Microsoft point, pas l'automne supérieur. Alors soyez très prudent avec celui-là. Donc, nous pouvons aller de l'avant et inclure cet espace de noms. Et puis pour les dépositaires, nous avons ajouté portée. Donc, nous ajoutons qu'ils sont tous étendus. Mais alors pour le générique, notez que nous ajoutons le type de référentiel générique ij avec nos crochets d'angle type virgule du référentiel générique, crochets d'angle. Mais alors tous les autres sont l'interface de l'homologue d'implémentation sans crochets d'angle. Mais je vais aller de l'avant et ajouter toutes les références manquantes ici. Et avec ça, et oh, je suis désolé, j'ai écrit le code à tort ici pour celui-ci, ajouter portée est parenthèses ouvertes et pas de crochets d'angle pour l'annonce scolarisée. D' accord, alors laisse-moi juste le chariot pour que tu puisses voir. On y va. Donc c'est parenthèse portée, type de référentiel générique oeil avec crochets d'angle, type virgule du référentiel générique avec des crochets d'angle. Je ne le fais pas encore une fois, ceux-ci sont entre parenthèses tandis que les autres auront les crochets entourant l'interface et l'appairage d'implémentation. Après tout cela, bien sûr, nous rendons les services. Donc, juste pour revenir un peu à ce que sera cette chaîne de connexion, nous n'avons pas encore de paramètres d'application, donc cela va vivre dans les paramètres de l'application qui appellera cette méthode. Et donc, quand il appelle configurer les services persistants, il est attendu qu'il soit possible avec cet objet de configuration, qui donnera ensuite accès aux paramètres de l'application. Et nous serons en mesure d'obtenir cette chaîne de connexion à possible Quel est notre contexte DB ? C' est donc ce que fait toute cette ligne ou toute cette section. Maintenant, le but de la force en utilisant portée, il ya trois modèles d'injection disponibles pour nous. Nous avons à l'école pour avoir singleton et ajouter transitoire. Singleton signifie à une instance de ce service existera, jeter l'application entière. Cela peut être dangereux en fonction de la nature du service. Et cela pourrait être utile, par exemple, peut-être un service de journalisation qui pourrait être un dans le capteur ou l'application entière. Vous ne voulez probablement pas quelque chose comme ça pour vos transactions de base de données. Parce que lorsque vous avez plusieurs transactions de base de données, vous voulez que celles-ci se produisent en silos. C' est pourquoi il utiliserait scoped, ce qui signifie que pour toute la vie de notre quête, je demande quelque chose. J' écris dans la base de données, j'appelle votre service pour la durée de vie de cette opération. Ensuite, ajouter scoped appellera et la connexion à la base de données ou à une instance de ce référentiel de type feuille ou de l'un de ces référentiels, comme il est appelé lors de notre demande. Une fois que ma demande est terminée, elle ne sera plus en mémoire. Cela réduit les chances de conflit. Et puis ajouter transitoire signifie que chaque fois, il fera toujours quelque chose de nouveau, ce qui signifie que vous pourriez finir avec plus que ce dont vous avez vraiment besoin pour terminer une demande, ce qui pourrait également conduire à un conflit. Donc, une fois de plus, vous pouvez les utiliser avec parcimonie, mais dans ce contexte, ajouter portée est celle que nous voulons pour nos opérations liées à la base de données. Maintenant que tout cela est fait, faisons un projet de loi rapide pour nous assurer que nous sommes sur la bonne voie, que nous n'avons pas d'erreurs et que nous avons réussi à construire nos projets. Donc, quand nous reviendrons, nous commencerons à mettre en œuvre ou l'infrastructure. 18. Ajouter des projets d'infrastructure (Service e-mail): Bienvenue les gars. Dans cette leçon, nous allons mettre en place nos projets d'infrastructure maintenant notre projet d'infrastructure est à peu près là où se dérouleront les implémentations de tous nos services tiers. Dans cette leçon, nous allons implémenter un service de messagerie électronique avec l'aide de SendGrid. Et nous allons le mettre en place dans le projet d'infrastructure. Maintenant, la première chose que nous devons faire est de mettre en place une abstraction pour les expéditeurs de courrier électronique, même manière que nous avions des obstructions pour nos référentiels. Nous avons une obstruction à notre contrat pour le service de messagerie électronique. Maintenant, sur cette note, je regardais en arrière et je me rends compte que la structure de dossier ici n'est pas très intuitive pour le long terme. Donc, je suis parti pour refactoriser ici parce que j'ai de la persistance alors que j'ai des contrats. Mais les contrats sont le terme le plus universel car alors vous avez des contrats pour la persistance dans leurs contrats pour la couche d'infrastructure et ainsi de suite. Donc je vais devoir retourner. Ces dossiers sont détenus, ce qui ne sera pas trop difficile sur ce qu'on appelle les contrats de dossier de persistance. Et puis je vais appeler la persistance des contrats. Maintenant, cela va avoir un effet d'ondulation pour tout l'espace de noms est parce que nous voulons que nos espaces de noms soient complètement représentatifs de ce qu'ils sont vraiment. Donc nous avons des contrats à points de persistance, non, nous devrons changer ça en contrats pensant persistance. Et puis cela va manquer avec toutes les références d'espace de noms. Je suis désolé, c'est terrible. Mais c'est un facteur qui est certainement nécessaire pour nous ayons une structure de dossiers intuitive, non ? Donc, après avoir fait tout cela, si nous faisons une construction, il indiquera tous les espaces de noms de bout qui ont été référencés tout au long de notre projet. Donc, vous savez, un moyen rapide d'aller de l'avant et de les réparer. Mais les espaces de noms seraient de rechercher contrats de points de persistance partout, puis de le remplacer par un système de points br de contrats. Donc, vous pouvez juste le faire et méticuleusement passer par et remplacer chaque terme me fait sûr que vous ne remplacez rien qui pourrait être important. Et une fois que vous avez épuisé cette recherche, vous pouvez aller de l'avant et faire une autre facture juste pour vous assurer que vous n'avez plus d'erreurs de construction. Et une fois que cela sera fait, je vais fermer toutes les baignoires et qui ont été ouvertes dans cette opération et ensuite on pourra y retourner. Donc, dans les contrats, nous voulons un nouveau dossier, notre appelant cette infrastructure unique. Et puis à l'intérieur de ce dossier, nous allons ajouter un nouveau contrat ou interface. Et je l'appelle je l'expéditeur e-mail, sais que je l'expéditeur e-mail va être interface publique avec une méthode qui va être appelée envoyer e-mail. Et il faudra un paramètre de type e-mail appelé email. Maintenant, nous devons définir à quoi ressemble cet e-mail. Donc je vais créer un autre dossier pour les modèles, non ? Laissez-moi juste ajouter ce dossier. On appelle ça des modèles. Et puis dans le dossier de ce modèle, nous ajoutons une nouvelle classe que nous appelons e-mail. Donc, ce sera notre modèle, notre modèle pour ce à quoi devrait ressembler n'importe quel e-mail. Et puis cet e-mail aura les propriétés typiques de tout e-mail que pour le sujet et le corps, toutes les propriétés de chaîne. Donc, maintenant que nous avons ce modèle défini, nous pouvons aller de l'avant et ajouter l'instruction using et faire le tri. Avant de passer à nos définitions de modèle, nous avons un autre modèle dont nous avons besoin, et celui-ci sera pour les paramètres de messagerie. Très bien, donc il va arroser les propriétés d' une clé API à partir de l'adresse et du nom de départ, qui sont tous de la chaîne. Maintenant que nous avons quelques choses fraîches avec notre expéditeur de courrier électronique, vous vous demandez probablement pourquoi ai-je besoin d'e-mail ? Alors le met en contexte parce que nous venons de commencer à construire le service de messagerie électronique sans contextes réels. Lorsque quelqu'un demande pour feuille ou que son statut d'approbation change quelque chose comme ça, vous voudrez lui avertir que cette action a eu lieu. Aucune action bizarre n'a lieu bien par rapport aux fonctionnalités, nous avons nos gestionnaires. Donc, lorsque vous créez une nouvelle allocation en direct, accord, peut-être que vous n'avez pas besoin d'envoyer un e-mail, mais alors une demande de congé justifierait l' envoi d'un e-mail à chaque fois qu'un est créé ou qu'un autre est mis à jour. Très bien, alors regardons le gestionnaire de demande de congé Créer où nous pouvons simplement injecter ou je e-mail expéditeur. Et je vais le faire en utilisant l'IntelliSense. Rapidement, initialisez le champ. Et puis compte tenu de notre convention de nommage, je vais juste renommer ceci en utilisant le trait de soulignement dans notre gestionnaire après que tout a réussi, avant de revenir et de tuer toute l'opération. Donc, le gestionnaire va toujours sur cette ligne. Donc apparaîtra un objet e-mail, puis essayez de l'envoyer. Et nous allons faire face à une exception. Alors regardons ça lentement. Donc var email est égal à un nouvel e-mail, qui est notre modèle que nous venons de définir. Nous avons les deux, je viens de mettre dans un e-mail fictif là quand nous arrivons à l'ensemble de l'authentification de l'utilisateur et d'avoir les utilisateurs réels soumettre. Et nous allons voir comment nous obtenons les adresses e-mail réelles. On a le corps. Et le corps de cet e-mail dit juste votre demande de congé pour et je suis juste mettre en utilisant l'interpolation pour mettre dans le contenu début besoin de se terminer. Il a été soumis avec succès et le sujet est les demandes de congé soumises. Si vous le souhaitez, vous pouvez ajuster davantage la date en mettant les deux-points D. Donc, traditionnellement, vous diriez ToString, puis spécifiez le format. Mais quand nous utilisons l'interpolation dans cette version de C Sharp, nous pouvons simplement mettre deux points et le formatage, eh bien, la chaîne de formatage à la fin de celui-ci. Et ça va s'en occuper pour nous. Donc, D vous donnerait le nom long. Lundi, juin cette date, cette année. D' accord. Donc, c'est tout pour ou gestionnaire savoir que toute notre application connaît l'expéditeur de courrier électronique oculaire, nous devons travailler sur la mise en œuvre de sorte que la mise en œuvre de cela vivra dans notre projet d'infrastructure. Donc, pour commencer, cela crée un nouveau dossier à l'intérieur du projet d'infrastructure appelé repas. Et puis créez une classe là appelée expéditeur de courrier électronique. Et puis cette classe, qui bien sûr ce sont le public héritera de i e expéditeur de courrier électronique. Donc, nous pouvons aller de l'avant et vous réalisez qu'il a besoin d'une référence à l'application. Nous devons donc aller de l'avant et ajouter cela. Et avec cette référence à cela, nous pouvons aller de l'avant et mettre en œuvre l'interface. Donc, avant d'aller plus loin, nous devons sauter sur le nouveau Git. Et nous avons besoin de quelques paquets. Swan est les mêmes extensions de configuration que nous aurions utilisées à partir des autres projets. Donc, un moyen rapide de gérer des projets communs est d'aller à cette solution et de dire des paquets NuGet gérés pour la solution, non ? Nous avons donc déjà quelques paquets installés dans certains projets dont nous avons besoin dans d'autres comme celui-ci, les extensions de configuration. Donc, je peux cliquer dessus et je vois que c'est déjà dans les projets de persistance, mais je voulais dans le projet d'infrastructure aussi je peux le cocher, cliquez sur Installer. Et cela peut réduire le temps que vous passez sur NuGet à essayer de trouver le même paquet encore et encore. Maintenant, le prochain paquet qui m'intéresse est SendGrid. Donc, vous pouvez sauter sur les bros et juste marcher dans SendGrid, et ensuite vous pouvez obtenir les dernières versions. Vous voulez donc cliquer dessus, assurez-vous que vous prenez le bon projet, puis cliquez sur Installer. Donc, après l'installation, nous allons commencer à câbler cette classe. Donc, une chose que je vais faire est de configurer un champ privé de paramètres de messagerie de type et sur ses paramètres de soulignement de messagerie en lecture seule. Mais alors je l'initialise dans le constructeur avec ce paramètre i options Email Settings. Maintenant, permettez-moi d'expliquer ce que c'est similaire à la façon dont nous avions configuré notre base de données. Et nous avons dit que nous avons un fichier de paramètres d'application que nous fournirons la chaîne de connexion le moment venu. C' est de la même façon que nous pouvons réellement passer. Les options sont des morceaux d'options sont des configurations à partir de l' ensemble du fichier de paramètres de l'application, qui peut ensuite être désérialisé en un objet entier pour nous. Donc, ce que nous faisons vous voir obtenir de la, à partir des options sont les paramètres de l'application, les paramètres de messagerie, équivalent JSON, et l'envoyer comme ce paramètre. Et puis nous pouvons juste l'injecter et ensuite l'avoir comme variable locale, notre domaine dans notre classe. Donc, cette injection de dépendance est tellement cool car elle rend tout si lâchement couplé et malléable. Continuons donc à configurer nos méthodes d'envoi de courrier électronique. Donc, la première ligne que nous allons avoir est un client qui va appeler ou initialiser une revendication SendGrid. Donc, nous allons juste aller de l'avant et ajouter en utilisant des instructions qui sont manquantes. Ensuite, après avoir obtenu le client, nous allons devoir récupérer tout le sujet et les deux et le corps de l'e-mail de notre objet e-mail. Mais les deux et le de surtout besoin d'être un type de données spécial. Donc, je vais dire que var 2 est égal à la nouvelle adresse e-mail. Et l'adresse e-mail ici vient de la grille du péché. Donc nouvelle adresse e-mail. Et puis on va devoir passer dans le tube de courrier électronique. Et puis on va devoir faire la même chose pour le départ. Donc, je vais dire var de est égal à la nouvelle adresse e-mail. Et dans celui-ci, nous allons en quelque sorte vous mettre un peu plus dans la définition où je vais voir l'e-mail vient du point de paramètres e-mail de l'adresse. Et puis le nom serait le point des paramètres e-mail du nom. D' accord. Nous avons donc le de et le à défini. Et après avoir fait tout ça, nous devons voir. Le message est égal à l'aide masculine. Donc Male Helper est, ça va être une classe statique qui nous est donnée par grille de péché qui nous permet de créer un seul e-mail. On y va. Et vous voyez que vous avez différentes options pour plusieurs destinataires et plusieurs e-mails. Plusieurs destinataires faisaient simplement un seul e-mail dans cette situation. Mais vous pouvez voir que peut-être vous avez envoyé un e-mail, envoyer un e-mail à plusieurs envoyer un e-mail avec une pièce jointe, et cetera. Ainsi, vous pouvez définir différentes méthodes à l'intérieur de l'expéditeur E e-mail. Tu n'es pas confiné à celui que nous faisons. D' accord ? Donc, créez un seul e-mail. Et puis nous allons devoir remplir cet ancien selon QUI ils l'ont déclaré dans le, dans les paramètres pour le constructeur. Donc le Fromm vient en premier. Et puis nous disons aussi, nous les avons. Et puis le sujet, je peux voir l'email beaucoup sujet ici. Et le texte brut serait le corps de l'e-mail. Et vous pouvez voir qu'ils ont le contenu en texte brut par rapport au contenu HTML. Donc, en fonction de la façon dont vous encodez votre e-mail, vous pourriez rassembler cet e-mail en conséquence, n'est-ce pas ? Mais pour l'instant, je vais juste dire le corps du point d'e-mail pour ces deux paramètres. Donc maintenant que nous avons l'objet de message formulé, je vais dire que la réponse var est égale aux clients envoyer des e-mails. C' est là que nous allons envoyer le message que nous venons de créer. Bien sûr, on a cette ligne rouge parce qu'on doit être un évier. Et une fois que cela est fait, nous n'avons pas besoin de retourner un booléen basé sur la réponse. Je peux juste dire retourner si le code d'état de la réponse pensée est équivalent à et je peux juste dire system.in c'est le code d'état HTTP. D'accord. Et je crois que SendGrid répond également à quelqu'un accepté de faire les deux, certains revenant. Je reviens juste. C' est correct ou accepté. Donc, ce sera le cas si c'est l'un d'eux est vrai. Si ce n'est ni l'un ni l'autre, alors c'est faux et ils sauront si l'e-mail a réussi ou non. Mais tout le point de ceci, encore une fois, je retourne à notre création Tumblr et la façon dont nous l'avons enveloppé dans une capture d'essai, l'API qui appelle ce gestionnaire ou n'importe quel code appelle ce gestionnaire ne devrait pas être interrompue si tout le reste. Donc, c'est la partie la plus importante de créer les demandes de congé si les champs e-mail, cela ne signifie pas qu'il devrait planter le programme. Donc, c'est pourquoi nous attrapons l'exception, mais nous ne faisons rien pour le jeter dit sont à travers toute l'application. Maintenant, pour couronner le tout, nous allons avoir un fichier d'enregistrement des services d'infrastructure, comme pour tous les autres projets antérieurs. Nous avons donc ajouté la classe d'enregistrement des services d'infrastructure à ces projets d'infrastructure. Et puis nous avons la même forme que toutes les autres classes de distribution ont eu. Encore une fois, la configuration I est injectée. Et le type que nous sommes, l'espace de noms dont nous avons besoin est la configuration des extensions Microsoft, pas en haut de l'automne et je vais le faire à chaque fois parce qu'il a attrapé plus d'un, désolé. Nous allons donc voir les services dot configurer les paramètres de messagerie. Donc, tout cela est l'étude que nous voulons paramètres e-mail. Je vais juste amener celui-ci à B par rapport à un serveur de configuration MouseY paramètres de emails lorsque nous faisons les options de point, nous voyons me donner un morceau de la configuration qui ressemble à l'objet paramètres EMEA. Eh bien, ce que nous allons vraiment voir, c'est la section des points de configuration. Et il va regarder dans les paramètres de l'application pour notre section avec le nom. Nous appellerons les paramètres e-mail le moment venu. Donc, de cette façon, il saura que nous allons formuler cette section pour ressembler à ce que nous attendons de la classe à ressembler. Donc, il sera juste automatiquement sérialisé dans cette classe codée dur sont fortement typés verre plutôt. Prochain arrêt, nous allons voir les services qui ajoutent transitoires. Souvenez-vous maintenant que je parlais des différents modèles. Nous l'avons fait. Singleton, sculpter et transitoire. Donc transitoire signifie que chaque fois que je suis appelé, je vais être une toute nouvelle instance. Donc, nous voyons que chaque fois que je l'expéditeur e-mail est appelé, donnez-moi une toute nouvelle instance de la, de la classe expéditeur e-mail. D' accord, alors allez-y et incluez les références manquantes. Et puis on peut clore celui-ci et ensuite on retourne les services. Donc c'est tout pour nous assis sur notre infrastructure, au moins c'est un niveau très basique. Encore une fois, tous les contrats que nous devrons définir pour une opération tierce seront définis dans notre application, mais mis en œuvre dans notre infrastructure. 19. Créer et configurer et configurer l'application: Bienvenue les gars. Dans cette leçon, nous allons mettre en place nos projets API. Nous avons donc déjà la base sous la forme de l'infrastructure, projets de persistance ou de domaine et de nos projets d'application. Le fait est que ceux-ci évolueront avec votre application. Donc, ces couches sont ces projets. Ils ne sont pas mis dans la pierre, mais nous avons au moins jeté les bases pour construire une API au-dessus de celle-ci qui sera en fait responsable des informations toxiques entre toutes les applications clientes et ces couches pour nous. Commençons donc à mettre en place ces projets API. Nous allons le placer dans notre dossier appelé API. Nous allons à Ajouter un nouveau projet, le trouver facilement, peut simplement rechercher dans la liste pour l'API. Et nous utilisons le modèle de projet d'API C-Sharp, et nous appelons cette API point de gestion des congés de points RH. Allez-y et appuyez sur Next, et nous utilisons dotnet cinq sont la dernière version parce que .net est très rétrocompatible. Donc, la plupart, sinon tout ce que nous faisons ce cours sera compatible avec les futures versions de dotnet et nous allons continuer avec les paramètres et créer. Maintenant, ce projet API est assez nu. Il nous donne un exemple de code sous la forme de ce contrôleur de prévisions météorologiques, dont nous n'aurons pas nécessairement besoin. Avant d'aller de l'avant, ajoutons les dépendances que ce projet API aura. Et ces dépendances incluent notre projet d'application ou projet d'infrastructure et ou projet de persistance. peu près l'un des projets dans lesquels nous mettrions en place ces méthodes de services de registre. Ce seront des dépendances pour l'API car l'API doit être en mesure d'enregistrer ces services dans sa base de code. Donc, nous pouvons simplement aller de l'avant et ajouter ces références de projet. Et une fois que nous avons fait cela, nous pouvons continuer notre configuration. Donc, lorsque nous parlons de création et de configuration, nous avons créé non, nous devons configurer. Donc, en termes aussi des choses qui ont des dépendances sur ce que nous allons être assis dans l'API. Nous parlons des paramètres de l'e-mail. Alors rappelez-vous que dans notre infrastructure, nous aurions fait mention de l'expéditeur de courrier électronique ou aurait implémenté l'expéditeur de messagerie autre et il est en fonction des paramètres de messagerie à venir via les options IA, les paramètres de messagerie, que nous avons déjà va venir de notre fichier de paramètres d'application. Une autre chose que nous devons mettre en place est pour notre couche de persistance. Désolé, je suis juste en train de choisir sauvagement pour la couche de persistance ou DB. Le contexte dépend d'une chaîne de connexion qui viendra une fois de plus de l'API. Donc, notre fichier de paramètres d'application ici, nous aurons des blocs ou des sections qui ont ces définitions. Donc, nous allons travailler sur le premier, et c'est notre chaîne de connexion. Donc, au-dessus de cette définition de journalisation ici, je vais juste appuyer sur Entrée et puis je vais mettre dans ma section de chaînes de connexion. Donc les chaînes de connexion. Et puis il a le même nom que ce que nous aurions mentionné dans la redistribution de la persistance, n'est-ce pas ? Obtenir la chaîne de connexion. Et puis il laisse les chaînes de connexion de gestion. Donc, la chaîne de connexion sait regarder dans l'application settings.js ON chercher des chaînes de connexion, obtenir celle-ci par son nom. Et sa définition ici est que j'utilise le serveur DB local MS SQL, donc vous devez le taper comme vous le voyez sur l'écran ici. Cela est intégré dans Visual Studio. La base de données est égale à, et j'appelle la mienne HR soulignement de la gestion des congés de soulignement DB. Vous pouvez appeler ça quelque chose d'autre si vous le souhaitez. Et à part cela, et chacun est séparé par un point-virgule et alors nous avons la connexion de confiance est égale à vrai point-virgule multiples jeux de résultats actifs est égal à vrai. Donc, c'est votre chaîne de connexion. Maintenant, pour les paramètres de messagerie, nous allons avoir une nouvelle section appelée Paramètres de messagerie, puis nous avons cette clé d'API. Donc, je dois, nous devons aller avec le SendGrid, puis obtient notre clé API suddenness, mettant un détenteur de place pour null. Et puis nous avons le nom de, c'est d'où l'e-mail semblera venir et puis l' adresse de ne sera pas de réponse à leave management.com ou laisser réponse. Pas de réponse, désolé, sur Ahrq.com, quoi que ce soit que vous voulez là-bas. Maintenant, au cas où vous n'êtes pas très familier avec ce qu'est SendGrid. Il s'agit d'un produit à deux niveaux qui nous permet d'accéder sur Paul pour le système d'API de messagerie. Et vous pouvez commencer gratuitement. C' est gratuit jusqu'à un certain point, bien sûr, et vous ne voulez pas en abuser. Mais une fois que vous vous inscrivez, ils vous donneront cette clé API, qui est ce que vous pouvez coller juste là dans les paramètres de messagerie, dans l'application settings.js IN. On pourra le faire plus tard. Bien sûr, je ne veux pas que tu voies ma clé parce que la clé est privée, donc tu veux t'assurer que tu gardes la vie privée avec ça. Donc maintenant que nous avons notre AP settings.js, fichier JSON au moins o équipé avec le minimum quatre ou la distribution de nos services. Passons au startup.js. Donc, ils ne sont pas certains du fichier startup.js. C' est essentiellement le conteneur qui dit que ce sont toutes les dépendances que mon application doit connaître. Et je les rend accessibles par injection de dépendance. D' accord. On parle d'injection de dépendance depuis un moment maintenant. Et chacun de ces fichiers d'enregistrement nous permet essentiellement d'enregistrer ces dépendances dans une application. Donc, ce que nous devons faire est de faire savoir à notre API que ce sont des dépendances que chacun devrait connaître. Donc, quand nous avons parlé de la figuration de l'icône, vous remarquez qu'elle est transmise la startup alors qu'elle est injectée directement dans la startup. Et cela nous permet de passer cet objet de configuration dans d'autres parties de notre redistribution. Donc, nous l'aurions vu dans l'infrastructure si je ne me trompe pas, là nous allons. Je configuration a besoin de la configuration et nous en avons besoin pour la persistance aussi. Donc assez de parler, entrons dans l'action. Donc, dans notre méthode de configuration des services, nous voulons inclure ces trois lignes, qui sont la configuration des services d'application, la configuration des services d'infrastructure et la configuration des services persistants, tous que nous connaissons bateau provenant de nos services ou à distance, fichiers de redistribution de services dans les différents projets. Donc voici le fourre-tout. Donc, il va juste aller de l'avant et ajouter toutes les dépendances et les espaces de noms manquants pour chacun d'entre eux. S' il vous plaît noter également que nous devons passer dans ces objets de configuration. Très bien, donc nous l'avons injecté dans le démarrage et ensuite nous pouvons le transmettre afin que lorsque ces méthodes sont appelées dans leurs projets respectifs et qu'elles aient les outils nécessaires pour accéder à ce dont elles ont besoin à partir de notre application paramètres. Une autre chose que nous voulons configurer dans cette API est, ou ce que nous appellerons la politique CORS. Donc, notre politique de cours détermine essentiellement comment l'API permet à d'autres clients d'interagir avec elle. Donc, en ce moment, cette politique est assez ouverte. Où voir les services dot-dot-dot core builder permet n'importe quelle origine, autorise n' importe quelle méthode, autorise n'importe quel en-tête. Ensuite, dans notre méthode configure, nous allons descendre et je vais juste le coller ici entre l' autorisation d' utilisation et les points de terminaison d'utilisation. Et cela est allégé ni qu'il devrait utiliser cette politique tout au long. Maintenant, nous avons fait un bon chemin avec toutes les configurations. Il nous reste encore une étape pour cette leçon, et c'est de générer notre base de données. Donc, nous avons fait toute cette configuration. Nous avons la couche de persistance maintenant nous l'avons branchée. Non, nous passons en fait sur la chaîne de connexion. Donc maintenant, il sait que quand il existe, sur quel serveur il devrait exister et quel devrait être le nom de la base de données. Alors, obtenons le nôtre pour venir configurer notre base de données. Nous devons donc exécuter des migrations. Et je fais juste une construction rapide qui a été couronnée de succès. Donc, avant de passer aux migrations, nous devons avoir accès à notre outil EF Core. Alors allez dans Package Manager, tout ça. Il recherchera des outils. Et bien sûr, Microsoft dot Entity Framework outils Core est le deuxième dans les résultats de recherche. Donc, je vais aller de l'avant et installer cela dans mon projet API. Et avec cette configuration, je vais également définir le projet API comme mes projets de démarrage. Donc, je peux le faire à partir de cette liste déroulante, Beaucoup en haut, ou je pourrais cliquer dessus et dire définir comme projet de démarrage. Maintenant, avec tout cela fait, nous pouvons passer à notre console Package Manager. Donc, si vous ne l'avez pas dans vos éléments de menu ou comme une barre d'outils comme je le fais, alors vous pouvez toujours aller dans Outils, aller dans le gestionnaire de paquets NuGet, et vous verrez la console répertoriée là. Dans cette console Package Manager, nous allons ajouter la migration SHE et nous pouvons lui donner un nom pour que je puisse l'appeler migration initiale de création, quelque chose pour indiquer que c'était la première, non ? Une autre chose que vous voudriez faire est de modifier les projets par défaut. Donc, le projet par défaut doit à peu près être le même projet où votre contexte DB est un paramètre qui doit être le projet de persistance. Et pour les contextes, rappelez-vous que dans notre projet de persistance ou un contextes DB, nous avions dit que le modèle dans la création non-modèle, nous avons dit appliquer des configurations de l'assemblage et partout où c'est cet assemblage, C'est à peu près ce que cette ligne spécifiait. Nous avons donc besoin de notre répertoire de migrations ici. Alors assurez-vous que c'est réglé. Si vous ne le faites pas, vous aurez une mauvaise erreur. Un bateau qu'il est mis sur le mauvais projet cible. Donc, quand nous allons de l'avant et ajouter que la migration va faire sa magie. Et puis nous obtenons ce fichier de migration, qui nous donne toutes ces tables que nous avions créées initialement. Alors visite rapide de notre fichier de migration, si vous n'êtes pas si familier, nous avons une méthode op et une méthode add-on. L' autre méthode a essentiellement du code et si vous venez de le lire en tant que développeur C-Sharp, en tant que développeur SQL, vous voyez ce qu'il fait. Il crée une table avec le nom, avec ces colonnes, avec tous ces correctifs sur chaque colonne. D' accord ? Et puis le bas signifie que si vous annulez cette migration, sont les choses qui feront l'objet. Il laissera tomber les mêmes tables. Donc pour tout ce qu'il y a des adultes. Maintenant que nous avons notre fichier de migration existant, nous pouvons aller de l'avant et mettre à jour la base de données. Donc, la base de données dit fondamentalement si elle n'existe pas, sont créés. S' il existe, j'appliquerai les modifications. Il n'existait pas. Donc, il a créé juste de la neige. Et pour vérifier et vérifier qu'il est créé, nous pouvons aller à l'Explorateur d'objets SQL Server, développer et développer la barre oblique DB locale et Mme Hill DB locale fait le serveur que nous avons indiqué. Et si vous utilisez un serveur différent, vous pouvez passer à ce serveur particulier. Et lorsque nous étendrons, c'est une base, nous verrons notre dB de gestion DV DSE. Et si nous développons les tables, nous verrons nos tables qui ont été définies en conséquence. On n'a vu aucun danger. Toutes les tables sont vides. Plus tard, lorsque nous commençons à construire notre propre application, nous pouvons aller de l'avant et regarder comment les données ISI. Mais pour l'instant, c'est une mission accomplie. 20. Mettre en œuvre des contrôleur API: Dans cette leçon, nous examinerons l'ajout de services de médiateur à notre API. Maintenant, le contexte est que les médias nous permettent de spécifier des comportements dans notre application en fonction d'une réponse sur le type de relation de gestionnaire. L' une des conséquences ou avantages de cela est que nous pouvons expédier une grande partie des opérations lourdes à partir de notre code d'appel, qui dans ce cas sera notre contrôleur. Et nous pouvons l'abstraire à un autre endroit. Donc, le contrôleur sait vraiment juste que je construis une requête et je l'envoie pour être traitée. Donc, pour le contexte, j'ai à l'écran le contrôleur du projet précédent, ce qui est une inspiration pour nous refaire ce système de gestion des besoins. Et là, vous verrez que nous n'avons pas de contrôleurs minces, nous avons de gros contrôleurs. Donc ils sont contrôleurs, vraiment. Ceux exactement ce que le nom suggère, contrôle le flux et tout ce que l'application fait. Il répond donc aux demandes de données d'un utilisateur, et cetera. Maintenant, dans l'ancien projet, nous avions ce qu'on appelle des contrôleurs de graisse, ou nous faisons tout à l'intérieur du contrôleur. Encore une fois, cela fonctionne. Donc ce n'est pas que ça ne marchera pas. Si c'est fait, nous travaillerons. Mais est-ce le Holman Tenable le mieux pratiqué ? Parce que si je voulais vérifier que ces opérations sont effectuées avec succès, j'aurais beaucoup de difficulté à tester l' unité de cette façon parce que ce n'est pas dans une union, c'est assez à l'intérieur de notre contrôleur. Cela augmente donc mon incapacité à tester les parties de l'application pour s'assurer qu'elles fonctionnent correctement. Et cela augmente mon temps consacré au dépannage, aux tests de régression et à toutes ces choses. Ici, il vérifie si quelque chose existe et s'il n'existe pas, il ne retourne pas le téléphone. Et puis il fait le mappage et il fait une recherche, puis il retourne la vue. Lisez Andrew, vous voulez juste le moins de couleurs possible sans logique métier. C' est une forme de logique métier. Nous ne voulons pas vraiment cela dans notre application. Ok, voici une autre situation où nous créons notre disque et nous faisons trop de choses dans cette option. Ce sont donc les choses que nous voulons réduire quand nous parlons d'avoir des contrôleurs minces. Commençons donc par installer le médiateur dans nos projets API. Vous connaissez la perceuse, vous pouvez juste faire un clic droit aller à NuGet. Nous avons cherché médiateur et aller de l'avant et l'installer. Une fois que vous avez terminé ces étapes. Une fois que vous avez terminé avec cela, continuons et ajoutons un nouveau contrôleur à notre projet. C' est un contrôleur MVC et nous voulons un contrôleur API avec des options de redirection. Nous allons commencer par le plus facile, qui est les types de congé et aller de l'avant et ajouter. Voyons comment les médias peuvent nous aider, n'est-ce pas ? Nous avons donc déjà les bonnes options de base générées pour nous heureusement. Mais alors ce que nous devons faire est d'injecter notre objet médiateur dans notre contrôleur. Donc tu vas travailler sur l'AVC. Et puis nous allons faire référence à I. Mediator nous demandera d'avoir cette instruction d' utilisation ainsi que d'initialiser ce champ. Ensuite, nous pouvons commencer à utiliser ce média pour nous opposer aux rues d'Arcbest ou causer de la neige. Visite rapide de ce contrôleur. Et à ce stade, bien sûr, je suppose que vous avez une certaine familiarité avec les contrôleurs. Et par extension, le développement de l'API, quand nous voulons obtenir la liste des enregistrements sont tous les types de congé dans la base vont frapper cette méthode qui est juste le obtient ses types de congé slash API. C' est ce qui devrait nous arriver, mais tous les types de feuilles. Et puis chacune de ces méthodes porterait sur les autres opérations brutes qui sont tire le put, la suppression. C' est pour les mises à jour. Ou si vous n'êtes pas si familier avec ce dont je parle, je vous encourage à aller vérifier mes cours de développement API afin que vous puissiez être au courant sur apprécier pleinement les subtilités derrière ces méthodes et comment elles fonctionnent . Alors continuons pour les get's qui devrait retourner tous les types de feuilles dans la base de données. Nous allons avoir un code qui ressemble à ceci. Nous allons avoir var types de congé est égal à une attente. Donc, la méthode envoyer trouvé dans nos médias à objecter et tout ce que nous envoyons exactement ? Si vous regardez la surcharge, il attend un objet de type ou un objet avec les appartements sont appelés demandes, donc il ne sait pas quel type de demande il va envoyer la demande. Et l'attente est qu'il va obtenir quelque chose qui peut être stocké à l'intérieur des types de feuilles. Vous savez quelles demandes nous enverrions ? Tout en revenant à nos fonctionnalités de projet d'application, laissez les types et les requêtes. Nous verrons ici que nous avons la demande de liste de type feuille get, qui devrait retourner la liste des détails de type feuille. Donc, dans notre contrôleur de types de feuilles, je dirais que j'envoie un nouvel objet de requête de liste de types. Et puis allez-y et incluez tous les manquements en utilisant des déclarations. Et puis je vais aller de l'avant et changer l'en-tête de la méthode en résultats d'action de tâche asynchrone publics, liste des détails découverts. Donc maintenant, il sait qu'il est prévu de retourner un résultat d'action qui a cette liste de types de feuilles. Donc, cette déclaration de retour n'est plus valide puisque non, je retournerai des types de feuilles et regarderai ces deux lignes. Contextes. Je vais juste le comparer avec l'ancien code ou c'est notre ancienne option aurait eu la variété de types. Il aurait en fait orchestré l'appel aux unités de travail pour obtenir les disques, les amener directement, Buck. Et puis nous allons effectuer le mappage car il retournerait les objets de domaine lorsque nous voudrions que les machines virtuelles soient des contextes de sorte que c'est la même chose qu'un DTO. Et puis nous ferions toute cette opération à l'intérieur de l'action elle-même avant de retourner la vue. Dans le nouveau paradigme, ce que nous faisons c'est que nous laissons les médias savoir que nous demandons la liste de type feuille ou le gestionnaire va effectuer toutes les opérations, il colle tout le mappage et l'interrogation et tout, et il retourne juste les objets que nous devons connaître. Ainsi, l'API n'interagirait jamais avec les objets de domaine réels provenant de la base de données. Nous faisons toute cette transformation avant qu'elle ne revienne. Alors avançons rapidement un peu à l'endroit où j'ai déjà écrit le code, mais comme d'habitude, je vais le parcourir lentement et expliquer chaque ligne afin que vous puissiez pleinement apprécier ce qui se passe. Vous pouvez faire une pause au besoin et répliquer. Et nous allons passer ensemble de toute façon. Bon, donc un ajustement rapide au HTTP GET j'ai limité le retour sur, ok, avec les types de feuilles. D' accord ? Et vous remarquez une fois de plus, tâche, résultats d'action liste les cinq dB HL. Donc, cela est très explicite quant au type de données qu'il va retourner null pour le HTTP GET avec un ID. Une fois que j'ai fait une tâche de code similaire, très similaire, les résultats d'action laissent le diabète. Bien sûr, il doit être asynchrone. Et nous disons que le type de feuille var est égal à, puis nous attendons le médiateur Dotson avec la nouvelle demande. Rappelez-vous donc que la demande sera traitée. médiateur s'occupe de cette partie. Nous devons nous assurer d'utiliser la demande correcte en fonction de ce que nous voulons. Donc, dans cette situation, la demande est d'obtenir le type de feuille bt EverQuest, qui est l'endroit où il obtient le type de feuille particulier avec toutes les intrusions et tous les autres fonds pendants ou exigences qui pourraient être là. Pour les détails. Nous devons également lui donner la valeur id que vous obtiendrez car dans notre gestionnaire, il dépendra fortement de l'ID pour savoir quel enregistrement doit être récupéré. Et puis on revient, accord, avec le type de feuille. Maintenant, dans le post, nous avons quelques lignes de plus et c'est vraiment juste je vous montre comment vous pouvez le sortir de toute façon, mais ce n'est pas absolument nécessaire. Parce que juste de la même façon que tout aurait pu se passer en 19 et nous avons juste créé le nouvel objet ici. J' aurais pu le faire à l'intérieur de celui-ci, les médias pour envoyer la ligne. À la place. Cependant, j'ai dit que la commande var est égale à une nouvelle commande de type feuille de création. Donc, la méthode post est conçue pour la création. Très bien, alors laissez-moi commencer par Desire2Learn graphique BAC, mais j'ai eu de moi-même il des résultats d'action asynchrone de tâche publique. En réalité, vous n'avez pas nécessairement à voir quel est le type de retour. Il ne aide avec la documentation sur le ghetto à swagger. Donc je le remettrais. Quelle que soit cette situation, la réponse serait un int. Donc nous pouvions voir int, mais comme je l'ai dit, ce n'est pas absolument nécessaire. Je vais donc continuer sans que cela soit nécessaire maintenant et plus tard, nous verrons pourquoi il aurait été une bonne idée de le mettre dans. Donc, tâche, action, résultat, post, et nous faisons à partir du corps, et puis nous utilisons le type de détail spécifique pour l'opération. Alors rappelez-vous que nous avons discuté de la vous obtenez granulaire. Laissez-le général. Eh bien, c'est une situation où nous empêcherions de surposter en devenant granulaire car alors quand ils tournent, quand ils envoient des informations de type feuille, ce que nous acceptons via cette option est limité à la à l'intérieur du type que nous avons spécifié. Donc, contrairement au détail de type feuille ou de type feuille BTO, qui a plus de détails sont plus de champs qu'ils créent. Le type de feuille est uniquement conçu pour accepter les points de données dont nous savons que nous avons absolument besoin pour créer notre type de feuille, donc tout autre sera ignoré. Donc, quand nous formulons cette commande, nous avons dit new create leaf Command, D, commande. besoins laissent cet objet de détail. Donc nous passons dans cet objet. Et puis notre réponse est relative à ce que revient le médiateur. Dans cette situation, notre réponse était int, parce que c'est ce que nous avions dit. Lorsque vous créez le type de feuille, il suffit de renvoyer son ID. C' était donc le gestionnaire que nous avons conçu pour ce genre de demandes. Donc, quand nous retournons tout k avec la réponse, ce serait correct avec l'ID de feuille. Maintenant passer à la mise, mettre est utilisé pour la mise à jour, une fois de plus est dans les résultats de l'action de la tâche. Et puis il est par défaut avoir ce paramètre d'ID et nous changeons du périmètre du corps pour être le type feuille DTO. Donc nous l'avons fait, nous avions discuté plus tôt que le type de feuille BTO, nous ne sommes pas trop granulaires avec cela. J' ai une balise div de mise à jour, div à différente de tout le reste. C' est très bien. Donc, dans cette situation, nous acceptons toutes les craintes possibles peuvent être mises à jour. Et nous avons certainement besoin de l'ID à l'intérieur de cet objet, c'est pourquoi nous atteignons cela. En fait, étourdisse-t-il cet ID est facultatif. Donc, je pourrais simplement dire, je n'ai pas besoin d'un paramètre d'ID. Donc, quand vous appelez le put, vous n'avez pas besoin d'appeler une pièce d'identité. Et puis ce commentaire serait en fait juste mettre à jour les commentaires établir l'uniformité. Donc, alors résultat de l'action de tâche, mettre une heure à la recherche est les contextes du corps avec le type de feuille DTO. Rappelez-vous, toute notre validation se produit à l'intérieur de nos gestionnaires. Donc c'est encore moins. Moins de choses ont déchiré des balles ici. Quand nous parlons de l'ID combe-over, est-ce que l'ID existe ? Toutes ces choses se passent à l'intérieur de notre gestionnaire, entre le gestionnaire et sont des validations couramment en fait. Et si quelque chose se sent de ce côté, alors toute cette opération échouera. De toute façon. Nous verrons comment nous gérons les échecs plus tard. Mais pour l'instant, nous voulions juste avoir une idée de la façon dont nos contrôleurs doivent ressembler. Donc, quand nous envoyons la commande pour mettre à jour, nous n'avons pas câblé le savon pour retourner quoi que ce soit, au moins rien d'utile, non ? Nous venons de dire que l'unité de valeur des points représentait un vide, donc nous devions retourner quelque chose, mais nous avons juste dit, ok, vous allez juste retourner quelque chose d'arbitraire pour dire qu'il a réussi. Et donc la réponse HTTP qui correspond à un put n'est généralement pas de contenu, ce qui est un outil pour, d'accord, donc nous pouvons simplement retourner que nous ne parlons pas et la réponse à une variable. Supprimer semble similaire. Delete prend un paramètre d'ID, tâche , résultats d'action, delete int id. Et puis nous avons la commande qui prend juste l'ID, puis nous envoyons sur la commande et retournons ou tout le contenu. Donc, si c'est que vous voulez que tout soit juste deux lignes, alors c'est aussi facile que de prendre la commande, mettre dans le même paramètre. Et tout peut être deux lignes. D' accord, donc je vous montre juste la différence, la grande différence entre ce contrôleur qui fait tout ce que ce contrôleur fait avec tout le code, d' accord, avec les modifications faisaient des validations ici. Pour la suppression, nous faisons une certaine forme de validation. Encore une fois, toutes ces choses sont nulles, obstruées vieux dans d'autres parties de l'application. Et notre contrôleur peut faire exactement ce qu'il est censé faire, c' est-à-dire recevoir une demande, appeler pour faire une opération, puis vous rendre vos données. Voici mon défi pour vous. Allez-y et branchez les autres contrôleurs pour les autres types, pour les fonctionnalités. Donc, nous avons des types de feuilles sont faits. Allez-y et essayez les demandes et laissez les allocations. Vous pouvez, bien sûr, créer des options personnalisées par rapport à ce que l'opération doit effectuer. Mais pour l'instant, je vous laisse faire ça. Donc je vais revenir dans la prochaine vidéo. On va comparer les notes. 21. Finition des contrôles API: Très bien, donc c'est plus une vidéo de révision qu'une vidéo d'écoute. ai seulement quelques choses sur lesquelles je veux me concentrer dans cette leçon que vous avez probablement essayé et probablement eu des programmes avec un sinon alors hommage à vous. Alors commençons par le contrôleur des allocations de congé, vraiment et vraiment, c'est un contrôle qui va être assez identique à notre contrôle des types de congé parce que vraiment et vraiment nous ne faisons que des opérations brutes ici. Nous obtenons la liste où obtenir par carte d'identité. Et bien sûr, si vous ne l'avez pas terminé, vous pouvez toujours faire une pause et aller de l'avant et répliquer comme vous me voyez traverser. Nous faisons la même chose pour le poste. Donc, vous remarquerez que tout ce qui a dit à peu près les demandes de congé remarque l'allocation des congés. Vous pourriez presque dire que vous auriez pu créer un nouveau contrôleur, copier tout à partir du contrôleur des types de feuilles, coller dans le nouveau contrôleur, puis juste le type de feuille avec allocation de congé ou taper avec l'allocation de mot. Je vous donne juste des conseils tout ce que vous auriez pu faire ça assez rapidement et assez efficacement, non ? Parce que celui-ci est assez identique aux types de feuilles. Les demandes de congé, d'autre part, a une petite surprise. Et c'est sous la forme de la mise à jour, non ? Donc, une fois de plus, en passant par assez lentement, je suis à peu près répliqué les options des types de feuilles sur dans les demandes de congé. Donc, la plupart du contenu de ce contrôleur est identique aux deux autres, l' exception de notre opération PUT. Et si vous remarquez et regardez de très près, je dirais mettre les opérations x2. Donc, tout le monde seulement à une opération de mise un, mettre à jour les points de terminaison. Mais dans le cas de la demande de congé, nous avions fait de la place pour deux types de mises à jour. Un où il est une mise à jour régulière. Et notez que cette fois, nous avons le paramètre ID dans le put. Et c'est parce que notre commande leave requests demande l'ID et un détail, c'est très bien. Mais une fois de plus, ces différentes saveurs sont relatives à n'importe quel style que vous pensez. Un scénario beaucoup plus facile. Donc je vous montre juste différentes options. Je ne dis pas que c'est comme ça. Vous avez les différentes options. Utilisez celui qui convient le mieux à votre situation et à votre projet. Maintenant, dans cette situation, une fois de plus, nous avons le paramètre ID que nous pouvons avec la commande et nous construisons une demande de congé Dto. Cependant, le scénario des autres mises à jour n'aurait qu'un statut d'approbation de modification pour nos demandes de congé. Donc, dans ce cas, j'ai créé une approbation de changement de point de terminaison personnalisée. Donc, pour arriver à celui-ci, vous dites api slash Requests Controller approbation slush. Et j'ai vraiment besoin de la carte d'identité. Alors laissez-moi aller de l'avant et l'ajouter à la racine afin qu'il soit modifié l'approbation de la valeur Slashdot ID. Comme j'ai également mis à jour la documentation en conséquence. Et je dois mettre ce paramètre d'identification, Buck. Donc difficile dit plus tôt, remettez-le et construisez mes objets de requête, tout droit, ou mon objet de commande plutôt. Donc je vous montre juste toutes les considérations qui doivent être faites. En fin de compte, nos contrôleurs sont minces et les avantages que vous voyez peut-être, d'accord, donc trois lignes, mais tout cela fonctionne ou dans les vidéos précédentes, juste pour que je puisse mettre trois lignes ici. Pourquoi Titus n'a-t-il pas mis toute la logique ici ? Lequel encore, je comprends complètement parce que cela fonctionnerait. Mais à la fin de la journée, citation, est beaucoup plus testable et je n'ai pas besoin de tester le contrôleur pour savoir si j'obtiendrais les résultats de ce point final. Au lieu de cela, je peux aller tester le gestionnaire qui est censé retourner ces résultats. Et si le gestionnaire fonctionne, alors le point de terminaison fonctionnera. Donc, vous savez, il est juste de déplacer votre attention d'être plus compacte à être un peu plus modulaire et répandre le code et la responsabilité à travers plus de plaisirs afin que vous puissiez avoir une meilleure appréciation ou un contrôle amer sur ce qui chaque composant n'est pas couvert, ils sont tous liés ensemble. 22. Données d'origine en tableaux: D' accord, donc nous sommes en train de finir avec nos opérations liées à l'API. Et dans cette leçon, ce que nous voulons faire est d'introduire des données par défaut dans notre base de données. L' étape suivante, bien sûr, serait de le tester, mais il est toujours bon d'avoir des exemples de données afin que nous puissions faire les opérations de lecture assez facilement et efficacement. Donc, pour voir les données dans notre base de données, nous allons examiner comment nous y parvenons avec Entity Framework. Maintenant, j'en ai déjà fait un et j'ai les deux autres faites par un, donc nous pouvons les faire ensemble. Mais commençons par aller au projet de persistance, ajouter un nouveau dossier appelé configurations, et là un autre dossier appelé entités. Et puis vous allez avoir un fichier de configuration par entité. Donc, à peu près ce fichier de configuration vous permet de mettre dans n'importe quel Entity Framework lié ou n'importe quelle base de données liée plutôt, configurations sont des valeurs par défaut ou des règles que vous voulez parcourir dans la table particulière dans la base de données sera alors tout le code est écrit avec la permission d'EF Core. Alors regardons celui que j'ai déjà fait, et c'est pour la configuration de type leave. Donc vous pouvez faire une pause, enlever ça, et ensuite nous pouvons passer par les morceaux ensemble. Donc, nous avons la configuration de type feuille et puis il hérite de la configuration de type d' entité I par rapport au type de classe que nous traitons, qui est le type feuille. Donc, tout dans cette base de code va être relatif au type de feuille. Donc, une fois que vous faites cela, vous allez finir avec, il va vous demander au parlement l'interface et ensuite cela générerait ce talon de méthode pour vous. Donc, à l'intérieur de ce stub de méthode, nous allons avoir public void configure. Et puis nous avons cet int. C' est tout ce qui est réellement généré pour vous. Donc, plus les parties principales de celui-ci, qui est ce que vous allez construire ou écrire, seraient dans cette section Builder. Donc, nous dirions que le constructeur a des données. Et puis nous dirions laisser le type ou crée un nouvel objet. Donc, c'est une méthode a la mort est une méthode qui a des accolades ouvertes et fermées. Et puis là, nous voyons un nouveau type de feuille et ensuite nous remplissons un objet. Donc, c'est l'objet de domaine que nous voyons vos ID un, votre défaut est d'aller dans les bases de données 10 et votre nom est vacances. Et puis autant que vous en avez besoin, vous pouvez simplement séparer chaque initialisation d' un objet ou instanciation d'un objet à l'intérieur de ce bloc entier. Non, je n'ai pas fait les deux autres. Donc je vais les faire un peu à partir de zéro. Même si par non, vous l'avez probablement déjà fait avec le type de feuille. Eh bien, c'est bon. Donc, pour la configuration d'allocation de congé, il hérite, mais il n'y a pas d'instructions d'utilisation du tout. C' est pour ça que tu vois la ligne rouge. Donc, je vais utiliser le point de contrôle en utilisant Microsoft Entity Framework Core, la référence de domaine, puis implémenter l'interface qui génère ce stub de méthode pour moi. Mais il n'y a rien pour moi à configurer pour l'allocation. Je n'ai pas d'exigence pour l'allocation pour le moment. D' accord. Donc, je ne vois pas d'allocation de congés. Je ne change rien sur les valeurs par défaut sur la structure de la table. Je ne fais rien d'autre. Donc, comme je l'ai dit, cette configuration peut être utilisée pour bien plus que simplement des données d'ensemencement. Et si vous voulez une meilleure compréhension de ce dont il est capable, vous pouvez toujours vérifier tout mon cours Entity Framework Core. Bon, donc nous ferons la même chose pour la demande. Et nous allons juste laisser cela là encore une fois, nous n'avons pas de demandes de congé dont nous avons besoin comme valeurs par défaut, mais nous avons quelques types de feuilles par défaut, donc c'est assez bon pour l'instant. Au moins, nous pouvons exécuter l'API et faire des requêtes GET sur cette table et vérifier que cela fonctionne. Donc, l'étape suivante après avoir écrit ce code serait d'aller à notre console Package Manager et nous devons ajouter la migration pour les types de congé d'amorçage. Donc, une fois que vous faites cela, nous arrivons à un fichier de migration qui nous informe qu'il va insérer ces données dans la base de données pour nous. La prochaine étape, comme nous le savons, serait de mettre à jour la base de données. Ok, super. Donc, cette fois, nous n'allons pas aller directement à la base de données pour vérifier que ceux-ci ont été créés. Ce que nous allons faire est de tester notre API. Alors on se voit dans la leçon suivante. 23. Examinez le soutien de Swagger: Très bien les gars, bienvenue. Donc, dans cette leçon, nous allons en regarder une, tester notre API et la documenter. Donc, le pool de clés qui englobe ces deux tâches est appelé Swagger. Swagger est un outil de documentation d'API open source basé sur les normes d'API ouvertes. Maintenant, il sort de la boîte pour dotnet cinq projets API. Donc, si nous sautons pour démarrer et faire défiler un peu dont voir ici que nous ajoutons la bibliothèque Ginn swagger, qui crée ce document Swagger avec une information API ouverte. Pour que nous puissions changer toutes ces choses. Je peux juste voir l'API de gestion des congés RH. Donnez-lui un titre, donnez-lui une version. Vous pouvez y ajouter d'autres nœuds, la description du contact, et cetera, et cetera. C' est donc un outil très puissant. Et comme je l'ai dit, ça sort de la boîte et tu n'as pas mis ça là. Et une autre partie que vous regarderiez est ici dans la méthode configure où il est dit, si nous sommes en développement, alors utilisez swagger et API. Donc, si vous voulez utiliser swagger, parce que je connais des sociétés qui ont été utilisés soccer comme leur documentation dans la production, alors vous pouvez toujours utiliser ce sel de cette déclaration if et effectivement l'utiliser indépendamment de votre environnement. Bon, pour que tu puisses aller de l'avant et faire ce changement. Non, dirigeons nos projets. Donc, je vais juste frapper F5 avec le projet API en tant que projet de démarrage. Et cela nous permet d'obtenir ce magnifique document qui nous montre tous nos points de terminaison potentiels et comment on peut les appeler. Remarquez que nous avons encore les prévisions météo. On peut supprimer ça par la suite, mais je vous montre juste que nous n'avons pas fait grand-chose. Tout ce que nous avons fait, c'est mettre en place nos contrôleurs, écrire le code que nous savons que nous devons écrire. Mais voici ce beau document qui nous montre tout sur notre API. Donc, si je clique sur l'un de ceux-ci, il s'étend et il me montre exactement à quoi je peux m'attendre. Donc, ce point de terminaison, qui est R, ce comportement api slash allocations de congé, qui est le get qui obtient tous les enregistrements dans la table des allocations de congé. Ça va me donner un code de réussite 200. Et ceci est un aperçu de l'objet qui serait en train de devenir buck. Une fois de plus, je vais toujours revenir aux détails et à quel point vous obtenez granulaire sur ce que vous voulez afficher. Notez que dans ce détail particulier, nous avons l'ID, nous avons le nombre de jours, nous avons le type de feuille avec son propre ID, le nom, et la valeur par défaut est, alors nous avons l'ID de type feuille. Donc, vous pourriez regarder ça et dire que c' est un peu redondant. Si j'ai déjà l'objet de type feuille, je ne veux pas difficile de répéter l'ID ici. Et ce serait une déclaration de peur, non ? Donc, vous savez, nous n'avons pas été très granulaires avec la liste d'allocation des congés DTO. Dans ce cas, nous utilisons simplement le nouveau détail d'allocation. Donc, nous pourrions envoyer trop de détails sont trop de champs dans cette réponse. Nous pouvons ajuster cela en conséquence. Alors regardons les demandes de congé. Les demandes de congé ont une pièce d'identité, le type de feuille, la date demandée et approuvée est vraie. Pourquoi a-t-il cela par opposition à celui qui reçoit les détails qui en a beaucoup plus. Donc swagger est en fait en train de regarder nos types de retour sur le contrôle particulier comme nos options plutôt. Et je vais revenir au contrôleur pour que vous puissiez voir ce que je veux dire. Rappelez-vous que je dirai en ce qu'il y a un avantage de mettre le type de retour directement en ce que je résulte parce que saga utilise réellement ceci pour dire, ok, c'est le type de données qui sera retourné de cette vente aux enchères par rapport à ce pour cette action. Ou en dehors de cela, il fera juste une supposition. Et le, le type de retour ou la fema que vous pourriez voir peut ne pas être représentatif de ce qui est réellement retourné. Donc, c'est l'un des avantages qui sont à distance dit il ya des avantages à mettre le type de retour ici. C' est l'un d'eux. Saga déduira les objets dont il a besoin pour afficher le schéma dans JSON. Et c'est le moins une documentation meilleure et plus claire pour ceux qui interagiront avec votre API. D' accord, alors faisons un test. Passons aux types de feuilles de slash api. Puisque ceux-ci ont été ensemencés dans la base de données, nous devrions, Je m'attends à au moins deux enregistrements après que nous avons essayé dit. Alors frappons ce point de fin pour l'essayer et l'exécuter. Ce que je vais faire est de définir un point d'arrêt sur le contrôleur et le gestionnaire que cette opération devrait frapper. Donc, quand j'exécute à 2Ts, le contrôle ou l'option plutôt, non ? Rappelez-vous que c'est qu'il va médier un Datsun et un symbole avec cette demande non, j'appuie sur F5 et puis il va frapper le point d'arrêt suivant, qui est le gestionnaire. Donc, vous voyez quand du contrôleur au gestionnaire et où toute la magie se passe vraiment à l'intérieur du gestionnaire et du gestionnaire, nous avons notre dépôt sous mapper. Les deux initialisés injectés. Et puis dans le gestionnaire, nous effectuons la requête, puis nous retournons la version détaillée des données. D' accord, donc je vais juste frapper F5 à nouveau et lui permettre de terminer son opération. Et puis swagger nous montre ensuite les données qui viennent de la base de données. Voilà, nommé vacances par défaut est ID1, et cetera, et cetera, et cetera, et cetera. Et de la même manière, si je vais à la get et j'ai essayé de tote, alors cela me permet de passer l'ID. Donc je vais passer ID1, exécuter, et puis ça m'amène la carte Wanderer avec celle d'identification. Maintenant, le football nous permet de faire toutes les opérations grossières, au moins tester le point final que nous avons mis en place. Alors essayons un autre où nous allons créer. Notez donc la différence entre ce schéma et le schéma renvoyé par le détail via gets, à droite. Celui-ci a l'ID, le nom, la valeur par défaut est celui-ci n'a le nom que les jours par défaut. C' est parce que, bien sûr, nous utilisons un détail différent avec une portée limitée. Donc pour le nom, je ne vais rien changer ici. En fait, je vais juste mettre, laisser ces données par défaut. Exécutons et regardons ce que nous obtenons. Nous obtenons une erreur 500. Ok, pourquoi avons-nous eu une erreur 500 ? Laissons-le de près. Souviens-toi de ce qu'on va mettre. On n'a rien changé. Le nom aurait été chaîne et la valeur par défaut, ceux-ci auraient été 0. Si vous vous souvenez bien, nous avons eu la validation de l'installation pour voir que la valeur par défaut est ne devrait jamais être inférieure à un. Donc, ce que nous voyons ici est une erreur 500 parce que l'API, je ne savais pas comment gérer le fait qu' il obtient une exception tout le chemin du gestionnaire. Et cette exception est d'exception de validation de type. Est-ce que ça a l'air familier ? Droit ? Donc, il est juste de nous faire savoir qu'il y avait une erreur et cette exception a été levée. Nous n'avons aucune gestion des exceptions intégrée. Donc, tout ce qui est jeté, swagger ne sait pas quoi faire est juste de nous montrer ce que l'application vous a donné, ce qui est très bien. C' est ce qu'il est conçu pour faire en ce moment. Et nous allons affiner cela au fur et à mesure que nous continuerons. Mais le fait est que cela fonctionne. Donc, si je mets quelque chose de plus significatif et cette fois je vais mettre en congé de maternité avec des jours par défaut de 90 exécuter à nouveau, alors nous récupérons notre code de réponse de 33 serait cet ID. Donc, je peux revenir à la get testlet 3 est exécuté. On y va. Par défaut, le congé de maternité est de 90, et cetera. Donc, je vous montre juste à quel point swagger est utile pour vous de voir le document pour l'API et de tester sans avoir à installer une autre application. Maintenant, cela étant dit, j'utilise généralement Postman pour faire mes tests d'API. Mais dans le but de ce cours, Swagger est parfait et il a servi son but. 24. Test d'unité - Aperçu des sections: Nous savons qu'il y aura un grand portail pour l'application construit. Nous avons développé la plupart de ce qui doit être là pour la fondation. Nous avons mis en place l'API et nous l'avons testée dans une certaine mesure où nous voyons qu'elle communique réellement avec la base de données et que c'est de l'art de travail. Mais alors, comme nous l'avons vu et discuté plus d'une fois, test est une partie très importante du développement d'applications. Donc, nous avons juste éclaté tester l'API Andrea pour le faire manuellement, où nous devons réellement le mettre dans l'outil de test pour l'API soumise. Et puis nous voyons qu'il a été soumis et tout. Et nous étions alors confiants que notre code fonctionne. Mais alors imaginez une obligation beaucoup plus grande avec beaucoup plus de points de contact. Nous n'avons testé qu'un seul point de contact, mais imaginez ensuite tester 50, 60 points de terminaison. Vous n'avez pas le temps ou la capacité pour ça. Ce serait une perte de temps d'essayer vraiment de passer par tout ça. C' est pourquoi nous allons examiner les tests unitaires et comment cela peut nous aider à automatiser ces vérifications pour nous assurer que notre code fait ce que nous avons conçu pour faire. Maintenant, en bref, test unitaire est un code qui teste le code. Oui, c'est exact. Nous allons écrire du code pour tester notre code. C' est l'une des raisons pour lesquelles les gens fuient un proton parce que certaines personnes le voient comme une perte de temps parce qu'alors vous écririez du code deux fois. Et que certaines personnes voient est tout à fait essentiel parce qu'elles ne font pas confiance au code qui n'a pas été testé par un test unitaire. Il ya des personnes qui souscrivent à l'un ou l'autre extrême Je ne suis pas forcément l'un d'eux. Je crois que les outils sont utilisés dans le contexte pour lequel ils sont conçus et au moment où vous êtes prêt pour eux. Donc, dans cette situation, c'est certainement un outil que nous voulons parce que nous voulons nous assurer que nos gestionnaires se comportent en accord avec ce que nous les avons conçus pour faire. Nous voulons également écrire ce que nous appellerons les tests d'intégration, qui seront juste l'interruption entre les différentes couches de notre application. Essais unitaires. Encore une fois, cela fonctionne vraiment bien pour gagner du temps. À long terme. Il faut un certain temps pour écrire les tests. Et notre test est seulement aussi bon que la façon dont il est écrit. Mais il y a des cadres qui peuvent nous aider à nous assurer que nous avons tests de qualité et que nous avons une couverture complète pour notre devis, une autre chose que les tests unitaires nous aide avec est la documentation. Donc, il pourrait laisser des documentations et des commentaires sur votre code. Mais des tests bien écrits peuvent en fait vous montrer notre indication des bits de code qui devraient faire ici et là. Donc, certaines personnes utilisent réellement le test unitaire comme un moyen documenter leur code d'une manière non officielle. Maintenant, en général, il existe trois types principaux de tests que nous traitons habituellement. L' un est le test unitaire, l'autre est le test d'intégration, lequel de nouveau, teste l'interaction entre les couches. Et puis des tests fonctionnels qui sont généralement comme l'interface utilisateur face pour tester ce que l'expérience utilisateur devrait être. Donc, quand nous reviendrons, nous allons envisager d'écrire notre premier test unitaire et nous allons mettre en place notre projet de test dans le dossier des artistes. Et nous allons tester notre logique d'application, alias les gestionnaires, pour nous assurer qu'ils font ce que nous pensons qu'ils font. 25. Ébaucher des tests d'unité pour le code d'application: Salut les gars. Commençons donc par créer un nouveau projet de test pour notre couche d'application. Donc, dans notre dossier de test, dans notre solution, nous allons créer une application de gestion des ressources humaines que j'ai appelée mine qui teste unitaires. Donc, dès le début, ce serait un nouveau projet et nous sommes à la recherche d'un modèle de projet d'unité x. Et puis nous voulons lui donner le nom bien sûr, et cela doit être fait à cinq heures. Très bien, donc une fois que vous avez fait tout cela, alors vous pouvez sauter sur NuGet et nous voulons installer MOQ ou simuler et astucieusement. Donc Mach va nous aider à créer des simulations de notre persistance. Il y a des dépôts et d'autres objets qui sont nécessaires pour simuler ce que notre application ou nos gestionnaires font réellement. Et ne devrait pas nous aider à affirmer que c'est ce que nous attendons de ce genre d'opération. Maintenant, je suis déjà allé de l'avant et mis en place une structure de dossiers pour vous. Et je pense qu'ils sont plus intéressés par les choses pour empilables que pour vous de vous asseoir et de me regarder taper. Je suis donc allé de l'avant et j'ai préparé certains des actifs à l'avance, mais comme d'habitude, nous les examinerons lentement et ensemble afin que nous puissions comprendre complètement ce qui se passe à chaque étape. Dans ce projet, nous avons deux dossiers au moins pour non, Donc, nous sommes 14 types de feuilles. Un pour les fumées de Mach sera le tuyautage des dépôts fictifs. Maintenant, vous avez deux options. Bien sûr, vous pouvez avoir un fichier par référentiel simulé, peut avoir un fichier de référentiel simulé et avoir plusieurs instances là-dedans. C' est à vous de décider en ce moment, je n'utilise qu' un seul fichier et ce qui n'aura qu'un seul test à exécuter. Donc, si vous avez 50 choses sont des fonctionnalités que vous devez exécuter. Nos gestionnaires sont des fonctionnalités sur lesquelles vous devez exécuter des tests unitaires, alors il serait probablement préférable de les diviser en fichiers particuliers par jeux de données que vous voudriez avoir une moquerie avant. Alors allons dans les simulations d'abord. Donc, j'ai déjà un peu traversé et configuré une méthode dans ce fichier, dans ce fichier. Alors discutons ensemble. J' ai donc fait ça une classe statique publique et j'appelle un référentiels fictifs. Encore une fois, j'aurais facilement pu être très spécifique et dire quelque chose comme mach leave type dépôt. En fait, je vais prendre ma propre soumission et le faire de cette façon. Nous avons donc ce fichier, en particulier pour le dépôt de type de congé Mach, le puits Newcomb de Toronto, dépôt d'emplacement de levier fictif, et cetera, et cetera. Donc, le dépôt de type Mach leave est une classe statique et il a une méthode statique dedans. Cette méthode est conçue une fois de plus statique publique. Et notez qu'il est décoré avec ce mot-clé mock, qui nous vient avec la permission de la bibliothèque fictive, non ? Et cela nous permettra de se moquer de n'importe quel type de dépôt ici. Donc, je veux un référentiel de type feuille simulé se moquant du référentiel de type elif. Et puis j'appelle la méthode get le référentiel de type feuille. Maintenant, cette méthode va avoir une liste d'objets de type feuille. Vous pouvez être complètement fictif avec ces. n'y a rien à dire qu'ils doivent ressembler à ce qui serait dans la base de données. n'y a pas, il n'y a rien de particulier à ce sujet est juste une liste d'objets similaires à ce que nous attendrions de la base de données lorsque nous traitons les objets de type de congé de domaine, non ? Donc je dois juste, vous pourriez en avoir 10, vous pourriez avoir 15 ou 20 en aurait plus en fonction de votre scénario et de ce que vous devez tester. Vous pourriez avoir besoin de plus, vous pourriez avoir besoin de moins que ça, mais c'est à vous de décider. Donc, je ne fais que deux. D' accord, alors on initialise notre faux repo. Donc je vais dire que le groupe environnemental était égal à nouveau Mock. Et les types de nouveau est que je vais quitter le dépôt de type. Donc, jusqu'à ce que nous fassions tout cela, vous allez voir notre ligne rouge à côté de cette méthode parce qu'elle dit que tous les chemins ne retournent pas une valeur parce que nous devons retourner la simulation. Donc avant de pouvoir retourner le Mach, il faut le mettre en place. Donc, des échantillons de données sont présents. Le nouvel objet du dépôt Mott est présent. Donc maintenant, nous devons littéralement appeler la configuration de point de repo simulé. Nous utilisons une expression lambda où elle nous donne accès aux méthodes qui auraient été à l'intérieur du repo original. Donc, si nous voulons tester la méthode get ou au moins mettre en place, ils obtiennent tous les moyens méthodiques que quand un test appelle ce faux repo et que nous voulons invoquer un test contre le code qui utilise cela obtient tout. Il passera dans le faux repo. Et puis on est assis, ils ont toutes les méthodes. Donc c'est un bloc ou c'est une configuration. Notre expression lambda R-dot ghettos L, C'est tout dans un bloc, puis retourne la liste des types de feuilles. Donc, tout code qui fait naître la moquerie va appeler le Get off pour ce dépôt, le simulacre. Qui sera invoqué dans le test, retournera cette liste de types de feuilles. C' est ce qu'il va traiter. Très bien, donc vous pouvez, vous avez le contrôle total de vos échantillons de données. Tend to T fait pour se lever et commencer avec ce Misha avec les données d'échantillon, mais tout est pour une bonne cause. Non, le suivant serait de configurer ce qui se passe lorsque nous appelons la méthode add. Très bien, donc la configuration de points bleus moqueux, encore une fois ce bloc lambda où nous appelons la méthode add. Donc tout ça est un bloc. Et je vais juste expliquer ce qui se passe ici. Nous voyons notre point point normal, mais la méthode add par défaut a besoin d'un objet de type entité de type feuille. Bon, donc je vais laisser ça. Très bien, donc nous devons passer une entité de type feuille dans la méthode add. Ce que nous faisons ici, c'est que nous faisons une sorte d'affirmation que vous ne pouvez appeler cette méthode que lorsqu'un objet de type, type feuille est transmis. Encore une fois, cela peut être un objet fictif. Il a juste besoin d'être de type, de type feuille. Il n'a pas besoin d'avoir toutes ces données et quoi que ce soit de spécial. Très bien, donc si c'est hors du type de feuille, alors cette méthode peut être appelée. Et il retourne est couler un objet. Donc, ce que nous allons faire est de faire un délégué pour dire après avoir obtenu l'objet de type feuille, et ensuite nous avons notre expression ou méthode Lambda les bloquer, il suffit de le déplacer à la phrase suivante afin que vous puissiez le voir plus clairement. Ensuite, nous disons les types de congé, qui est notre liste de points ajouter. Donc, pour la durée de vie du test, chaque fois que quelqu'un appelle la méthode add et passe dans ces objets de type feuille, nous allons juste l'ajouter à la liste des types de feuille et en retour ce type de feuille particulier. Donc, c'est juste tenir le fonctionnement de l'installation et puis basé sur le scénario ou le test de l'installation de Fourier peut différer. Donc, vous remarquez qu'ils obtiennent tous les regards d'installation assez différents de la, le, désolé, ils vont ajouter la configuration. Et puis la supprimer un mil différemment, puis la mise à jour un mil différemment. Donc en ce moment, nous sommes juste assis ou pour ajouter et obtenir tout. Et puis nous allons de l'avant et rendons ce faux repo. Donc, après l'avoir retourné, cette flèche disparaîtrait, et c'est ce que cette méthode est quatre. Donc, après que vous avez répliqué tout cela, vous pouvez juste, je suis sûr que vous êtes en pause et que vous n'écrivez pas, mais j'espère que vous avez une meilleure compréhension de la façon dont le MAC nous aide à simuler des données sans réellement toucher la base de données. Maintenant, passons à notre premier test unitaire. Maintenant celui-ci va être des requêtes, des dossiers. J' ai laissé des onglets et des commandes et des requêtes. Très bien, donc les gestionnaires qui font des requêtes seront testés à l'intérieur des requêtes regarderont et les commandes dans les commandes. Donc, le premier que nous avons est le test du gestionnaire de requête de la liste de type feuille get. C' est presque plein, mais au moins personne ne peut faire une erreur quant à ce qui est testé. Au lieu de ce fichier, vous pouvez avoir plusieurs tests bien sûr, mais dans ce scénario, nous voulons seulement avoir, nous avons seulement besoin d'un test vraiment pour le gestionnaire de liste d'invités ou non, laissez-moi juste vous expliquer ce qui est se déroulant dans ces 10 premières lignes. Eh bien, nous avons besoin de savoir que nous avons besoin d'un mappeur automatique et nous savons que nous avons besoin d'un dépôt pour interagir avec le gestionnaire, non ? Et je vais juste sauter, n'ai-je pas fini écrire les tests que nous allons faire ça ensemble, mais je voulais juste montrer ce qui se passe quand nous essayons d'instancier notre gestionnaire, nous recevons une erreur. Pourquoi ? Parce qu'un 100 attend un paramètre de type I elif type dépôt et un autre paramètre de type high mapper. C' est un test unitaire qui ne peut pas les injecter. C' est 12. On ne voudrait pas l'injecter. Je veux dire, on pourrait probablement, mais on ne le voudrait pas parce qu'on a affaire à des simulations, non ? Je ne veux pas injecter dans le référentiel de type elif réel car cela va parler à la base de données. Nous ne voulons pas que notre test unitaire parle réellement à la base de données. On voulait juste le simuler. Donc, ce que j'ai fait est d'initialiser ou de déclarer ou d'autres champs privés, un pour le mappeur et un pour notre faux repal, non ? Donc mach privé en lecture seule des personnes de référentiel de type II elif. Ensuite, nous avons notre constructeur. Donc, dans le constructeur, une fois que ce test est invoqué pour initialiser notre mockery boat local pour être égal à appeler type feuille simulée point de la classe de dépôt de type feuille obtenir la méthode de dépôt de type feuille. D' accord, pour que non, nous allons faire toute cette configuration et retourner les gens moqueurs pour les utiliser dans ce test. Maintenant, pour le mappeur , on n'injecte rien. Nous avons donc besoin de ce mappeur pour connaître toutes les configurations de mappage réelles qui existent dans notre application. Donc, ce que nous allons faire est d'initialiser l'objet de configuration du mapper. Être une nouvelle configuration de mappeur de marché. Et puis nous avons une expression lambda ici avec notre bloc objet dans lequel nous voyons lambda Tolkien point ajouter le profil pour le profil de cartographie. Après avoir mis en place le profil de mappage et la configuration, alors nous pouvons savoir juste passer qui n'a pas fait. Donc, nous disons que le mappeur est égal au mappeur. Config dot crée un nouveau mappeur à l'aide de cette configuration. Donc, dans l'ensemble, notre mappeur ici dans l'artiste est vraiment Il est représentatif du vrai mappeur dans l'application. Donc, toute la méthode ci-dessous savoir a la tâche asynchrone publique obtenir la liste de type de congé. Donc on est précis, on sait pour quoi on teste exactement ? Où tester la méthode qui obtient la liste des types de feuilles. Il est décoré avec cet attribut de fait parce que c'est ce qui dit à l'obligation qu'il s'agit d'un test unitaire. C' est un dicton, Hey, quoi qu'il arrive ici doit être combattu. Quelles que soient les affirmations ici doivent être passées. S' ils ne réussissent pas, ce test a échoué. Maintenant, nous avons réellement interagir dans les centaines, même que les tests sont plutôt. Donc, nous disons que var handler est égal à nouveau. Et puis j'instancie les 100 que j'ai souhaité le test dans cette méthode. Remarquez les lignes rouges car cela nécessite notre ondulation simulée ou une instance d'un dépôt de type elif. Donc, moquerie Bull nous donne un objet simulé, mais alors je peux obtenir la citation réelle unquote objet réel à travers MLK repo dot objet. Prochain arrêt, nous avons besoin de notre mappeur. D' accord, ça a l'air bien. Ensuite, nous voulons réellement tester l'appel de méthode. Donc, je vais dire que le résultat var est égal à la poignée de points du gestionnaire. Très bien, parce qu'il y avait gestionnaire a cette méthode appelée handle et il nécessite un nouvel objet ou il nécessite les objets de requête. Donc, nous devons passer dans un nouvel objet du but. Et je vais juste enlever tout cela et utilise l'insert, l'instruction using. On y va. Pour que nous n'ayons pas tout ce texte. Et puis après cela, il a aussi besoin d'annulation. Tolkien, d'accord, donc contre la laisse sur peut ou je peux juste passer dans l'annulation Tolkien ligne pointillée. Bon, donc ce bus qui est dans, mais ce renversement rouge et inclure toutes les références manquantes. On y va. Donc on voit juste appeler ça. Nous ne transmettons aucun jeton d'annulation. Nous sommes autoritaires et ce nouvel objet, donc nous n'avons pas forcément à l'être. Donc Mach est vraiment juste pour ça, le top. D' accord ? Non, on peut voir un résultat. Et si vous regardez le type de données pour les résultats, oh, eh bien, nous devons attendre ça. Excusez-moi. Si vous regardez le type de données pour le résultat, il est en fait liste. Oui, on y va. Donc, le type de données pour le résultat est une liste de type feuille DTO. Donc, il est assez facile de porter des déclarations et de dire, Ok , eh bien, si les cônes sont plus grands qu'un, alors ceci ou quelque chose, juste pour s'assurer que nous en sommes revenus plus d'un parce que la liste, donc nous devrions en récupérer un ou plus. Mais à la fin de la journée, nous pouvons nous asseoir et penser à toutes sortes de scénarios et ainsi de suite que nous pourrions être dépassés. C' est pourquoi nous avons le cadre devrait nous aider. Donc, je peux dire dotplot résultat. Rappelez-vous que c'est vraiment juste des choses répertoriées. C' est juste une liste. Mais allé au type devrait être hors type parce que je veux m'assurer que j'obtiens le bon type de données. Le type de données que nous attendons de notre gestionnaire pour cet appel particulier serait la liste. Le type de données serait la liste des détails de type feuille. Donc je vais voir et connaître les lignes mandarines pour l'instant. Travaillons simplement sur cette partie. Laissez le type DTO. D' accord ? Non, quand je fais ça, il y a une pure ligne de Larry parce que devrait être de type, vous ne l'avez probablement jamais vu avant. Donc, si je contrôle WC en utilisant peu de temps, donc c'est là que cela ne devrait pas être entre en jeu. Cela nous aide avec nos affirmations, avec nos hypothèses sur ce qui devrait arriver. Je vais aller de l'avant et mettre dans l'instruction using pour le DTU aussi. Mais c'est là le point que je vais sûrement faire. J' ai donc appelé le gestionnaire, j'exécute une commande ou exécute une opération, j'ai obtenu un résultat. Et puis je vois que les résultats devraient être de type, feuille de type DTO. Donc c'est une affirmation là. Et nous allons voir ce que nous avons Kinsey résultat point et le début, commencer à taper Devrais-je voir tous les possibles, à droite, tous ces. Nos choses possibles que nous pouvons affirmer ou qu'il devrait être non, devraient être à portée de main, devraient être en ordre. Toutes ces choses sont des choses que vous pouvez vérifier. Donc, je peux voir devrait être et dire T2 parce que je sais pour mes données de test que le tournage, oh désolé. Plus de nombre de points C devrait être. On y va. D'accord. Donc, cela devrait être juste caché sur toute autre propriété ou l'objet lui-même. Et cela lui permet d'obtenir l'assertion pour n'importe quel scénario attendu. Alors sachez qu'on l'a dit. Laissez-moi écrire sur le projet et dire exécuter des tests. Et cela nous donnera Spore autistique, qui va ensuite exécuter le test et nous montrer ce passé. D'accord. Alors que quatre heures, si elle doit être deux. Non, je sais que j'en ai mis deux, mais disons que j'en ai dit cinq et relancé ce test. Nulle part obtenir des échecs. Et si je développe que juste un peu, qui voit devrait laisser l'affirmation devrait être cinq, bateau était deux. Donc, cela signifie que si quelque chose a changé dans mon code et qu'il recherche en masse, je sais que mon code est censé revenir à tout moment, mais alors quelque chose de gènes. Disons que je n'ai pas changé le test. Je sais que c'est aussi. Droit. Mais si je mets un objet mère. Très bien, donc c'est là que la modification du code intervient. Et oui, tout est statistique, mais encore une fois, on parle de sonars. Donc, la maternité ou si je change le code qui aurait dû revenir à un, devrait toujours revenir à 18, introduire quelque chose. Non, ça revient trois. Mes tests unitaires juste en l'exécutant il saura me dire quand quelque chose change. Laisse-moi juste relancer ce test unitaire. Et mon affirmation est encore deux, mais trois dollars de jeu. Donc, tout de suite, je sais qu'il y a un bug dans le gestionnaire auquel je fais face ou parce que quelque chose a mal tourné. C' est donc une sorte de ce que les tests unitaires apportent à la table. Maintenant, nous allons créer nos crée le test de gestionnaire de commande de type leave sont. Et donc, au lieu du dossier de commandes, vous pouvez aller de l'avant et configurer ce fichier. Et cela va sembler assez similaire au type get leaf. Nous avons le même dépôt Mach utilisé. Nous avons la même procédure d'initialisation utilisée. Et puis nous avons test, qui est le courant qui bien sûr avec le fait et la tâche où nous voyons créer le type de feuille. Donc, nous appelons le gestionnaire, qui est le gestionnaire de commande create leaf type, chantant Ce sont les objets que nécessaire, et ensuite nous avons les résultats. Donc, notre résultat va provenir de notre commande de type feuille gestionnaire de point handle de manger créer une commande de type feuille. Et n'oubliez pas que notre commande de type feuille à créer nécessite une BTO à vie. Donc, cela signifie que nous avons besoin d'un objet ici pour passer en null, vous avez deux options. Vous pouvez créer les nouveaux critères d'objet dans ce gestionnaire et l'utiliser. Mais alors si vous avez plusieurs tests, vous pouvez simplement créer un objet de type feuille D2 et l'utiliser pour plusieurs tests. Donc, je vais utiliser la deuxième approche où je vais laisser mon privé en lecture seule ce DTO et ensuite je l'initialiserai dans le constructeur. Certaines personnes après un certain temps, elles ont tellement d'actifs en cours d'initialisation que ce constructeur devient trop grand. Ce qu'ils feraient est peut-être de regrouper ETL à une autre méthode qu'ils appellent comme initiale, configuration initiale ou initialisation. Et puis ils font toutes ces initialisations là-dedans. Et parfois les actifs sont partagés entre les tests. Donc, ce qu'ils feraient est de charger tout cela dans un fichier complètement différent, comme une configuration de point crass, la configuration test de type Laisser droit. Cela va juste aller de l'avant et retourner tous les objets nécessaires. Donc il n'y a pas de deux façons, mais ce ne sont pas de gros tests. Donc on veut juste mettre le concept sous nos doigts avant de penser à l'obstruer trop, non ? Donc, nous avons toute cette configuration et nous avons notre détail de type feuille qui doit être transmis. Donc oh désolé, je reçois cette zone parce que c'est le type de feuille de création BTO, excuses. Laisse-moi juste réparer ce type de données et ensuite nous devrions être prêts à partir. Et on y va. Très bien, et bien sûr aucune pièce d'identité n'est dedans. Bon, alors voyons ce que nous devons affirmer dans celui-ci. D' abord, lorsque nous ajoutons un nouvel outil de type feuille, notre faux repo, alors le cône devrait augmenter, non ? De la même façon quand nous avons ajouté à notre base de données, s'il y en avait dix, sachez qu'il y en a 11. Alors rappelez-vous dans notre faux repo, nous avions mis en place la méthode add qui devrait prendre n'importe quel type de congé et il devrait l'ajouter à la liste. Ce qui veut dire que si je devais appeler la liste ou obtenir tout. Le repo juste après une opération d'ajout, alors il devrait y avoir un fichier de plus, puis il y a null, un enregistrement de plus et il y en a au moment, non ? Il y a donc trois nuls. Permettez-moi d'abord de mettre à jour cette affirmation pour dire trois. Et puis j'appellerai le faux repo. Donc, je vais dire les types de congé var. Je suis allé chercher le repo pour Khomeini. Donc, bien sûr, nous faisons les faux objets repo dot pensés, et ensuite nous pouvons juste obtenir le get all. Donc quand nous invoquons encore, tout ce que nous savons exactement ce que nous recevons. On a cette liste. Ensuite, je peux faire mes résultats pensés devraient être. Et nous savons que nous retournons les valeurs d'ID. Donc, après avoir appelé le create Tumblr pour le type feuille, il devrait être de type int, à droite, donc c'est notre première assertion. Et puis je vais aussi dire que les types de feuilles point, point devrait être. Et je vais m'assurer que ça dit quatre parce que nous savons qu'on commence avec trois nuls après l'appel, ça devrait être pour. Avant de faire le test, je vais juste le renommer pour avoir l'air un peu plus utile, non ? Donc, créez, créez des tests de type feuille. Mais qu'est-ce que vous pouvez avoir plusieurs tests sont que les humains créent des types de tests de feuilles pour ce qui se passe quand il est un test incorrect pour ce qui se passe quand il est valide test pour ce qui se passe lorsque les valeurs sont une valeur particulière et que vous avez un dans leur travail devrait se comporter de cette façon ou de cette façon en fonction de la nature de tout ce qui est passé là-bas. Tant de scénarios, je ne peux pas m'asseoir et penser à tous les scénarios, mais je vous donne juste le cadre sur lequel vous pouvez formuler vos tests. Donc, ce test est, est une assertion que chaque fois qu'un type de feuille valide est ajouté, C'est le comportement attendu. Donc, je vais revenir à notre gestionnaire fait pour que nous puissions comprendre, encore une fois le but des tests unitaires. Donc tester qu'on a besoin de Buck, c'est facile. Ok, oui, nous avons le repo MLK où seule requête dans le repo simulé, le gestionnaire est censé faire une chose toute façon qui est retourné ce qui est dans le repo, c'est très bien. Mais dans une situation où nous avons plusieurs résultats dans notre gestionnaire, nous voulons tester chaque résultat. Et puis vous pouvez probablement le décomposer en le bon test et le test sanguin. C' est à votre discrétion sur ce que vous voulez vous assurer que vous avez une couverture pour les résultats potentiels. Parce que si les règles métier changent, si un développeur arrive, modifie l'instruction if, même si accidentellement, l'un des résultats changera et vous voulez l'attraper le plus tôt possible. Donc, dans notre commande create leaf type, et rappelez-vous que nous faisons une validation ici, non ? Donc, nous validons le type de feuille, puis nous lançons une exception. Quand il n'est pas valide. Ensuite, si elle est valide, nous passons par et nous retournons l'ID. Donc nous avons testé que c'est déjà. Et nous voyons où l'ajout de la chose ramène en fait plus de records. Si on était à Git repo. Et c'est bien, mais nous devons tester ce qui se passe lorsque de mauvaises données entrent dans, assurez-vous qu'elles sont traitées correctement conformément à nos règles métier. D' accord, donc c'est là qu'on a fait les affirmations. Nous affirmons que si je reçois un objet de requête invalide avec un type de feuille non valide D DO laisser la demande de type DTO feuille ab initio, désolé, que nous devrions obtenir une exception ou nous devrions obtenir certaines choses dans leur réponse basé sur la façon dont vous avez écrit votre code. C' est ce qui devrait arriver. Ce scénario est MIT. Notez également que parce que nous sommes à, dans l'unité deux, CO commence à voir combien de références sur le nombre de tests passent pour votre code. Donc, vous pouvez toujours savoir que vous êtes dans le vert, que vous êtes dans l'ambre ou le vert ou que vous n'êtes pas dans le vert quand il s'agit de passer les tests. Donc, je vais revenir à notre test et j'ai ajouté un autre test pour le type de feuille non valide ajouté. D' accord, donc nous avons le même code où nous avons mis en place notre gestionnaire, n'est-ce pas ? Et une fois de plus, cela se répète. Donc, ce que certaines personnes font et ce que j'ai tendance à faire parfois est de déplacer code répétitif en étant un champ privé et initialisé dans le constructeur. que le fichier de test de charbon augmente, vous voudrez peut-être exploiter certaines parties de celui-ci parce que nous ne voulons pas avoir à le faire chaque fois que vous avez un test, vous devez initialiser. C' est donc le même gestionnaire de commandes que nous allons utiliser avec un repo simulé C et le même mappeur. Donc, après s'être assis sur le faux repo, je suis le mappeur. Nous pouvons juste initialiser notre gestionnaire pour obtenir ces objets. Alors, l'artiste regarde, et bien, on a une ligne de moins à s'inquiéter, non ? Donc, nous disons juste le gestionnaire de soulignement, facture de datetime, et aller de l'avant. Donc, dans ce nouveau test, je vais prendre mon type de feuille DTO et je vais le rendre invalide. Alors rappelez-vous que nous l'avons initialisé pour avoir 15 jours et ce nom. Mais alors nous savons que pendant que nous testons pour ça, si je laissais le type jamais venu avec ça, alors il devrait être invalide, non ? Donc on va juste le rendre invalide. Et puis je vais faire quelque chose d'un peu différemment. Non, donc on teste une exception. D' accord, donc je vais dire que l'exception de validation e x est égale à 0, il devrait. Donc, nous obtenons un appel de classe statique ne devrait pas lancer une exception de validation de puits. Et puis nous ouvrons les parenthèses et vous pouvez ouvrir et fermer. Et puis au lieu de cela, vous dites async délégués flèche Lambda. Maintenant, nous allons à nos poids, l'appel du gestionnaire transmettant les détails. Donc, littéralement, juste ce neuf que nous mettons à l'intérieur de cela devrait lancer la méthode asynchrone. Ensuite, à la fin, nous pouvons tester pour obtenir tous les types de feuilles. Donc nous allons entrer dans les feuilles, rappelez-vous que nous l'avons fait ici et nous avons dit qu'il devrait le savoir avant. Donc, après une opération invalide, ça devrait encore être trois, non ? Donc c'est ce que nous sommes un domaine distinct. Nous nous assurons que cela ne l'a pas fait dans notre jeu de données de repo simulé. Et puis je peux également m'assurer que l'exception ne devrait pas être nulle. C' est donc ma façon de m'assurer qu'une exception était bien trône. Maintenant que j'ai fait tout ça, et quand tu testes quelques jours, tu auras le fœtus. Donc, quand vous êtes rempli comme c'est soit parce que vous devez affiner le test pour vous assurer que vous testez la bonne chose ou que vous êtes, vous avez lu le test et vous interagissez simplement et il échoue parce que votre code ne passe pas le test. Bon, donc deux parties cherchent. Alors maintenant que j'ai fait tout ça, allons de l'avant et lançons une nouvelle série de tests. Et j'ai eu tous les feux verts partout. Donc, le type de feuille non valide a ajouté toutes les assertions passées, ce qui signifie qu'il ne l'a pas correctement ajouté au repo et il a jeté l'exception parce que l'exception n'était pas nulle et que la valide a été ajoutée avec succès. Et bien sûr, nous avons récupéré les choses dans l'ondulation correctement. Bon, pour que nous puissions fermer cet explorateur de test, et c'était les tiques vertes ici. Et puis si nous regardons en arrière dans notre code, ce qui voyait le champ n'est pas de voir passer. Très bien, donc vous pouvez voir combien de tests font référence à cette méthode de gestionnaire particulière dans cette commande. C' est donc une vue d'ensemble rapide et sale des tests unitaires et comment cela peut nous aider avec notre couverture de code. Et cordial, bien sûr, le rouge bien que les tests pour vos autres gestionnaires et explorer comment les différents scénarios peuvent être testés pour. 26. Configuration du projet ASP.NET MVC: D' accord, donc nous mettons en place notre projet dans ce nouveau module. Et ce que nous allons utiliser pour notre projet d'interface utilisateur est l'application Web ASP.Net Core, MVC. Ainsi, notre application client ou notre interface utilisateur aurait facilement pu être construite avec n'importe quelle technologie capable de consommer une API RESTful. Nous avons donc notre API que nous avons déjà configurée. Mais quand nous allons créer ce client, nous aurions pu utiliser la vue angulaire, réagir ou larve ou blazer, n'importe lequel d'entre eux. Mais je vais vraiment m'en tenir au MVC parce qu'il est rare que vous voyez réellement un MVC comme le consommateur d'une API. C' est généralement le tout en un de toute façon, que, et le projet original était déjà intégré MVC. Donc, nous allons garder ce sentiment MVC à lui. Pas de problème. Mais alors l'architecture sous-jacente a déjà été vidé et configuré. Donc, nous allons y aller et vous pouvez juste chercher MVC. Et rappelez-vous que c'est un ASP.NET Core Web up, pas l'application Web ASP.NET. Très bien, donc vous appuyez sur la prochaine, vous lui donnez le nom, qui, auquel cas nous l'appelons h i point de gestion de laisser point MVC, et nous utilisons un projet dotnet 5. Vous pouvez également activer le rasoir à la fin du temps pendant que vous êtes ici. Et puis vous pouvez simplement appuyer sur créer. Maintenant, une fois que cela est fait, vous allez finir avec ce projet, qui est la norme modèle MVC standard standard pour une application MVC standard pour dotnet Core. Vous verrez qu'il ressemble beaucoup à notre projet API, sauf qu'il a quelques dossiers supplémentaires comme les vues et les modèles. MVC Model-View-Controller. Et puis nous avons le même fichier de démarrage, le même fichier program.cs, les paramètres de l'application. Toutes ces choses sont une sorte de plaidoyer commun. Et nous avons le dossier racine ww www, qui a tous les quatre statiques. Donc, si vous êtes déjà familier avec MVC où vous n'avez pas de problème, mais je vais essayer de mon mieux pour être le plus détaillé possible avec tous les changements et le code qui doit être écrit et comment tout se lie. Ainsi, lorsque nous reviendrons, nous examinerons comment nous pouvons commencer intégrer notre API à nos clients. 27. Utilisez NSwag pour le code de client API: D' accord, donc nous sommes bons et artiste à être est de configurer notre application client pour consommer notre API. Nous avons donc déjà créé notre application MVC et nous avons notre documentation API sous la forme du sogar noch. Donc, nous allons utiliser n swapped pour nous aider à générer, il génère littéralement le code qui, cela nous aiderait à consommer cette API. Et entre swagger et in swag, vous verrez qu'en quelques clics, en quelques minutes, nous aurons tout le code, ou au moins la plupart du code nécessaire pour réellement établir communication entre le client et l'API. Donc, étape 1, faites apparaître votre documentation Swagger et ensuite vous pouvez vous diriger vers le fichier JSON qu'il génère en cliquant sur ce lien, qui fera apparaître ce fichier JSON, qui alimente essentiellement cet affichage que nous voyons ici. Donc, la prochaine chose que je veux que vous fassiez est d'aller à Google ou Bing et de trouver la page GitHub pour n swag studio. Ensuite, vous pouvez télécharger et installer cela et c'est bien documenté, mais nous allons passer en revue exactement ce que vous devez faire pour le mettre en service. Vous pouvez donc simplement le télécharger et l'installer. Et une fois que vous aurez fait cela, vous serez accueilli avec cette belle interface. Il y a donc peu de choses que vous voulez faire aussi. Commencez avec cette procédure. Numéro un, vous voulez vous assurer que le moteur d'exécution est correct. Donc, par défaut, je pense que cela peut aller au net Core 21. Nous utilisons le filet 5, donc vous pouvez aller de l'avant et changer ça. Et puis l'URL de spécification doit être l'URL du fichier JSON provenant de swagger. Donc, vous pouvez simplement copier cela à partir du navigateur et le coller là. Cliquez sur Créer une copie locale. Et puis vous voyez cette documentation ici ci-dessous. Maintenant, avec tout cela fait et juste les notes qui, dans swag, supportent d'autres types d'applications clientes, ce qui signifie TypeScript. Si, si vous utilisiez la vue ou le réacteur, l' un de ces frameworks JavaScript, alors vous pourriez tout aussi facilement générer du code en utilisant et swag pour ces types de frameworks. Cependant, nous nous en tenons aux clients C-Sharp, donc vous devriez juste prendre cela et vous obtenez ce nouvel onglet. Et puis il y a quelques réglages ici. Laisse-moi juste faire défiler vers le haut. Il y a quelques paramètres ici que nous voulons nous assurer qu'ils sont dans la police. Numéro un, configurez l'espace de noms. Donc, pour l'espace de noms, j'ai des services de points MVC de gestion de points de points de points HR C' est l'espace de noms dans lequel j'ai l'intention d'avoir tout le code généré. Il y a d'autres choses qui peuvent déjà être cochées, mais je vais juste passer par et m'assurer que nous avons mis en place la carte F1. Utilisez donc l'URL de base pour la requête. Vous voulez vous assurer qu'il est coché ainsi que génère la propriété URL de base doit être définie sur la classe de base. D' accord ? Vous voulez vous assurer que vous avez coché le client HTTP d'injection par un constructeur et générer des interfaces pour les classes clientes. faisant défiler, je pense que la plupart d'entre eux sont déjà là par défaut. Vous voulez vous assurer que les types de détails génériques sont cochés. Et près de la fin. Nous voulons également nous assurer que nous arrivons à la fin en fait, parce que je pense que tout le reste ici sera déjà rempli par défaut. Donc, je ne vais pas passer trop de temps sur des choses qui sont déjà là et pas je ne suis pas fatigué, pas absolument nécessaire. Donc, tout ce qui est hors de propos, ça va juste s'assurer qu'ils sont en place. Tu peux laisser tout le reste. Et puis à la fin de cela, vous voulez mettre dans le chemin du fichier de sortie afin que vous puissiez simplement aller à votre projet correctement appelé le projet. Beaucoup de Visual Studio, désolé, grep, cliquez sur un projet et allez à Ouvrir dans l'explorateur, prenez cette URL ou ce chemin et collez-le ici, ce que nous mettons des services barre oblique, barre oblique point de service client CSS. Donc, après avoir fait tout cela, vous pouvez aller de l'avant et appuyer sur Générer des fichiers et cela ne devrait pas prendre beaucoup de temps pour générer ces fichiers. Et puis, lorsque cela est fait, vous pouvez passer à Visual Studio et accéder à votre base de services et à la classe de client de service. J' ai un peu plus rapide que nous allons discuter plus tard, mais il s'agit juste de se concentrer sur le serveur et le fichier de subvention de service. Donc, nous avons ce fichier client qui est généré et il nous donne une interface et l'implémentation de l'interface hors de la boîte, n'est-ce pas ? Beaucoup de documentation sur les annotations n'ont pas vraiment à s'inquiéter de trop de ces choses. Mais à la fin de la journée, il a généré un bateau 1700 lignes de code, au moins dans mon livre. Donc, en fonction de la taille de votre API, vous pouvez obtenir plus, vous pouvez obtenir moins. Mais le fait est que tout cela a été fait pour nous afin que nous puissions nous concentrer sur des choses plus importantes, non ? Donc, nous voulons travailler plus intelligemment, pas plus dur. Et une autre chose importante à noter est que dans swag, chaque fois que la documentation change, ce qui signifie que quelqu'un a changé à l'API, swagger. En conséquence, obtenu, bien que les exigences des points de terminaison ont changé, qu'est-ce que cela change ? Vous pouvez toujours supprimer ce que vous mettez dans. Et donc encore une fois, régénérez ce fichier afin que vous n' ayez pas à obtenir qui réduit les allers et retours, surtout dans un environnement agile où les changements sont inévitables et rapides. Donc, vous pouvez toujours suivre le rythme avec régénérer dans ce client et changer le code autour d'elle si nécessaire ? Non, je n'ai pas dit que j'ai quelques autres fichiers et pendant que nous allons entrer dans les détails, je vais juste vous montrer. J' ai donc des contrats et les contrats que j'ai un fichier de contrat ou une interface par type de point de terminaison que je connais d'interagir avec et aussi un fichier d'implémentation de service pour chaque contrat a commencé pour Windows dans, mais je vous donne juste une idée de ce que ces fichiers supplémentaires sont dans le fichier de base, dossier de base. J' ai également une réponse API et ils sont plus PFAS qui iront dans la base juste pour que nous puissions avoir cette extensibilité. Mais pour non, tu n'as pas à t'en inquiéter. La prochaine chose que vous voudrez peut-être faire, c'est mettre en place Newton soft. Donc, vous obtenez probablement une erreur n'importe où que le mot Newtons de ceux-ci étant référencé dans ce fichier. Donc, vous pouvez toujours aller à New gets. Et puis vous voudriez chercher le soft, désolé, Microsoft point ASP, NET Core, VC point Newton soft JSON de Newton. Donc, vous pouvez aller de l'avant et installer cela, faire une nouvelle construction, et ces zones devraient disparaître. Ensuite, dans notre classe de démarrage, nous voulons enregistrer notre client HTTP. Donc, vous dites, dans les services de configuration diraient les services qui ajoutent le client. Je dirige PaaS dans le client et le client IE. Ces deux-là sondent pour plus de fichiers générés. Et puis nous voulons lui transmettre l'adresse de base. Donc c'est juste un PDG ou un client à usage égal, vous savez, c'est une expression lambda. L' adresse de base des points est égale à la nouvelle URI. Et puis nous voulons l'URL de l'API réelle. Donc, pour trouver cette API URL, ce que vous pouvez faire est d'aller au projet API, développer les propriétés et lancer les paramètres. Et puis vous verrez ce port SSL. Donc, il est fondamentalement http localhost deux-points pour plein, dans mon cas, 44, 3, 27. Dans votre cas, ça pourrait être différent, non ? Donc HTTPS localhost et ce port SSL comme vous le voyez dans vos séances de pelouse. Donc, avec cela fait, nous avons réellement mis en place le client ou au moins la fondation du client. Donc, les contrats et les définitions de services que nous avons ici et que nous allons pêcher reviennent en fin de compte, sont relatifs aux opérations spécifiques nécessaires par appel. Parce que lorsque nous appelons C obtient tous les types de feuilles. Comment allons-nous afficher les types de feuilles dans notre application ? nous faut encore des modèles. Nous devons toujours le désérialiser de JSON parce que, vous savez, les API de repos qu'ils envoient et reçoivent JSON. Nous devrons donc convertir de JSON en un type que notre application cliente peut apprécier. Et puis nous pouvons permettre à l'utilisateur d'interagir avec lui en conséquence. Donc, quand nous reviendrons, nous regarderons tout ça. Bien que les activités de codage que nous devons mettre dans notre propre, notre client. 28. Configuration des clients et code de base: Donc, maintenant, nous allons créer ou examiner certains des fichiers et fonctions de soutien que nous allons mettre en place avant de continuer à construire notre application client. Donc, ce sont vraiment des opérations ponctuelles que nous allons traverser et je vais vous expliquer pourquoi elles sont utiles. Pas nécessairement nécessaire, mais au moins utile. Commençons donc avec nos bibliothèques tierces dans de nouveaux gets. On va aller chercher l'automne et on va obtenir un stockage local chez Julian Hansen. Très bien, donc ça nous aidera plus tard. Nous n'allons pas forcément l'utiliser maintenant, mais vous pouvez simplement aller de l'avant et l'obtenir de Non, afin que nous puissions tout mettre en place une fois pour toutes. Nous obtenons à la fois l'automne supérieur et finalement des extensions. Et nous avons déjà le Newton doux. Donc, avec tout cela installé dans le démarrage, nous allons nous assurer que nous ajoutons le mappeur automatique. Maintenant vous vous demandez probablement, ok, pourquoi est-ce que j'ajoute le papier ultime ? Encore une fois après nous l'avons probablement fait déjà dans l'application. Nous avions donc mis en place ces services pour la distribution dans notre couche d'application et nous avions ajouté l'oper d'automne. Donc, vous vous demandez probablement, ok, tout comme avec l'API quand nous venons d'appeler configure application et services. Pourquoi ne pas configurer les applications et les services qui sont Clint ? Eh bien, la réalité est que le client ne sait vraiment rien d'autre dans ce projet, n'est-ce pas ? C' est donc son propre projet. Imaginez si nous utilisions dire, une vue ou une application angulaire, ce sera la même chose. n'y aura pas, ouais, à part le fait qu'il n'y aurait pas de référence ascendante, mais le fait est qu'il n'y aurait pas de référence de base ou d'infrastructure. Il fait à peine référence à l'API, sait juste qu'une API doit être trouvée à une adresse, et c'est l'hypothèse qu'il fait. Donc, avec cela dit, c'est pourquoi nous ne référençons aucune des autres bibliothèques à l'intérieur de cette application MVC client. Il est autonome et tout ce qu'il fait est accessible à un point de terminaison et attendez un certain résultat par la suite, qui serait l'appel d'API que nous avons configuré ici. Nous ajoutons donc l'empeigne d'automne individuellement à ce projet. Et encore une fois, c'est parce que lorsque nous recevons le DTo avec, nous pourrions avoir à masser les bits de données avant que nous les affichons à l'utilisateur interagissent avec lui de quelque manière que ce soit, forme ou forme. Donc, nous ajoutons le mappeur automatique, et je suis déjà allé de l'avant et ajouté cela. Eh bien, vous n'avez pas à vous soucier que cette ligne va passer par ces trois lignes en détail dans quelques uns. Alors allez-y, ajoutez la partie supérieure de l'automne. Et puis les quelques choses suivantes que nous devons mettre en place seraient de créer un type de réponse personnalisé. Donc, notre type de réponse ici serait utilisé lorsque nous parlons à l'API et la réponse de l'API, il pourrait être avec la réponse de la commande. Cela pourrait être avec la réponse de la commande RBS, plutôt il pourrait être avec les erreurs de validation, peu importe ce qu'il est. On ne sait pas. Rappelez-vous, nous n'interagissons qu'avec une API, donc nous nous attendons à ce que de bonnes choses reviennent ou une forme d'exception est un feu de frai de beurre. On ne sait pas. Nous créons donc notre propre type de réponse générique sur le client, qui sera capable d'obtenir un message. Ce sera bien. J'aime obtenir des erreurs de validation sous la forme d'une chaîne. Il saura s'il a réussi et il récupérerait des objets, des objets. Donc je l'appelle « pas « , on ne sait pas ce que ça pourrait être. Il pourrait être un objet avec le vous savez, nous avons été renvoyés l'objet dans certains de la création, il pourrait être un entier, serait juste l'ID, nous ne savons pas. Bien sûr, il serait prudent de notre part de revenir en arrière et de normaliser toutes ces choses. À des fins éducatives, nous aurions passé par différents scénarios. Mais au moins dans le cadre plus d'entreprise, nous voudrions normaliser cela afin que nous puissions certainement savoir à quoi nous attendre pour chaque scénario. C' est donc notre réponse du client. Bon, donc passer au prochain dossier que nous avons qui veut examiner, c'est que je prétends. Donc, dans le dossier de base, nous avons un client et vous avez des clients que vous voyez probablement. D' accord. Mais n'avons-nous pas vu le client AAE et le client avant ? Et si vous voyez cela, alors vous avez raison. Dans nos clients de service qui ont été générés, nous avons vraiment ironclad et nous avons un client. Mais alors nous voulons juste créer un peu d'extension de ça pour ne pas avoir à creuser trop profondément pour arriver à certaines choses. Donc un, vous remarquerez que c'est une partie. D' accord ? Donc, la chose cool à propos d'une partie est que cela signifie que vous pouvez avoir plusieurs versions de la même classe. Bien sûr qu'ils vont tous travailler ensemble. Mais n'importe quel kevin a plusieurs fichiers avec le même nom, le même nom de classe ou le même nom d'interface. Et c'est comme s'ils fusionnaient tous au moment de l'exécution. Donc, c'est plutôt cool si vous n'avez jamais interagi avec des partiels. Mais nous avons déjà l'être partiel généré pour nous. Nous allons donc simplement créer notre propre implémentation partielle ou notre propre interface client AAE partielle, qui a juste accès au client HTTP. Très bien, alors en service, nous avons ce client HTTP. C' est très profond. Dans des temps probablement pas très accessibles, donc nous sommes juste en train de créer une version publique de cela. Et puis dans la mise en œuvre qui est public partiel crédit de classe dans le, dans la coupe de cheveux, désolé, de l'Islande. Nous avons juste cette propriété publique qui nous permet de rendre cette propriété privée du genre de services. Il y a donc notre client HTTP privé. Cela signifie donc que cela nous permet de ne pas réellement interagir avec le client HTTP au cas où vous vouliez y faire quelque chose. Comme plus tard, quand nous faisons la sécurité, nous allons vouloir interrompre pour mettre des en-têtes avant qu'il n'envoie une inflammation. Donc, vous verrez que dans quelques No 1 à noter avec le client et le client, vous voulez vous assurer qu'ils sont dans le même espace de noms qu'un service, gradient de service. Très bien, donc en fait quand je faisais ça, je n'avais pas le point parce que je lui ai donné des services de point nbc. C' est l'espace de noms que je donne dans swag pour générer ce fichier même s'il va dans le dossier de base. Et puis je client a été automatiquement créé avec l'espace de noms dot ds. Donc, vous avez deux options. Vous pouvez soit dans celui-ci à ceci, et ensuite vous assurer que dans swag sait que l'espace de noms devrait adopter ceux-ci. Ou vous pouvez simplement vous assurer que ce sont des services parce que s'ils ne sont pas dans le même espace de noms et qu'ils ne se verront pas comme partiels. Donc, vous pouvez juste prendre note de ça quand vous le faites. Si vous rencontrez des erreurs que vous ne pouvez pas comprendre pourquoi vous les obtenez. Maintenant, nous allons retourner à notre dossier Contrats. Et là, vous verrez que j'ai un fichier appelé i service de stockage local. Non. Je vais parler d'aller de l'avant. Les services de stockage local pour nous allons implémenter l' authentification en utilisant JSON Web Tokens ou JWT pour le savoir court, après un Tolkien a été facile à appliquer, application ici étant une application client, nous avons besoin un moyen de le stocker entre les opérations, donc vous vous connectez, puis pendant que vous êtes connecté, vous êtes probablement en train de regarder votre congé, vous faites probablement un certain nombre de choses. N' importe qui peut faire n'importe quoi à n'importe quel moment du système. Mais nous allons exiger une authentification pour que vous puissiez compléter certaines choses. Donc, un jeton doit absolument être présent. Comme je l'ai dit, nous l'ajouterons plus tard. Mais je veux mettre en place ceci au moins le service local de l'œil, service de stockage local de null car il sera nécessaire pour une autre configuration bête que nous voulons faire. Non. Donc, après avoir obtenu cette bibliothèque de stockage locale de NuGet, nous allons simplement créer une interface où nous pouvons extraire certaines des opérations dans nos propres méthodes. Nous voulons donc un stockage clair existe, obtenir une valeur de stockage et une valeur de stockage définie. Et c'est vraiment juste une paire de clés de valeur. Donc nous allons juste lui donner une clé et une valeur. Vous pouvez donc l'utiliser pour stocker des petits morceaux d'informations. Bien sûr, vous ne voulez pas stocker quelque chose de trop sensible à l'intérieur du stockage local, car il peut alors ouvrir votre application pour des vulnérabilités. Mais c'est là son but. Donc, après avoir configuré cette interface, vous pouvez aller de l'avant et configurer l'implémentation dans le dossier des services. Nous avons donc un service de stockage local héritant de mon stockage local. Et nous avons un champ de type stockage local qui nous vient de la bibliothèque qui nous a été donnée par le point net de Hansen. Et ici, dans le constructeur, nous sommes juste assis comme une petite configuration, puis initialisons le stockage. Donc, notre configuration dit nouvelle configuration de stockage à faible coût. Le chargement automatique et l'enregistrement automatique sont vrais. Et puis le nom de fichier que je viens de lui donner ce nom qui est indicatif de l'application à laquelle il appartient. Donc tu peux aller de l'avant et faire ça. Et puis le stockage est égal au nouveau stockage local. Et toutes les méthodes sont assez simples. Dans le stockage le plus clair, nous avons juste la liste des clés que nous voulons effacer du stockage. Donc, cette coordonnée pratique lorsque quelqu'un se déconnecte probablement et que vous voulez supprimer les références aux jetons et tout ce que vous auriez stocké. Vous pouvez simplement aller de l'avant et passer toutes les clés et il serait juste de les enlever pour vous. Vous avez la valeur de stockage définie où nous passons dans la clé et quelle que soit la valeur, puis il la stockera. Non, c'est t. Oui, cela peut prendre comme un objet ou une chaîne, quel que soit le type de données, mais il l'analysera dans une forme de valeur stockée, puis le stockage qui persiste l'analyse de base, il suffit de le garder et assurez-vous que vous prêtent attention à cela. Obtient la valeur de stockage essentiellement retourne juste ce qu'il est basé sur la clé qui est demandée. Et puis on peut toujours vérifier s'il existe, non ? Alors passez la clé et il retournera le stockage Xist, qui est juste un booléen. Oui, il existe ou non, ce n'est pas le cas. Aucune étape que j'aurais négligé les visites pour ajouter cela aux fichiers de démarrage. Nous devons donc dire que les services dot ajoutent singleton cette fois parce que nous n'avons pas besoin de plusieurs instances de notre stockage local. Ce serait en fait. Mauvaise idée, non ? Donc, nous voulons juste qu'une instance du stockage local persiste pour l'ensemble de l'utilisateur, l'exécution de l'utilisateur ou l'utilisation de cette application cliente. Et nous sommes en train de passer dans l'œil le service de stockage à faible coût ainsi que le service de stockage local ? Non, dans notre service HTTP de base, qui vit dans le dossier de base de nos services. Nous allons juste faire quelques opérations de base que nous voulons que tous les services puissent faire. Donc, un où nous avons les champs pour I, le stockage à faible coût, service de stockage et un client que nous avons initialisé en utilisant notre constructeur, nous sommes familiers avec cela ou simplement les injecter dans. Et plus tard, n'avons-nous pas deux méthodes. Nous en avons un où nous convertissons les exceptions API sont c'est donc l'exception API vient en fait de notre cogénération usine de service. Parce qu'en regardant le point de terminaison, regardant à quoi s'attendre, il s'est rendu compte que nous pourrions obtenir des exceptions de costume avec code d' état et la réponse et d'autres choses, non ? Nous avons donc accès à ce type de base, mais nous voulons probablement le convertir en réponse si jamais cela arrive. Donc, nous pouvons voir si le code d'état de l'exception API est 400, alors nous voyons des erreurs de validation ont eu lieu parce que c'était la mauvaise demande, non ? S' il s'agit de 404, alors nous voyons le message, l'élément n'a pas pu être trouvé. Et puis sinon, si c'est 500 et que vous voyez quelque chose s'est mal passé, et autant de codes d'erreur que nous aurions b, nous savons que nous serions en mesure de revenir de l'API. Nous pouvons toujours les configurer ici et avoir personnalisé, au moins dans une certaine mesure, des messages personnalisés par type d'époque. D' accord, la prochaine méthode serait d'ajouter la bière Tolkien. Donc vide protégé au jeton de porteur nous permet de voir si le stockage à faible coût a une certaine valeur avec le mot Tolkien. Certains juste une fois de plus, Linda, Linda a cultivé du travail ici, là où nous ne sommes pas tout à fait prêts pour celui-là. Je le mets juste là et on en discutera en détail plus tard. Mais cette méthode vous permet d'ajouter le jeton porteur au point client HTTP, client par défaut ou demande l'autorisation, n'est-ce pas ? Donc, tout ce code est fondamentalement comment vous obtenez l'accès aux en-têtes d'autorisation dans toute communication client HTTP avec notre API RESTful. Et ce que nous allons faire est d'ajouter une nouvelle valeur d'en-tête d'authentification. Laisse-moi juste briser la ligne ici assis ou clair. Nous ajoutons donc une nouvelle valeur d'en-tête d'authentification avec le porteur de nom. Et nous le mettons à partir du stockage local, obtenez la valeur de stockage de la chaîne de type avec cette clé. D' accord, donc c'est votre âme va obtenir les jetons à envoyer avec nos requêtes HTTP. Mais nous ne sommes pas tout à fait prêts à en discuter en détail, mais vous pouvez écrire dans le code à partir de null. Encore une fois, tout cela est cultivé travail. Personne ne va regarder notre costume. Je n'aime pas les appeler costume, mais nos extensions des différentes fonctionnalités sont les différents types d'interactions que nous allons avoir avec l'API à la fois, toutes les interactions de type feuille, toutes les interactions de type les demandes et les interactions d'allocation. Nous les avons empêchés de participer à leurs propres contrats. Et puis tous interagiront de toute façon avec le service HTTP de base, parce que lorsque nous nous sécurisons, ils auront besoin de certaines fonctionnalités BCE et pour une interruption générale. D' accord, donc quand on revient et qu'on commence à mettre en place le type de feuille, parce que c'est toujours le plus facile, non ? Celui est assez simple. Donc ça commence par celle-là. Et je vais regarder comment nous attachons tout ensemble. 29. Service de gestion de police de police: Salut là, bienvenue. Nous allons commencer à examiner les exigences de service de type feuille. Mais avant d'entrer dans le contrat et l'implémentation du service dans le projet d'interface utilisateur, je veux que nous fassions quelques choses d'entretien avec les gestionnaires et l'API. Et j'expliquerai, bien sûr au fur et à mesure, pourquoi elles sont bénéfiques avant d'aller de l'avant. Donc, pour commencer, passons simplement au gestionnaire de commande create leaf type. Et si vous avez besoin de notre premier entendu, c'est dans le projet d'application sur le dossier de base. Très bien, donc ce que je vous encourage à en faire une, c'est de normaliser ce qui est retourné. Donc, à tous les points, nous voulons probablement avoir la réponse de la commande bs. Rappelez-vous qu'une réponse de commande bs nous permet de transmettre l'indicateur de succès, l'ID du nouvel enregistrement, ainsi qu'un message, n'est-ce pas ? Vous voudrez donc refactoriser votre code de gestionnaire. Je vais juste laisser cela sur l'écran assez longtemps pour que vous puissiez faire une pause et refactoriser en conséquence, où si la validation échoue, alors les succès de réponse tombent. Ils auront un message et nous mettons toutes les erreurs de validation. Et puis on en a d'autres. Si c'est correct, alors nous avons le vrai, le message et nous retournons l'ID avec l'objet de réponse. Bien sûr, si nous mettons à jour cela pour retourner la réponse de la commande bs, cela signifie que notre demande doit également renvoyer cela. Donc, vous pouvez simplement aller de l'avant et mettre à jour la commande de type leaf pour que je demande de retourner la réponse de la commande bs. Donc, ce sont des sommes des changements dont nous avons besoin dans le gestionnaire ainsi que dans la classe de commande. Bien que. Passant à cela, passons à l'API. Maintenant, lorsque nous discutions de l'API, nous avons également mentionné pourquoi il est une bonne idée dans les résultats de l'action de la tâche d'inclure également le type de données renvoyé. Et nous avons vu dans la documentation de swagger que, vous savez, pour ceux qui avaient notre type de retour, la documentation indiquait clairement ce qui serait retourné. Maintenant que nous avons ajusté le type de retour pour notre gestionnaire de commande create, ajustons également le type de retour des résultats d'action pour le rythme avec la réponse de la commande bs. Dur parce que quand on fait ça, on obtient la réponse, on revient bien. Avec cette réponse. D' accord. Pour que nous sachions, améliorons notre documentation, puis je vais vous montrer une autre chose qui la rend encore meilleure en termes de ce que la documentation étant à jour et d'être aussi explicite nous aide à faire. Maintenant, une chose de plus avant d'aller de l'avant, je veux que vous cliquiez sur votre projet de test et exécutiez des tests. Donc juste au cas où vous n'étiez pas convaincu de l'importance des tests unitaires. Si vous exécutez les tests, vous obtiendrez probablement tous les échecs pour les tests qui devaient vérifier si le, si la validation ou le type feuille valide ou le type feuille non valide ont été ajoutés avec succès, Pourquoi échouent-ils ? Eh bien, on vient de faire notre refactor, donc on change quelque chose dans notre code, notre poulet Teslas pour une chose. Et évidemment, ce que nous avons changé va briser ce test. Maintenant, si vous revenez à votre test, rappelez-vous que nous avons dit que le résultat de l'opération ADD devrait être de type int. Donc, une fois de plus, c'est un excellent moyen de voir où refactoriser votre code modifierait réellement les choses, non ? Donc non, le test valide aurait dit que devrait être de type feuille int. Nous allons changer cela pour devrait être basé sur la réponse de la commande. Maintenant, l'invalide comptait sur une exception de validation lancée, ce qui était le cas avant ou pris en compte ou neige. Donc, nous avons réellement besoin d'ajuster ce test pour savoir refléter qu'il n'y a pas d'exception. Et que nous faisons juste le même genre d'opération où nous appelons juste en attente de 0 parce que c'est ce que fait notre nouveau code, n'est-ce pas ? Donc nous appelons à attendre les résultats. Et les résultats devraient être hors de la réponse de commande basée sur le type et le code devrait être trois. Donc, si nous réexécutons ces tests, alors nous voyons que nous avons des tests réussis tous les nôtres. Donc, une fois de plus, l'unité elle-même était de nous garder, nous aide à garder le contrôle de nos facteurs et de nos changements fondamentaux dans un si grand projet. Maintenant que nous avons modifié ou API, nous devons régénérer la Guerre froide, le client de service. Et en plus de simplement régénérer, il y a quelques changements que je veux souligner avec les paramètres comme vous le faites. Donc, une fois de plus, allez-y et obtenez ce lien JSON si vous ne l'aviez pas déjà. Et puis dans l'interface swag de fin, nous allons le coller et nous allons recréer la copie locale. Donc, nous devons faire cette étape à chaque fois, si vous l'aviez il n'y en a pas parce que tout ce qu'il voit dans le JSON est ce qu'il va utiliser quand il génère le code. Donc, je pointe cet orteil parce qu'avant la méthode post que nous venons de modifier n'avait qu'un type de retour de 200, 100 avec peut-être un int. Non, vous verrez qu'il a d'autres types de retour. D' accord. Donc, l'inférence de cela pour la fin SWACH Studio est qu'il doit compenser le fait qu'il devrait attendre notre type de retour de réponse de commande bs. Donc on va être la même chose. Donc, si vous l'avez déjà ouvert, c'est bon. Mais si ce n'est pas le cas, on pourra le revivre. C' est la gestion des congés R-dot, mais MVC point services.js, je mets sur la base cette fois M. it off la première fois, veux nous assurer que nous générons les classes d'exception. Injectez le client HTTP via l'instructeur et générez des interfaces pour l'accès au client. Et nous voulons envelopper les exceptions de détail dans le football. Instance d'exception. Nous voulons générer les détails. Mais une chose que si vous aviez avant, j'aimerais que vous décochiez est ceci sur un bateau, l'URL de base américaine pour la demande. Donc, au départ, nous l'avions coché. Vous pouvez le décocher. Raison étant dans le code de subvention de service que vous avez tous ouvert, vous verrez qu'il y a un champ BaseURL dedans et qu'il attend une chaîne. Donc, nous sommes en fait une sorte de contourner la nécessité de mettre la chaîne dans ce code parce que nous avions enregistré ou client HTTP avec son adresse de base. Donc on n'a pas besoin de ça. Utilisez BaseURL pour la demande plus. Bon, donc vous pouvez décocher le point un et aller avant et vous assurer que tout le reste est coché en conséquence. Et une fois que vous avez fait cela, bien sûr, vous avez pointé sur le chemin de sortie, puis vous générez des fichiers. Donc, une fois que vous que ce fichier de tendances de service CS sera régénéré et mis à jour pour savoir s'attendre à ce que le ou les nouveaux types de retour si vous refactorisez plus d'une chose, quoi que ce soit qui est nouveau dans votre API sera reflété dans le et, par conséquent, reflété dans votre nouvelle classe de marque de service. Maintenant que nous avons terminé le travail de base avec nos gestionnaires et notre API. Revenons à notre interface utilisateur. Donc, je suis dans la classe de démarrage et Lee peut voir que je n'ai pas commenté la ligne de service de type feuille de service de type. Nous allons décommenter les autres en temps voulu, mais vous pouvez simplement commencer par celui sur commenté. Et regardons les implémentations. Avant cela cependant, je tiens à souligner que nous avons le profil de cartographie. J' ai donc créé le profil de cartographie qui suit les mêmes procédures ont été utilisées à partir de notre couche d'application où nous héritons du profil courtoisie de l'automne supérieur, puis nous commençons à mettre dans ces configurations de carte de profil. J' ai également créé des modèles de vue. Je vais réellement commencer avec le ViewModel avant de regarder l'implémentation et l'interface du service de feuilles. Donc, si nous ne savons tout simplement pas où cela, j'ai créé dans notre dossier de modèles, laissez le type VM. J' ai juste mis tout dans un fichier cette fois. Donc, dans la VM de type feuille, vous verrez que je l'ai, qui représente la VM qui a tous les champs, mais elle n'a que l'ID. Et puis j'ai créé laisser cette machine virtuelle où nous avons le nom et la valeur par défaut est, alors laissez cette machine virtuelle hérite de créer feuille cette machine virtuelle. Nous avons donc toujours cherché comment réduire la répétition entre les machines virtuelles. Et encore une fois, cela dépend de la granularité que vous voulez obtenir en termes de données ou de points de données plutôt que vous mettez dans vos modèles de vue. Donc, ici, laissez cette machine virtuelle a ID et hérite de tous les autres champs de Create et crée ceux qui n'ont pas cet ID. Et nous avons déjà discuté que c'est du niveau des détails, pourquoi cela est fait de cette façon. Donc, une fois de plus, à partir du profil de mappage, je peux mapper comme entre le ViewModel natif à l', à l'application d'interface utilisateur ou la façon et le détail de notre fichier client de service IA ou fichier de subvention de service, désolé, où nous avons tous les détails mentionnés dans ce dossier. Donc, vous pouvez aller de l'avant et répliquer ce type de mappage et ces modèles. Maintenant, passons à, je crois, le service de type. Donc, cette interface, c'est dans les contrats et elle implémente essentiellement toutes les fonctions de foule que nous savons sont natives. Vous devez que je laisse les opérations de type sont croyées opérations de type. Donc, nous avons les types get leaf qui renvoie une liste de lift, IBM, celui qui obtient le détail renvoyant la même machine virtuelle. Nous avons réponse à la tâche insulaire. Ils ont regardé la classe de réponse. Donc, ici, nous attendons réellement cette réponse par rapport au Père. Nous obtenons cette réponse de base à partir de la commande qui crée notre type de feuille. Donc, notre tâche va retourner une réponse, mais ensuite l'intérieur, cela représente la valeur id qui revient parce que c'est ce que nous voulons vraiment, vraiment, non ? Donc, une réponse relative au type de int create leaf type et nous passons dans cette feuille cette machine virtuelle. Nous avons également la tâche de mettre à jour et une tâche à supprimer. Donc, après avoir configuré tous ces éléments dans l'interface comme nous l'avons vu auparavant, une fois que vous avez un contrat, vous devez avoir l'implémentation. Donc, dans l'implémentation que je viens de mettre dans le dossier des services, nous avons le service de type feuille. Alors passons à travers celui-ci ensemble. Donc, cela hérite du service HTTP de base que vous avez traversé ensemble. Et puis je laisse le service de type à ce stade va vous dire tout ce dont vous avez besoin pour faire la mise en œuvre. Pas de problème, vous allez de l'avant et laissez-le implémenter toutes les méthodes requises. Donc, à l'intérieur de ce service de type feuille, nous avons la surtension locale, le client IM supérieur et AAE en cours d'injection. Donc, tous ceux sont injectés et initialisés en conséquence. Nous devons aussi passer à notre base. Et la base ici étant le service HTTP de base, le client HTTP, ainsi que le service de stockage local. Tu l'as déjà vu. Donc, vous devez régler toutes ces choses. S' il vous plaît pointez pour arrêter là vraiment pour ce segment, quand nous reviendrons, nous allons examiner les différentes méthodes qui ont été mises en œuvre. J' ai déjà du code là-bas, mais c'est bon. Nous allons passer en revue en détail sur le retour. Mais ce sont vos méthodes héritées du service de type elif et elles sont toutes mises là en attente d'être implémentées. Donc, nous allons passer par cela ainsi que nos contrôleurs et nos points de vue dans la prochaine leçon. 30. UI: Dans cette leçon, nous allons parcourir nos contrôleurs et nos vues et l'interface utilisateur générale sur la façon dont nous menons notre application interagit avec l'API pour toutes les opérations brutes. Mais avant d'y arriver, j'ai quelques corrections que nous devons apporter à notre interface et à l'implémentation de notre service de type feuille. corrections incluraient donc la mise à jour des types de retour pour la mise à jour et la suppression. J' ai un peu copié et collé. Et dans la leçon précédente, vous auriez probablement copié sur les implémentations incorrectes sont des prototypes incorrects pour ces méthodes. Donc, vous pouvez aller de l'avant et les mettre à jour en conséquence, où ils sont tous censés retourner la même réponse de tâche par rapport au type int. Et pour la mise à jour et la suppression mise à jour est bon de prendre un paramètre int id et le type feuille VM. Et la suppression va prendre ce paramètre int id. Ainsi, vous pouvez aller de l'avant et apporter ces modifications et bien sûr mettre à jour les implémentations à l'intérieur du fichier de service de type feuille. Maintenant, afin de commencer à faire l'interface utilisateur, bien sûr, nous devons mettre l'implémentation sous-jacente, puis câbler le code et tout. Donc, nous allons commencer par les très simples, qui seraient le type de feuille R pour obtenir les types de feuille, qui sera la liste. Et ils obtiennent des détails de type feuille, ce qui serait le seul. D' accord, alors regardons les implémentations de cet outil. Ils sont assez simples. Tout ce que nous faisons est d'initialiser une variable que j'appelle dans les types de feuilles ou Napoléon via des types de feuilles égaux attendent client. Donc, ce client n'est pas la subvention HTTP qui est injectée dans ce que le client venant du service HTTP obèse, n'est-ce pas ? Certes, ce serait presque la même chose parce que la seule raison pour laquelle nous avons celui-ci est de pouvoir le transmettre à la base. D' accord, mais restons-en à ça. Donc, le client de soulignement représente la glande de service HTTP du problème de base. Et c'est ce que nous utilisons. Donc je vais attendre sur ces Tendances de travail, types de feuilles de points, tous un évier. Très bien, donc c'est nous donner accès à toutes les méthodes qui ont été générées pour nous dans le service client thunks le swap final. Donc, vous verrez des types de feuilles de types de feuilles, leads obtiennent le plus complet est vu par quelqu'un le nomme méthodes dans votre contrôleur API, vous pouvez voir des noms légèrement différents, mais j'ai juste regardé sur la convention de nommage en particulier pour l'API standard développement. Et je prends juste ça. Donc je pense qu'il est assez clair que celui-ci obtient tout l'autre est, juste envie d'obtenir, et cetera. De toute façon, les paramètres peuvent toujours être votre guide. Donc les types Vardy est égal à attendre tous les types de feuilles. Et puis nous retournons vadrouille, liste de vadrouille, type de feuille, VM, les types de feuille. Très bien, donc c'est pourquoi cela renvoie cette liste de type feuille VM, parce que cela reviendrait dans la liste sont la zone publique de type feuille DTL heure juste les mapper à notre machine virtuelle de type feuille locale. Nous avons donc déjà examiné le mappeur et la configuration pour cela. Pas en dehors de ça, pour les détails, ce que nous faisons ici est d'en obtenir un seul. Donc, nous voyons var leaf être z égal à 08. Client. Les types de feuilles obtiennent un évier et le get prend notre mentor sur int id. Et puis de même, nous retournons une version simulée pour laisser le type VM de cette feuille. Maintenant, passons à l'un des plus compliqués. Commençons par le type de feuille de suppression, et je vais supprimer le type de feuille n'a besoin que de l'ID. Il a seulement besoin de l'ID car le paramètre API quand il a besoin de l'ID. Donc, nous faisons une capture de tendance dans cette situation où nous allons voir un type de feuille client de poids .read, supprimer async passant cet ID. Et puis nous retournerons une nouvelle réponse de type int où le succès est vrai. Très bien, Donc, si cela n'a pas réussi, alors c'est pourquoi nous attrapons et puis nous convertissons ou API qui aurait notre exception API plutôt que cela aurait été de retour dans la réponse avec les informations appropriées. D' accord, donc c'est à peu près tout pour la suppression. Et puis la mise à jour. En fait, il semble très similaire à cela, sauf pour prendre ID et le type de feuille en tant que feuille de type que VM. Ensuite, je vais faire un mappage pour convertir cela de la feuille une VM dans le type feuille DTO avant de l'envoyer ensuite. Et tout ce qui concerne ce type de feuille mettre async. Si vous survolez, vous verrez qu'il prend un ID de type string, ma chaîne générée par la fin. J' ai trouvé cela surprenant ce que je viens de dire, laissez-moi travailler avec elle au lieu d'essayer de contourner. Le tien prend int, alors c'est bien. Vous n'avez pas besoin de faire cet identifiant point en chaîne, mais dans mon cas, il faut une chaîne, donc pas de problème, je prends l'id int, je suis juste en train de le convertir en chaîne. Et je passe aussi sur ce diabète de feuilles. Eh bien, c'est que je viens de convertir. Ensuite, si tout a réussi, nous retournons juste une réponse avec le succès étant égal à vrai. Encore une fois, c'est dans une prise d'essai. Donc toute exception serait interceptée. Savoir avec la création vous met dans un peu plus. Donc j'ai commencé ou vous auriez vu un aperçu de ça. Eh bien, laissez-moi vous expliquer ce que ce code fait cette fois. Donc, une fois de plus, il retourne une réponse avec plonger dans le jalonnement, créer feuille VM comme paramètre. Et c'est vraiment les mêmes bits de code, mais juste avec quelques autres intrigues et rebondissements à elle. Donc ici, je vois créer des détails de type feuille et je fais le mappage. Et puis je vois Obtenir la réponse du post. Donc, la raison pour laquelle je dois faire cela est de rappeler que nous avons mis à jour notre appel API pour retourner cette réponse de commande. Les autres que je renvoie du contenu nul, n'est-ce pas ? C' est pourquoi il n'y a que des tâches. Mais dans le cas de la création, nous recevons des commentaires après l'appel. Donc, nous obtenons une meilleure réponse, qui est la réponse de la commande bs. Donc, le client de service a réellement généré ce verre pour nous d' imiter la réponse de la commande de base provenant de l'API. Alors rappelez-vous à ce stade que nous ne savons toujours rien sur AICPA n'a pas été interagi avec l'implémentation de la réponse de base réelle que nous avons fait tout le chemin vers le haut dans notre couche d'application. Tout cela se fait ici, dans le client. Donc, fondamentalement, la non-réponse aide buck après que nous faisons une tentative de post. Et rappelez-vous que c'est opposé à la tentative, même s'il pense que ce n'est pas nécessairement un échec parce qu'il aurait pu échouer pour des raisons de validation, mais qu' il recevrait toujours environ 200 réponses, n'est-ce pas ? Donc, le try catch, et juste pour revenir un peu, le try-catch ici est vraiment que si le client de service est configuré d'une manière que si la réponse n'est pas un 200, alors il le voit comme une exception, c'est pourquoi nous faisons cette conversion. Sachez dans le cas de la, le Create, nous aurions pu obtenir une réponse 200 avec cette réponse de commande de base, mais alors ce n'est pas réussi. Donc on revient, ok, http wise. Mais l'opération elle-même n'a pas réussi, donc le moteur nous dit qu'il n'a pas réussi. On a écrit ce moteur pour qu'on le connaisse bien. Mais dans le cas où vous consommez une API tierce chez nous, à ce stade, ils auraient dû vous indiquer clairement que vous pourriez obtenir un 200, mais vous devez toujours vérifier cet indicateur si c'est vrai ou faux. Donc, dans ce cas, si elle réussit, alors nous équipons notre réponse, c'est notre réponse locale de type int. Nous équipons les données avec l'ID. Rappelez-vous que nous avons parlé de cela, retournant l'identifiant de l'enregistrement nouvellement créé, puis le succès est vrai. Donc, localement, nous savons que notre tentative de création a effectivement été couronnée de succès. Sinon, nous n'allons pas obtenir toutes les flèches qui auraient été empaquetées dans cette réponse de commande de base avec celles-ci, avec les erreurs de validation. Et puis nous les mettons dans notre réponse locale et les empilons. Et puis nous retournons cette réponse pour qu'elle soit vraie ou fausse ou retourne cette réponse. Et encore une fois, nous attrapons toutes les exceptions qui auraient été lancées. Donc, maintenant que nous avons une procédure pas à pas tous combattu, notre code d'implémentation de service ressemble à. Et bien sûr, cela est encore imprégné de changements dans un environnement agile. Vous pouvez le faire d'une façon et dans le gingembre sur la route parce qu'il y a autre chose qui va bien. Mais pour l'instant c'est ce que nous avons. Donc, l'étape suivante serait de commencer à créer nos contrôleurs. Et le contrôleur que nous commençons serait bien sûr pour les types de feuilles. Vous pouvez donc aller de l'avant et cliquer avec le bouton droit sur les contrôleurs, cliquez sur Ajouter un contrôleur Et je vais juste faire un contrôleur MVC avec des options de redirection. Allez-y et ajoutez-le, et nous allons l'appeler contrôleur de type feuille. Donc sachez que le contrôleur a été créé. Le premier ordre du jour serait de mettre en place l'injection. Donc, nous voulons injecter notre service de type Je vais quitter et nous pouvons, bien sûr, aller de l'avant et ajouter des références manquantes. Donc, je laisse le service de type est nul dans notre contrôleur. Commençons par le facile, je vais dire les pages les plus faciles à mettre en marche. Comment nous pouvons commencer avec la page d'index. Moyen si facile de créer la page d'index. Vous pouvez simplement cliquer avec le bouton droit, cliquer sur Ajouter une vue. Et nous voulons augmenter leur indice de vue. Nous voulons le modèle de liste. Et puis il devrait être une liste relative au type, type feuille de VM. Donc, vous pouvez aller de l'avant et ajouter cela. Une fois que vous aurez fait ça, vous aurez cette vue. Très bien, donc c'est gentil et simple. Et si vous êtes habitué à MVC, alors ce n'est pas une véritable tâche pour vous. Donc tu sais ce que c'est. Et parce que nous n'utilisons pas un EOF, notre objet de domaine, certaines choses que nous aimons envoyer de l'argent, que ce soit cette section où il demande la clé primaire, alors disons l'ID point de l'article. C' est pourquoi nous utilisons la VM de type feuille, qui a tous les champs par opposition au créateur, les autres, parce que nous avons certainement besoin de l'ID pour cela et aller avant et mettre à jour ces liens afin que édite les détails et la suppression. Savoir où obtenir l'ID quand nous devons naviguer. Si vous voulez épineter l'interface utilisateur de Non, Vous pouvez également supprimer les champs id parce que vous et moi savons que nous n'avons pas nécessairement besoin de ceux dans les opérations quotidiennes d'affichage des données. Sachez que l'interface est créée. Bien sûr, nous devons laisser l'interface N4 d'où il obtient ses données. Donc, cet appel va être assez simple, où tout ce que nous allons voir est le modèle VAR est égal au poids. Le dépôt de type feuille git types de feuilles, qui est ce que nous venons d'examiner l'implémentation pour. Donc, il l'appelle les types de laisser, ce qui provoque ensuite l'API et retourne la version mopped. Donc, une fois de plus, nous faisons la promotion des contrôleurs minces ici parce qu'il voudra faire toute la logique ici, vous savez, faire l'appel d'API, faire le mappage, puis revenir dans la vue. Nous voulons faire tout ça ailleurs. Donc, le contrôleur sait juste, appelez cette méthode, obtenez les données, puis continuez avec la vie. Cette ligne rouge est parce que nous devons faire de cette méthode une option résultats. C' est une tâche et un évier, non ? Donc, si vous vouliez vraiment passer à travers et faire tout ça parce qu'ils vont tous faire des appels asynchrones. Donc, juste pour réduire la probabilité d'obtenir ces flèches, allez-y et changez tout en un résultat d'action AsyncTask. Et puis c'est tout pour l'index. Alors prenons cela pire été avant que je le fasse, laissez-moi aller à la mise en page et ajouter une URL pour cela. Donc, je suis juste en train d'ajouter un nouvel élément de menu qui dit est B dash Controller types est l'action est index et ce sont des types def. Alors courons et voyons. Je suis désolé, avant de courir, avant de courir, j'ai échoué à mentionner que nous devons laisser le client et la flèche API et simultanément. Donc, qu'est-ce que vous devez faire est de cliquer avec le bouton droit de la souris sur cette solution et aller dans Propriétés. Et puis vous iriez au projet de démarrage et le changer en plusieurs projets de démarrage. Nous avons donc besoin de l'APA pour commencer. Nous avons besoin de MVC pour avoir aussi commencé. Si vous voulez que je commence par notre débogage. Donc, il faut, vous avez besoin d'un temps plus court pour commencer. Secant est aller de l'avant et cliquez sur Démarrer. Donc maintenant notre application est en marche, elle est en cours d'exécution et tout ce que nous devons faire maintenant est de sauter par-dessus pour laisser les types. Et il y a nos données qui proviennent directement de notre base de données. Eh bien, on ne sait pas. On se fiche de ce point d'où ça vient. Nous savons juste où appeler une API, lui demander les données et cela, nous l'affichons ici. Donc tout se passe hors de la boîte, non ? Bien sûr, en arrière-plan, en tant que développeurs d'API, nous connaissons tous les mots que nous mettons avec un gestionnaire et tout ce que nous savons d'où viennent les données. Nos deux clients ne savent pas. D' accord, alors nous voulons être en mesure de créer. Donc, nous devons créer notre scuffled qui crée la vue. Pour ce faire, encore une fois, tout ce que nous avons à faire est d'aller à View, cliquez avec le bouton droit Ajouter vue, vue rasoir. Et puis nous voulons créer des modèles. Et le modèle ici serait la machine virtuelle Create leave type, puis vous allez de l'avant et ajoutez cela. Donc, une fois que vous avez ajouté la vue et que vous obtenez le fichier physique, le code que nous devons écrire ici est double. Donc un pour le get, nous n'avons pas besoin de code parce que nous ne chargeons que le formulaire, n'est-ce pas ? Donc c'est déjà, il a déjà créé ce formulaire sachant qu'il devrait être relatif aux champs qui sont ici. Nous avons donc le champ pour le nom du fœtus pour les jours par défaut. On n'a pas besoin de faire autre chose. Donc, à moins que tu aies quelque chose de spécial, c'est bon. Mais au niveau de base, rien d'autre n'est nécessaire. Cependant, sur la poste, c'est là que la magie doit se produire. Donc ce que nous devons faire maintenant, c'est à notre poids, notre appel à l'opération de type feuille. Et bien, avant même d'y arriver, nous devons nous assurer que nous recherchons le bon type de données, n'est-ce pas ? Donc, je vais appeler cette feuille de création à VM et laisser le type. Allez-y et incluez les références manquantes. Donc, créez feuille à type feuille VM. Nous allons essayer d'obtenir une réponse de la feuille que le point de dépôt crée le type feuille. Et puis si notre opération est réussie, alors nous pouvons rediriger vers l'index. Très bien, alors regardez cette valeur nulle. Si nous faisons cet appel, Si c'était un succès, alors nous pouvons opérer comme si c'était un succès. Que se passe-t-il quand il a échoué ? Donc, quand cela échoue, nous voudrions, bien sûr, ajouter nos erreurs de validation à l'interface utilisateur. Donc les flèches seraient revenus avec la réponse. Vous pouvez donc dire des états de modèle, des modèle, des erreurs de validation de réponse. Et à la fin de tout cela, nous retournons juste la vue. Donc, nous allons le modifier un catch pour ne pas retourner la vue a un fait brouillon je vais modifier le catch, le catch une exception réelle, et ensuite nous pouvons ajouter cette exception. Donc c'est à votre discrétion. Bien sûr, cela dépend de l'expérience que vous voulez que votre utilisateur ait, car vous ne voulez pas nécessairement qu'il voit les détails de cette exception. Vous pourriez probablement simplement mettre quelque chose qui dit que quelque chose a mal tourné, veuillez contacter votre administrateur. Mais à la fin de cette opération, vous voulez retourner la vue. Et vous pouvez même remettre les données de type feuille qui viennent d'être soumises. À la vue de sorte qu'il ait tout ce qu'il faut afficher à l'utilisateur. Alors prenons celui-ci pour un spin art afin que nous puissions exécuter l'application, sauter sur notre Create. Et je vais créer avec compassion avec le nombre par défaut de ces Sten. Disons que j'ai fait une erreur et que j'ai mis trop de zéros. Et puis je clique sur Créer. Vous verrez ici que nous récupérons notre message de validation. Et je suis sûr que ce message a l'air très familier. Je n'ai pas tapé ce message depuis que j'ai construit cette interface utilisateur. Cela provient directement de l'API. Donc, ceci est juste pour vous montrer comment les informations ont voyagé à partir de l'API et comment nous pourrions être divisés à l'utilisateur que l'APIC, Ceci est illégal. Maintenant, vous avez deux options en matière de validation. Vous pouvez vous fier à l'API pour toutes vos validations et vos messages et ainsi de suite. Mais alors la chose est que vous à une API est facturé par appel. Très bien, donc dans cette situation où vous construisez probablement sur une API que vous ne voulez pas trop de trafic ou utilisateurs de l'API disent que vous avez fait sur trop de trafic ou votre limité ou quelque chose. Eh bien, vous pouvez faire est d'utiliser la documentation de l'API et d'appliquer la validation du côté client. Donc, ce message provient directement de l'API. Bien sûr. Ce qui signifie alors qu'un appel d'API a été fait, un processus a été fait, et il a tiré buck avec ce message. Tout cela aurait pu être évité si j'ai lu la documentation en tant que développeur d'applications clientes et mis en place mes propres règles de validation du côté client. Donc, cela n'arriverait même jamais à l'appel API tant que cela n'est pas valide par les normes du client. Maintenant, il y a des micros. Sur la base de votre intuition, vous devrez le faire d'une manière ou d'une autre. Mais pour l'instant, nous laissons l'API faire la validation. Et puis je pense qu'il est toujours bon de construire la validation dans l'API parce que c'est la dernière ligne de défense avant, ou du moins dans les centaines plutôt, c'est la dernière ligne de défense avant qu'elle n'obtienne la base de données. Donc, juste là, vous voulez vous assurer que seuls les éléments valides obtiennent la base de données. Vous pouvez cependant encourager vos utilisateurs API à suivre les règles de validation. Donc la combustion au nombre par défaut de ces 10 contre, continuer avec la création et regarder cela. Nous avons un tout nouveau type de feuille, donc la création a fonctionné, puis une page d'index chargée, rechargée et nous sommes de retour ici. Ne vous gênez pas de l'identité. Des expérimentations ont continué. Buck dans les deux au moins, nous sommes convaincus que cela fonctionne. Quelqu' un est revenu et a dit avec compassion que ça devrait être 15 jours. Et tout ce dont nous avons besoin pour aller de l'avant et édité. Et toute la première étape est de créer réellement la vue. Donc, voir directement à l'édition de vue. Et nous savons que nous utilisons l'édition et la machine virtuelle de type feuille. Et puis une fois que vous aurez tout cela en place, vous pouvez aller de l'avant et ajouter. Et puis dans l'édition que vous remarquez, tout comme avec create, nous avons deux méthodes. Nous avons le poste et nous avons les get, connaissant le Get. Cela signifie qu'il doit obtenir le nécessaire pour être édité. Eh bien, comment on peut obtenir ce record ? Nous savons déjà comment obtenir une liste d'enregistrements. Nous avons cherché à obtenir un seul enregistrement pour l'instant, mais peu importe ce que nous avons le droit d'obtenir le seul enregistrement ici est peu près le même cool d'avoir à écrire pour obtenir le seul enregistrement ici. Donc, ce que nous allons faire est de dire que le modèle var est égal à 08 point de dépôt de type feuille obtenir les détails de type feuille. Ainsi, les détails afficheraient tous les champs nécessaires à une opération de mise à jour. L' ID, le, vous savez, les champs, tous les champs, le nom des noms des champs échappent à Marino, mais nous récupérons tous les détails pour le type de feuille qui est sur le point d'être édité, alors nous sommes retournant la vue avec ces données. Alors que j'ai fait cette année pour les modifications, je vais vraiment le faire à nouveau pour les détails parce que c'est la même chose. Détails. On a les détails. Nous arrivons à l'ID, le passons, puis nous retournons la vue avec ces données. D' accord, alors on va de l'avant et on fait ça, édite pour le get. Et puis pour le post va regarder un peu similaire à notre Create sauf que nos paramètres devraient avoir l'int id et laisser le type VM. Très bien, donc ID feuille type VM et ils essayaient d'obtenir une réponse de notre type feuille de mise à jour. Et puis nous passons l'ID et l'objet à éditer. Et si cela a réussi, alors nous sommes retournés à l'index. Sinon, nous avons simplement la chaîne de daisy et toute l'erreur de validation, tout comme nous l'avons fait avec la création. Et puis nous retournons la vue avec les données qui ont été soumises. Alors commençons l'opération d'édition et hors du bus, vous pouvez voir qu'il y a des frais dont nous n'avons pas besoin. Par exemple, nous n'avons certainement pas besoin d'afficher l'ID de cette manière, de manière additive à l'utilisateur Cela ne va même pas fonctionner. Ou l'API rejetterait tout à fait cela. La base de données rejetterait pour répandre le nom. Nombre de jours par défaut. C' est tout ce qu'on a dit. Nous devions changer le 15 et je suis juste curieux de voir ce qui va se passer exactement si je tente ceci, si je clique sur Enregistrer, d'accord, donc je reçois cette Mme de valeur ne peut pas être nulle. La valeur ne peut pas être nulle. D'accord ? Laissez-moi revenir à 10 et laissez-moi cliquer sur Enregistrer. D' accord, donc ça a marché. Permettez-moi de revoir ce que ce message signifiait. Si les données ne sont pas valides. Rappelez-vous que notre gestionnaire qui s'occupe de la mise à jour, n'est-ce pas ? Non, c'était, ou du moins à l'origine, conçu pour lancer l'exception de validation lorsque les données étaient invalides. Donc sauter sur ce gestionnaire fait un QI et voir ce que je voulais dire. On n'a rien rendu. C' était juste l'unité ou à laquelle nous avons expliqué n'était que quelque chose à dire. Tout va bien. Mais alors, lorsque le résultat de validation était invalide, nous avons lancé une nouvelle exception de validation. Maintenant, cette exception de validation n'a pas été gérée. Nous n'avons pas écrit de citation réelle pour gérer ce qui se passe lorsque notre gestionnaire lance une exception hold l'API traite avec elle et comment tout le reste descend. Donc, entre le gestionnaire qui lance l'exception, l'AICPA et automatique étant la gestion globale des erreurs pour savoir quel type de réponses en buck. Et puis la subvention de service n'étant pas en mesure de comprendre quel genre de réponse il s'agit, alors nous obtenons ce genre d'erreur. Donc techniquement, vous ne seriez pas nécessairement tout ce que vous ne vouliez pas du tout l'utiliser pour voir une erreur comme celle-ci. C' est en fait l'erreur qui revient de tout ce try catch et le message d'exception renvoyé dans la validation de l'état du modèle. Vous ne voudriez pas nécessairement l'utiliser pour voir ça. Mais plus tard, quand nous regardons la gestion globale des exceptions verra comment nous pouvons mieux ou fournir une meilleure rétroaction lorsque des exceptions sont lancées à travers le gestionnaire ou à travers l'API tout le chemin vers l'interface utilisateur sans que nous ayons pour compenser trop de scénarios. D' accord, mais pour tout, nous voyons réellement que la validation fonctionne dans une certaine mesure , elle échoue parce que si je mets un point d'arrêt ici dans ce gestionnaire, et puis je clique sur Enregistrer à nouveau, Oh, noix en mode débogage. Ou nous pouvons le faire plus tard, mais vous pouvez essayer de mettre un point d'arrêt à l'intérieur du gestionnaire. Essayez cela, voyez si vous voyez qu'il frappe la validation n'est pas là. Désolé, la validation est fausse. Et puis il va jeter le dollar d'exception. Et si vous passez à travers et le suivez en bas de la ligne, vous verrez pourquoi tout cela équivaut à ce message très vague. Cependant, nous voyons que l'édition fonctionne correctement. Et prochain arrêt. Nous avons déjà examiné le détail afin que vous puissiez aller de l'avant et générer la vue détaillée. J' ai déjà le mien, et vous verrez qu'entre le code que nous venons de mettre dans le contrôleur et vous générez la vue, vous pouvez voir les détails. Donc, le suivant serait supprimé. Sachez pour la suppression généralement stockée en deux étapes dans les applications MVC, non ? Donc, généralement, vous obtenez l'enregistrement et l'afficher à l'utilisateur comme dans une vue de détails et dites, êtes-vous sûr de vouloir supprimer cet enregistrement ? Et puis ils diraient oui, puis il soumet essentiellement un formulaire. C' est donc un moyen très sécurisé ou la meilleure façon de le faire. Laissez-le soumettre le formulaire. Donc un port il par l'anti-falsification Tolkien et il transporterait cette opération de suppression. Non, ce que je ferais, ou il y a plusieurs façons d'aborder cela. Mais ce que j'ai fait plusieurs fois est au lieu d'utiliser à la fois le bon et le post, j'ai juste le post, non ? C' est donc à quoi ressemble ma méthode de suppression. Et si vous regardez, vous voyez qu'il ressemble beaucoup à la, tout le reste que l'éditeur et le Créateur autre. Donc nous essayons, nous obtenons la réponse. Si cela réussit, nous redirigeons vers la page d'index, puis je retourne juste une requête d'octets. Donc, la plage, l'application se sentirait juste, mais nous verrons comment gérer cela plus tard quand nous regardons nos modifications pour null, cependant, sur la page d'index, ce que je ferais est au lieu d'avoir ce lien axone, En fait, je les envelopperais dans une ferme. Encore une fois, il y a plusieurs façons de le faire parce que certaines personnes ont la forme qui passe par et par le passé. Certaines personnes ont un formulaire et utilisent JavaScript pour le voir lorsque vous cliquez sur le bouton Supprimer, puis supprimez la batterie. Mais maintenant, je vais juste garder ça assez simple pour passer à travers ça. Il s'agit donc d'un bouton de suppression. Bon, donc je ne voulais pas t'ennuyer avec ma dactylographie, alors je suis allé de l'avant et j'ai fini le top. Donc notre formulaire ressemble à ceci, où formulaire est Option, Supprimer est B tiret, ID de route est item.name. Utilisation de ce signe pour faciliter l'utilisation. Et la méthode est égale à post. Donc, entre ces trois saura qu'il devrait cibler la méthode post de nom axon et passer cet ID. Donc, alors il sait post et supprimer avec cet ID. Et ce qu'il faudrait faire, c'est mettre dans le bouton haut. Donc, le type de bouton soumettre et je lui ai donné la classe btn, btn ligne pointillée. Donc, il ressemble aux deux autres liens, donc il a l'air uniforme. Personne ne saura jamais que c'est avorter et à moins qu'ils ne vont vraiment dans le code pour voir. Et puis onclick, nous revenons sur la fenêtre ferme. Êtes-vous sûr de vouloir supprimer ? Et puis nous passons dans le mot supprimer. Jetons donc un coup d'oeil à ce que cela rend. D' accord, donc c'est ce que nous ne sommes pas tout à fait alignés. Nous pouvons corriger cela plus tard, mais le fait est que nous obtenons ce bouton de suppression. Donc j'en ai un très aléatoire ici. Je pense que quelqu'un essayait d'usurper le système et qu'ils y entrent, donc c'est bon. Supprimons ça. Êtes-vous sûr de vouloir supprimer cet enregistrement ? D' accord. Et puis vous voyez tout s'est passé. Ce bilan n'est plus là. Cela signifie donc que notre opération de suppression a fonctionné avec succès. Et avec cela fait, nous venons de terminer la foule pour nos types de feuilles via notre interface utilisateur. D' accord, donc quand nous reviendrons, nous verrons comment nous pouvons terminer les autres opérations spécifiques avec les demandes de congés et les allocations de congés. 31. Ajouter une authentication Json Web Token (JWT): Hé les gars, bienvenue. Dans cette leçon, nous allons parler de l'authentification. Maintenant, l'étape logique suivante suivant ou le réglage de l'interface utilisateur de type feuille aurait été de régler l'allocation feuille et les interfaces utilisateur de demande de congé. Mais ensuite, ce plan est que pour allouer des congés ou des demandes de congé, nous avons besoin d'utilisateurs ou d'employés. Donc le seul moyen pour que l'employé voie le système, c'est s'ils se sont connectés et qu'on sait qui ils sont, c'est sa femme. L' authentification doit venir avant ces deux autres fonctionnalités. Donc, je suis allé de l'avant et l'ai mis en œuvre parce qu'il y a un peu de code à écrire et je ne veux pas vous ennuyer en me regardant taper. Donc, bien sûr, je vais y passer très lentement pour que vous puissiez faire une pause, répliquer et expliquer tout ce qui est là qui doit être compris. Non. En dehors de cela, j'ai swagger où j'ai implémenté l'authentification JWT, donc je l'ai juste pour que vous puissiez obtenir un aperçu de ce que l' authentification JWT est vraiment au cas où vous n'en seriez pas très familier. Donc, laissez-nous J, W et T sont courts pour JSON Web Tokens. Et ce qu'ils sont est juste comme un paquet, juste une chaîne plate qui est encodée. Mais dans cette chaîne codée sont ce que vous appelez des bits d'information sont des revendications qui permettent à l'accord D et de savoir qui est l'utilisateur. Aucun JWT n'est largement utilisé dans la fraternité API comme norme de sécurité car il permet l'authentification sans état. Autrement dit, lorsque vous vous connectez, vous ne vous connectez pas vraiment à une couche API accédant à l'API. Mais si c'est beaucoup os ou protégé et que vous vous authentifiez sur l'API et qu'ils identifient fondamentalement qui vous êtes, puis envoyez ce jeton avec toutes les informations sur qui vous êtes. Donc, l'application cliente doit maintenant voir chaque fois que j'utilise l'application cliente et que je demande des données de l'API, elle doit inclure ce jeton avec mes informations de sorte que chaque fois que l'API est appelée, quand elle voit ce jeton, il le décodera, vérifiera que cette personne est valide et pourra ensuite exécuter sur la requête. Donc juste une démonstration rapide ici, je vais essayer de me connecter. J' ai donc déjà modifié swagger, j'ai déjà modifié l'API avec les points de terminaison de connexion et d'enregistrement et nous allons passer par cela. Mais j'ai également mis dans certains exemples d'utilisateurs. Et je vais juste aller de l'avant et montrer à quoi ressemble le jeton. J' exécute donc une demande de connexion avec l'un de mes utilisateurs. Et vous voyez ici qu'il retourne un 200 avec cette réponse de jeton, n'est-ce pas ? Donc, j'obtiens l'ID de l'utilisateur, le nom d'utilisateur, l'e-mail. Et c'est ce JWT ou jeton, non ? Donc, il s'agit essentiellement d'un véhicule avec toutes les informations nécessaires pour m'identifier. Donc juste pour vous montrer ce qui arrive dans ce jeton, je vais sauter sur JWT point IO, qui est un outil gratuit cool que vous pouvez utiliser pour coller votre Tolkien juste ici. C' est une forme encodée, puis à droite il sera essentiellement tout ce qui est dans ce jeton. Donc sujet, c'est l'adresse e-mail, GTI, qui est l'identifiant JWT. Oui, l'e-mail, vous avez, l'ID utilisateur, les rôles que l'horodatage d'exploration, l'émetteur, et le public. Donc, vous pouvez mettre plus de choses. Ce ne sont que des choses de base que ce jeton que nous générons va avoir. Mais à l'avenir, vous pouvez mettre plus de choses et mettre toutes les informations que vous jugez nécessaires pour que votre application ou votre API fonctionne. Commençons maintenant dans notre art de code. Donc, tout d'abord, je vais attirer votre attention sur, et je vais juste effondrer tout ce qui n'est pas absolument nécessaire à la, à la conversation à portée de main afin qu'il soit moins déroutant. Donc, dans notre projet d'application, vous voulez ajouter un nouveau dossier dans le dossier de modèles appelé identité. Sachez lors de l'ajout de ce dossier qui dit que j'aurais dû mettre les paramètres e-mail et e-mail dans un dossier pour eux-mêmes, mais nous pouvons le faire plus tard. Mettez-les dans un dossier appelé e-mail ou mail, quelque chose comme ça. Mais pour une identité de tous les modèles et ensuite nous avons ces nouveaux fichiers. Donc, nous avons une demande d'authentification, qui est fondamentalement juste e-mail et mot de passe. Nous venons de voir que lorsque nous nous connections via swagger, nous avons mis l'e-mail, mis le mot de passe, puis nous le soumettons. C' est donc à quoi sert la demande d'authentification. La réponse d'Auth est ce que nous avons obtenu buck à travers swagger, l'ID, le nom d'utilisateur, l'e-mail et la chaîne de jeton. Très bien, les paramètres JWT, cela doit le faire est similaire aux paramètres e-mail. Rappelez-vous que nous voulons les paramètres de messagerie de la partie du fichier Up settings.js ON qui nous a donné tous les paramètres nécessaires pour l'e-mail. Eh bien, c'est ce qui va se passer avec les paramètres JWT. Nous allons donc avoir un problème clé ou une audience et une durée en minutes, tous référencés dans le fichier de paramètres UP de notre API. Maintenant, comme tout ce que nous avons la demande d'authentification, nous allons avoir la demande d'inscription. Si souvent est court pour l'authentification, je viens de l'raccourcir, mais vous pouvez être explicite et dire l'authentification. Mais la demande d'inscription va nécessiter le prénom, le nom, l'adresse e-mail, le d'utilisateur, ainsi que le mot de passe. Donc, tous ceux qui s'inscrivent sur le haut et le nouvel employé qui vient dans l'entreprise leur diront, vous pouvez encore remuer. Vous devez fournir ces informations. Et puis la réponse de redistribution va vraiment juste repousser avec l'ID utilisateur. Donc, après que cette personne s'est inscrite dans le système, nous envoyons juste l'ID utilisateur. C' est tout ce qu'il faut. Non, en dehors de ça, nous voulons aussi un nouveau dossier dans notre dossier Contracts, et je l'appelle identité. Et nous voulons le service d'authentification. Nous allons donc avoir un nouveau service où nous avons la connexion de réponse de l'auteur de la tâche. Et il prend cet objet de requête de la demande d'authentification. Et puis nous en avons un pour la distribution qui nous donne la réponse d'enregistrement. Et il y a une quête de redistribution. Et c'est vraiment tout ce qui est nécessaire pour l'application. Donc, vous pouvez aller de l'avant et passer en revue si vous en avez besoin. Bien sûr, faites une pause pendant que vous allez le long pour vous assurer que vous obtenez tous ces fichiers et les champs requis. Et notez les attributs de validation qui sont sur la demande d'enregistrement car nous voulons nous assurer que nous respectons les normes minimales. Notre prochaine tâche ne nous fera pas ajouter un tout nouveau projet dans le dossier de l'infrastructure ICT appelé Identity Art. Donc, le point de gestion des RH identifie le nom, et nous voudrions que celui-ci soit un point dedans, cinq. Donc je vais vous expliquer celui-là. Oui, nous utilisons dotnet standard pour la plupart des bibliothèques de classes. Mais dans ce cas, nous allons avoir besoin de certaines bibliothèques qui ne peuvent tout simplement pas fonctionner avec une bibliothèque standard dominante. Donc, nous voulons dotnet fire afin que nous ayons 0 problèmes de compatibilité. Et bien sûr, cela se poursuivrait dans les futures versions de celui-ci. Donc, vous pouvez aller de l'avant et ajouter ce nouveau projet. Je l'ai déjà ici. Et dans ce nouveau projet, nous allons avoir quelques nouveaux dossiers. Nous allons avoir des configurations, des migrations, des modèles et des services. Nous avons de nouveaux fichiers où nous avons la redistribution des services d'identité. Nous sommes familiers avec cela où nous sommes assis sur ce fichier d'enregistrement à appeler à partir de l'API. Et nous avons aussi notre propre contexte DB. Donc, je vais commencer avec un contexte DB parce que c'est probablement le plus facile. Donc, dans le contexte DB, nous avons l'identifiant de gestion des congés de classe publique, l'identité, les contextes DVI héritant du contexte DB d'identité. Notez ici cependant que nous tapons le contexte DB d'identité. Donc, j'aurais pu le faire, mais j'ai une classe de remplacement spéciale pour mes utilisateurs. Donc, de manière générale, l'utilisateur d'identité n'a pas de frais supplémentaires comme FirstName et LastName. J' ai donc cette classe d'utilisateur d'application que j'ai créée dans le dossier models. Et il hérite de l'utilisateur d'identité. Donc, il a deux champs. Prénom, Nom. Dans votre situation, il se peut que vos utilisateurs aient besoin de plus d'informations sur ces prénom, nom et adresse e-mail. Et donc peut-être que vous voulez la date de naissance, vous voulez d'autres champs. Vous pouvez ajouter tous ceux ici. Mais tant que vous héritez de l'utilisateur d'application d'identité utilisateur peut être utilisé pour remplacer l'utilisateur d'identité et l'opération liée à l'utilisateur. Celles-ci vous donnent accès à tous les champs nécessaires. Donc, en revenant au contexte DB, nous avons le même type de constructeur que vous auriez vu dans notre contexte DB précédent, où nous prenons les options de contexte DB et ce sera Pâque via l'API dans le bouleversement une fois de plus. Et puis nous avons le modèle sur la création. Donc cette fois, je ne fais pas ça, obtient l'assemblage. J' appelle les abeilles sur la création de modèles. Et puis je les appelle un par un. Dans la pratique n'a même pas d'importance. Alors continuons. Nous avons donc la configuration de la règle, la configuration de l'utilisateur et la configuration du rôle de l'utilisateur. Donc, c'est là que je suis en train de semer ces bits de données lors de la génération de cette base de données. Alors rappelez-vous que j'ai dit que les utilisateurs générés avant. Donc, si nous passons au dossier configurations, vous verrez la configuration du rôle où j'ai la configuration règle héritant du rôle d'identité de configuration de type d'entité I. Maintenant celui-ci est configuré pour configurer de nouvelles règles. Nous avons l'ID, le nom de la règle et l' ID de nom normalisé. Cela doit juste être en bonne et vous pouvez aller chercher notre bon Dino aléatoire, générer un en ligne, c'est bon. Vous pouvez l'utiliser là-bas. Vous n'avez pas à utiliser le même. J' ai acheté. Ils doivent être bons. Ainsi, nos tables d'identité n'utilisent pas d'entiers comme ID. Une fois les rôles terminés, vous voudrez prendre soin des utilisateurs. Donc, les utilisateurs, il y a un peu plus, mais c'est vraiment juste un peu plus parce qu'il y a plus à remplir, mais c'est pratiquement le même concept, configuration utilisateur héritant d' une configuration de type d'entité relative à l'utilisateur de l'application. Et puis dans notre méthode de configuration, nous avons var Hampshire est égal à nouveau mot de passe Hampshire, relatif pertinent, désolé pour l'utilisateur de l'application. Donc, cela va être utilisé pour hacher le mot de passe. Donc, nous remplissons les utilisateurs de l'application une fois de plus obtient un bon, nous donnons celui-ci l'e-mail et e-mail et normalisé e-mail et nom d'utilisateur, nom d'utilisateur non normalisé, ils sont tous les mêmes. La seule différence est que les versions normalisées ont toutes les majuscules. Si vous êtes familier avec l'utilisateur d'identité, alors je ne le ferai pas, je ne veux pas vous ennuyer, mais vous voyez un peu que je remplis tous les champs en conséquence. Et puis pour le hachage de mot de passe, j'utilise le HobShare pour hacher le mot de passe null pour le premier paramètre. Nous n'avons pas besoin de transmettre l'utilisateur de l'application. Évidemment, on ne peut pas parce qu'on est en train d'en créer un. Mais nous allons hacher le mot de passe, non ? Donc, j'utilise simplement mon mot de passe par défaut spécial qui répond généralement aux exigences minimales pour créer notre utilisateur dans l'identité. Donc, nous avons celui-là pour l'administrateur et ensuite nous en avons un autre pour un utilisateur régulier. Donc, après que nous avons nos deux utilisateurs sous deux règles, j'ai l'utilisateur ou la configuration, qui est à peu près I la configuration de type d'entité au rôle d'utilisateur d'entité. Et puis vous passez ce tapage pour une chaîne. Très important. Et puis nous avons deux nouveaux rôles d'utilisateur d'identité. Nous avons l'ID de rôle à l'ID d'utilisateur, ID de règle à l'ID d'utilisateur. Donc, ce rôle voit, je pense que c'est le rôle d'employé à l'utilisateur qui était censé l'employé, puis l'ID de rôle à l'ID d'utilisateur. Donc, parce que ce genre de doit arriver dans l'ordre, nous avons besoin de la règle que nous devons utiliser sont tous avant que l'utilisateur ou soit généré. Donc, je pense que c'est pourquoi je viens d'indiquer explicitement les configurations comme celle-ci. Donc, il ne lancerait pas cette course qui exécuterait ensuite ça. Maintenant, avant d'aller plus loin, je voulais juste 0 chansons les bibliothèques dont vous aurez besoin dans ces projets juste pour que vous ayez sur le dessus tant de lignes rouges. Donc, nous voulons nous assurer que nous avons une vitesse dotnet Core Authentication, JWT porteur, nous voulons une identité de base, identité Entity Framework, Core Entity Framework, Core dot SQL, les outils, les extensions pour les configurations Newton point JSON et modèle de ville system.out.print, JWT de Tolkien. Donc, vous avez probablement déjà inclus certains d'entre eux parce que lors la configuration du contexte DB et d'autres fichiers, vous auriez été invité à avoir besoin de certaines bibliothèques. Donc, si vous avez déjà cela, c'est bien, mais ce sont les bibliothèques dont vous aurez besoin dans l'ensemble. Au fur et à mesure que vous allez, vous pouvez simplement inclure les éléments manquants en utilisant des instructions et des références en conséquence. Alors passons à la mise en œuvre de notre service Auth. Nous avons donc le service d'authentification dans le dossier Contrats. Maintenant, nous avons la mise en œuvre. On est habitués à la colonne vertébrale. Bon, donc nous avons trois champs sont, eh bien, commençons par le constructeur et comment nous injectons le gestionnaire d'utilisateurs. Nous injectons le gestionnaire de connexion et nous recherchons des options pour la section appelée paramètres JWTS. Vous pouvez donc simplement aller de l'avant et créer ces trois champs. Et puis dans nos implémentations, nous avons la connexion et l'enregistrement, et nous avons quelques méthodes privées, mais nous allons juste les parcourir une par une. Donc, dans notre login où prendre la demande d'authentification, donc ils sont mémorables que cela va être appelé à partir de l'API en fait. Donc, quand quelqu'un frappe le point de terminaison de connexion ou quand j'ai frappé le point de terminaison de connexion, sachez juste que l'API appelle vraiment cette méthode qui a ensuite fait les vérifications et retourné l'art de réponse. Donc, nous essayons d'obtenir l'utilisateur, si l'utilisateur n'a pas à exister, nous lançons une nouvelle exception, Donc, nous utilisons des exceptions ici plus tard, nous allons examiner la gestion appropriée des exceptions, Gestion globale des exceptions pour l'API. Mais pour l'instant, nous allons juste utiliser les exceptions et nous allons affiner au fur et à mesure que nous allons le long. Donc, si l'utilisateur n'est pas trouvé, nous lançons une exception, pas pu trouver cet utilisateur. Si l'utilisateur est le téléphone, c'est bien. Mais on a essayé de les signer. S' ils ne pouvaient pas être enregistrés, ce n'est qu'une autre exception. Maintenant, s'ils passent tous ces chèques, la prochaine chose serait pour nous de générer leur Tolkien. Et c'est là que cette méthode privée entre en jeu, Générer un jeton. Donc, je vais juste sauter à cette méthode pour que vous puissiez voir exactement ce qu'est cette génération de Tolkien. Donc nous allons retourner la boîte à outils de sécurité JWT qui vient dans la bibliothèque pour le modèle d'identité JWT de Tolkien, n'est-ce pas ? Donc, vous pouvez, comme je l'ai dit, inclure toutes les instructions d'utilisation une fois que vous avez votre filature à peine. Invite Visual Studio. Aujourd'hui, vous devez référencer la bibliothèque d'effets. Donc, nous générons le Tolkien ou nous analysons dans l'utilisateur d'application qui a été appelé. Très bien, donc l'utilisateur est tombé ici et a pu se connecter. Donc nous passons sur cet utilisateur. On a les réclamations. Ainsi, les revendications peuvent être stockées dans la base de données. Les jeux, une fois de plus, sont des bits d'information sur l'utilisateur. Vous pouvez essentiellement stocker quoi que ce soit que je nettoie l'utilisateur dans un peu d'informations dont vous avez besoin pour que votre application s'exécute, vous pouvez les ajouter aux cris de l'utilisateur. C' est en dehors du cadre de ce cours, mais je vous donne juste une idée de ce qu'est vraiment une réclamation. Donc, il est hors informations sur l'utilisateur dans la base de données. Allons le faire rouler. Nous voulons toutes les règles car un utilisateur peut avoir plusieurs utilisateurs Rosa pourrait être un employé et un administrateur. Comme si je suis un superviseur que je pourrais avoir à être un superviseur bas aussi un employé afin que je puisse approuver les demandes de congé. Peut-être que ce que je peux également faire des demandes de congé parce que j'ai tous les deux raison, Donc les rôles peuvent avoir plusieurs rôles pour notre utilisateur obtient toutes les règles. Alors, nous allons maintenant créer une nouvelle liste de réclamations. Ensuite, nous allons ajouter à la liste des réclamations toutes les règles. Donc, vous voyez, nous ajoutons juste une nouvelle revendication appelée règles aux rôles sont en fait, il y a, laissez-moi me débarrasser de cette chaîne magique parce qu'il y a en fait une constante que nous pouvons utiliser pour nous assurer que nous obtenons le type de règle de panier Nino à éviter les fautes de frappe que nous avons déjà discuté pourquoi nous ne voulons pas de cordes magiques, n'est-ce pas ? Donc, je peux ajouter les types de réclamation rouleau de points et les types revendiqués est juste une constante qui a différents types de revendications qui sont principalement utilisés tout au long. Très bien, donc vous pouvez toujours donner votre propre nom pour propre, mais il y a certains standards que vous pouvez toujours rechercher et vous pouvez simplement regarder à travers et voir lequel est pertinent. Mais dans ce cas, nous ajoutons des rôles. Donc, je vais utiliser le type de réclamation pour roll. D' accord, alors je vais construire un autre IRI de revendications où je vois que le nucléon est égal à notre nouvelle revendication, est JWT enregistré noms revendiqués. Vous avez donc réclamé des types par rapport aux réclamations enregistrées par JWT. Donc JWT a enregistré des réclamations à peu près. Il s'agit de revendications particulières des T.N.-O. qui sont généralement utilisées pour les demandes en général. D' accord. Ce sont donc des normes DWT directes par rapport aux types de crème, ce qui n'est pas nécessairement lié à JWT, ce que ces utilisateurs ont lié. Vous pouvez donc les combiner car ils se répartissent tous au même type de réclamation. Nous avons donc les rôles et nous ajoutons des noms propres enregistrés DWT. Du savon. Le savon est abrégé pour le sujet. D' accord ? Et c'est en général, les utilisateurs, le nom d'utilisateur ou leur e-mail, tout ce qui est unique. Vous voyez GTA, qui est généralement juste une bonne chaîne, puis l'e-mail, qui est explicite. Ensuite, j'ajoute ma propre revendication ici où j'appelle l'UID ou l'ID utilisateur, qui est la valeur d'ID réelle de la base de données. Donc, vous voyez que vous pouvez construire vos revendications. Vous pouvez mettre autant de revendications, vous pouvez mettre vos noms personnalisés si vous le souhaitez. Mais même, même si j'ai une chaîne magique ici, je suggère que si vous avez plusieurs revendications personnalisées que vous devez ajouter, n'ajoutez pas les chaînes magiques, mettez-les dans une autre constante. Classmates est comment vous voyez les constantes ici, puis les référencez-les en conséquence. Donc, vous auriez votre constante comme les types propres personnalisés, l'ID utilisateur point, quelque chose comme ça. Et l'OMS après avoir construit cette zone, nous allons juste point union les revendications de l'utilisateur de la base de données et les revendications de rôle, et puis tout est maintenant dans cette IRI unique. Donc, en descendant un peu plus, ce que nous devons faire est d'encoder notre clé de signature. Ainsi, lorsque nous arrivons aux paramètres JWT, vous verrez qu'il y a une clé qui serait unique à votre application. Et il y a plusieurs façons que les gens utilisent pour stocker la clé dans ce paramètre. Nous allons juste utiliser settings.js, sun, certaines personnes le stockent comme une variable d'environnement. Je l'ai fait dans mon cours de développement d'API ultime. Vous verrez donc plusieurs façons de le faire. Donc tout ce qu'on fait ici, c'est de le signer. Et ce que nous voulons faire est également l'utiliser pour déterminer les informations d'identification de connexion. D' accord, donc entre ces deux lignes, nous avons les identifiants de connexion. Donc, ce peu de bruit de code où nous générons réellement notre jeton de sécurité. jeton de sécurité JWT est donc égal au nouvel émetteur de jeton de sécurité. Et cela vient de notre public de paramètres JWT. Cela vient aussi de nos paramètres et revendications que nous venons de construire à nous-mêmes, expire. Nous sommes en train de convertir de date-heure savoir où ajouter les minutes provenant des paramètres JWT. Encore une fois. Et puis nous ajoutons les identifiants de connexion, que nous venons de déterminer ici en utilisant cette clé de signature. Et puis nous rendons ce Tolkien. Donc, une fois que nous retournons ce Tolkien, voir beaucoup quand il est fait dans cette méthode. Après avoir tourné ce Tolkien, puis nous construisons notre réponse de l'auteur, qui a l'ID utilisateur, le jeton que nous venons de construire. Et prenez note de l'accord ici, nouveau gestionnaire de jetons de sécurité JWT point droit Tolkien et JWT sécurité Tolkien et l'e-mail et le nom d'utilisateur, et puis nous retournons cette réponse. C' était donc la réponse que nous avons obtenue de swagger avec l'ID, le Tolkien, l'e-mail et le nom d'utilisateur. Donc maintenant que nous avons fait tout ce travail entre les services et, vous savez, tout ce code qui saute vers les services d'identité ou un fichier de distribution où nous configurons les services d'identité. Donc, comme nous l'avons fait dans les temps précédents, nous allons avoir besoin de la collection de services IA et de la configuration I. Et en descendant, nous verrons les différentes sections. Donc, les services dot configurent par rapport aux paramètres JWT. Nous cherchons dans la configuration pour obtenir la section appelée paramètres JWT. Nous ajoutons des contextes RDB que nous connaissons bien. Donc, vous pouvez simplement copier, coller ce code, assurez-vous juste que vous référencez le bon fichier de contexte DB. Donc, il est de laisser les contextes Management Identity DB, qui est celui que nous venons de créer pour ce projet particulier. Et nous ajoutons SQL Server. Permettez-moi d'abaisser le quota. Vous pouvez voir que c'est un peu plus facile. Donc, les options qui utilisent SQL Server obtiennent la chaîne de connexion, et c'est ce que j'appelle la chaîne de connexion quittent la chaîne connexion Management Identity. Maintenant, le truc cool à ce sujet est que vous pouvez réellement avoir deux magasins de données entièrement différents. Si vous avez besoin d'un magasin de données pour vos applications distinct d'un magasin de données pour vos utilisateurs. Ensuite, c'est, C'est facile de les séparer parce que tout ce dont vous avez besoin est une chaîne de connexion pour une base de données et une autre pour une autre. Nous référençons l'autre chaîne de connexion. Donc, je vais réellement séparer ces banques de données et vous verrez cela dans quelques minutes dans les paramètres de l'application. Donc, si vous souhaitez utiliser la même base de données pour les deux, alors vous avez juste besoin de la même chaîne de connexion. Pas d'agitation. Nous spécifions également que l'assembly de migrations est dans le même assembly que le contexte DB, c'est pourquoi nous avons ce dossier Migrations. Nous avons également des services qui ajoutent de l'identité, où nous constatons que l'identité que nous ajoutons est l'utilisateur d' application pour la classe d'utilisateur d'identité et le rôle d'identité. Nous ajoutons le framework, le magasin Entity Framework pour être notre contexte DB qui vient d'être initialisé en haut. Et nous ajoutons des fournisseurs de jetons par défaut. Donc, cela ajoute que les fournisseurs de jetons utilisent pour générer pour réinitialiser les mots de passe G et Gmail, toutes ces choses. Bon, donc si vous devez faire cet outil, confirmer, envoyer un e-mail ou réinitialiser le mot de passe, ce genre de choses. Cette bibliothèque, nous allons faciliter ces fournisseurs de Tolkien pour vous. Nous sommes aux services et j'ajoute celui-ci comme transitoire parce que nous voulons un nouveau service d'authentification chaque fois qu'une demande arrive. Donc, ce n'est pas la portée cette fois. Ça m'en donne un nouveau à chaque fois. Et nous sommes juste contraignants ou, ou abstraction ou implémentation. Et puis nous arrivons aux services qui ajoutent l'authentification. Donc, ici, nous spécifions les options où nous avons des options non schéma d'authentification par défaut est JWT bière par défaut schéma d'authentification et par défaut schéma Challenge est la même chose. Bon, donc c'est comme ça que nous disons au schéma d'authentification d'utiliser JWT. Après cela, nous ajoutons les options de bière JWT où je vois les paramètres de validation de Tolkien sont en tant que tels. Dans les cours précédents où j'ai passé par WTI était district plus étroit, mais une fois de plus, le contexte détermine votre implémentation. Donc, pour nos paramètres de validation de Tolkien, je vais avoir besoin de valider notre clé de signature, l'émetteur, l'audience, la durée de vie, l'inclinaison de l'horloge, qui obtient nos réglages l'horloge lors de l'application d'un temps de validation. Par rapport à l'endroit où vous êtes, comment l'appliquer ? Heure de validation, validez l'EC désolé, émetteur divisé se trouve dans la configuration pour les paramètres JWT deux-points émetteur. C' est donc un bon moyen rapide d'obtenir une valeur spécifique de notre section de paramètres dans un fichier de paramètres d'application. Bon, donc nous recevons l'émetteur et l'auditoire à la fois de la section de réglage JWT de la configuration et de notre clé de signature de l'émetteur. Et nous avons vu quelque chose comme ça avant où nous faisons la signature des clés de sécurité symétriques pour cette clé qui se trouve également dans les paramètres JWT sous la clé de nom, puis nous retournons les services. D' accord, pas ça, mais maintenant que nous avons fait tout ça dans notre identité, nous pouvons le savoir, le brancher avec l'API. Donc, dans l'API, je vais commencer avec notre fichier de paramètres d'application. Donc, une fois de plus, nous avons deux chaînes de connexion. J' ai deux chaînes de connexion. Vous pourriez en avoir un si vous le vouliez. Pas de problème. Mais j'en ai un appelé RH gestion des congés DB, qui étaient habitués à. J' ajoute ensuite 14, l'identité que je viens d'ajouter sur l'identité carrée, non ? Donc, ce n'est vraiment pas si important, en fonction des besoins de votre entreprise, vous devrez peut-être les séparer. Un cas pour quand vous voudriez les séparer serait si nous avons plusieurs applications utilisant le même magasin d'utilisateurs. Donc, dans cette situation, vous pouvez vouloir une base de données autonome strictement pour les informations de l'utilisateur. Et puis les différentes bases de données sont relatives aux différentes applications. Mais toutes les opérations pourraient s'abonner au magasin d'un utilisateur et utiliser la même bibliothèque d'identité que je viens de configurer et les mêmes chaînes de connexion réglées. Chaque application pourrait en profiter assez facilement. Ce serait agnostique à qui interagit réellement avec elle. Donc, nous avons notre chaîne de connexion et plus tard ne sont pas dans le fichier, j'ai la section des paramètres JWT. Donc ici, j'ai juste une clé. Encore une fois, cette clé pourrait être n'importe quoi, ça pourrait être un mot, ça pourrait être quelque chose comme un mot de passe, mais ce n'est pas quelque chose que vous voulez que quelqu'un puisse deviner facilement parce que alors les gens pourraient usurper votre Tolkien s'ils connaissent votre clé. C' est pour ça que j'ai dit que parfois les gens ne le stockent pas dans les choses opposées. Ils le stockent comme une variable d'environnement ou comme un Secret d'application, autre chose. Mais pour l'instant, je le mets juste ici parce que c'est notre application, mais vous savez comment le stocker. Plus de sécurité doit être notre émetteur. Je vois juste chacun notre direction principale et le public serait l'utilisateur de gestion des congés RH. Et la durée est de 60 minutes, ce qui signifie que ce jeton est valide pour exactement une heure. Après une heure, vous aurez besoin d'un nouveau jeton, vous devrez vous connecter à nouveau. Donc c'est votre discrétion que vous vous asseyez cette fois. Certaines personnes le définiraient pour des jours, dépend de vous et de votre politique de sécurité. Maintenant, passons aux contrôleurs de cônes dans le contrôleur du côlon, j'injecte le service d'authentification oculaire. Et vous pouvez voir que c'est un contrôleur très simple. Souviens-toi, mince Gonzalez, c'est notre objectif, non ? Donc il n'y a en fait rien, pas de logique, pas d'opération sérieuse qui se passe ici. Nous sommes en train de mettre en œuvre les résultats à l'action. Celui qui renvoie la réponse de l'auteur sur bien que celui qui renvoie ou une distribution sur la réponse. Et puis, à peu près, on revient juste. Ok, je vais 18 le résultat de la demande de connexion. Encore une fois, dans notre service OSS scolarisé, nous jetons des exceptions. Donc, plus tard, nous verrons comment nous évaluons ces exceptions et avons des messages de retour appropriés lorsque notre application cliente appelle. Mais pour l'instant, c'est tout ce dont nous avons besoin pour nous connecter et nous inscrire. Et puis dans notre fichier de démarrage, qui est le deuxième à dernier bit auquel nous devons vraiment faire attention. Nous avons quelques changements en conséquence. Nous voulons donc que vous configuriez nos services d'identité. Et pour ce faire, nous devrons faire référence aux projets identitaires, non ? Donc, vous serez invité, ou si, si vous n'êtes pas invité, alors au moins ajoutez-le en tant que dépendance de projet lorsque vous en aurez la chance, et cela sera disponible pour vous. Donc, après que nous avons configuré nos services d'identité et d'autres changements que je veux souligner est trop swagger. J' ai donc changé ceci en une méthode qui va configurer le swagger car il y a peu de choses qui vont être différentes. Comme vous le remarquez, mon doc de football était légèrement différent des premières fois où nous l'avons utilisé. Et c'est pourquoi. Donc, avant d'arriver à cette méthode cependant, dans la configuration pour les middlewares, vous voulez ajouter l'authentification des tissus et vous voulez vérifier que vous avez utilisé des autorisations. Donc, vous voudrez vous assurer que vous avez ces deux-là. Si rien d'autre. À l'intérieur de cette configuration, tout est que vous devez rester inchangé. Connaissez les modifications apportées au document Swagger, et c'est juste la méthode privée implémentée ci-dessous. Donc si j'écrase ces deux-là, vous voyez le quai de football de la Ligue arabe. Il faut que je serve de collection. Donc, dans l'appel de méthode, nous passons dans les services et dans celui-ci, non, nous élargissons ce qui était juste les services qui avaient le football, Jen. Donc non, nous créons une configuration sur le sang où nous voyons la définition de la sécurité AD pour le porteur. Donc, cela signifie que nous disons à swagger que chaque fois que quelque chose est autorisé et nous arriverons à la partie de citation d'autorisation de l'API. Quoi, quand un point de terminaison est autorisé, alors exiger un jeton de porteur. C' est notre schéma de sécurité pour les tests qui autorisent le point de terminaison requis. Nous lui donnons juste cette petite description sur une navette verbiage, l'utilisateur, c'est ce que vous devez faire. Autorisation de nom. Dans l'emplacement de périmètre est l'en-tête. Donc, tout ce que nous mettons, qui est une bière, va dans l'en-tête de la demande. Et le type est une clé API, et le schéma est un miroir. Très bien, donc c'est tellement fendre Swagger. Sachez que si un paramètre est autorisé, une fois de plus, besoin d'une bière Tolkien, et c'est ainsi qu'il devrait être manipulé. Ensuite, nous ajoutons les exigences de sécurité là où nous voyons de nouvelles ouvertures. Une API de référence de schéma de sécurité ouverte API, Open API type de référence est un schéma de sécurité de type de référence nommé schéma porteur au nom bear. Donc, vous verrez beaucoup de choses qui se répètent. Alors, allez-y et ajoutez cette section. Et puis nous avons la même section Swagger doc où nous disons la version 1. Et le type est RH, gestion des congés, EPA et mettre un peu d'espace là. D' accord. Donc c'est à peu près tout. Donc, si je devais autoriser et flottante, donc vous m'avez vu utiliser l'API. Vous m'avez vu m'authentifier, mais vous ne m'avez pas vu autoriser et tester. Donc, c'est tout ce dont vous avez vraiment besoin pour faire savoir à l'API qu'elle devrait tout verrouiller dans ce contrôleur. Si vous ne le voulez pas sur l'ensemble du contrôleur, vous pouvez le placer sur les actions spécifiques. Donc, si l'obtention des types de feuilles ne nécessitait pas que quelqu'un se connecte, alors c'est bien. Cependant, si la création des types de feuilles nécessitait que quelqu'un se connecte et alors vous pourriez le mettre directement sur ce poste ou le PUT, etc. Non, nous avons presque fini de mettre en place nos services d'identité. Et à ce stade, nous avons juste besoin de laisser la base de données exister réellement et la mettre à jour avec les données pertinentes, n'est-ce pas ? Donc, je vais dans la console Package Manager et assurez-vous que votre projet de démarrage est l'API et que le projet par défaut référencé ici est le projet d'identité. Très bien, donc la première commande que vous devez exécuter est la migration d'annonces pour les nouveaux contextes BB d'identité. Donc, nous allons dire ajouter une migration de tiret. Qu' est-ce que nous avons le nom de la migration, mais alors je spécifie quels contextes cette spécification vous pourriez obtenir une erreur vu qu'il y a plusieurs contextes et il ne sait pas lequel utiliser. Donc, pour obtenir notre propre Que vous dites juste contexte néerlandais et le nom réel du contexte. Une fois que vous faites cela, vous obtiendrez ce fichier de migration généré. Et vous aurez les tables en cours de création, ainsi que les nouvelles données prédéfinies pour les rôles, les utilisateurs et les attributions de rôle utilisateur. D' accord ? Maintenant, après avoir fait cela, vous voulez faire une base de données de mise à jour. Donc, la base de données va sembler similaire dans le sens nous devons spécifier quels contextes nous mettons à jour. Donc, vous dites juste mettre à jour la base de données de tiret, contexte néerlandais et mettre dans les contextes DVI d'identité. Et avec tout cela, vous n'auriez pas créé la base de données. Je peux sauter par-dessus et vous montrer la base de données HR quitter Management Identity, avec toutes les tables qui auraient été créées. Une fois de plus, j'ai séparé la base de données de l'application du magasin de l'utilisateur. Très bien, alors testons cette autorisation et on pourra mettre fin à cette activité une fois pour toutes. Donc, nous allons dire autorisé sur la liste get ou obtenir la liste des types de feuilles et le point. Et puis nous sauterons à swagger et connectez-vous certains se connectant comme l'un de la mer que les utilisateurs ont le Tolkien. Et puis quand je fais défiler tout le chemin vers le bas quelqu'un pour tester un qui n'est pas autorisé juste obtient droit. Alors regardons les ID get by afin que je puisse le diviser en id1 et l'exécuter. Et vous voyez que je reçois ma réponse, aucune authentification requise. Maintenant, si je voulais tester les types de feuilles, peut cliquer sur ce cadenas. Laisse-moi recommencer. Quand ce cadenas, il me donnera les instructions que nous avons données. Donc, il est dit, assurez-vous que vous entrez porteur puis l'espace que votre Tolkien. Donc c'est à ça que ça ressemble en passant sur le fil, écrivez le mot miroir. Et que Tolkien que je viens de copier à partir de la réponse de la connexion. Et quand je clique sur Autoriser, je peux noter les vêtements. Donc, en ce qui concerne le football, toutes les demandes qu'il va envoyer, lorsque nous cliquons sur exécuter, il va inclure ce jeton porteur dans l'en-tête. Donc, quand je clique sur Exécuter à ce stade, alors nous voyons notre réponse. Laisse-moi essayer à nouveau avec le barista. Si je clique sur déconnexion, il efface l'en-tête du porteur et je clique sur Exécuter. Et je reçois ça pour une fois, je ne suis pas autorisé, je ne suis pas authentifié. Droit ? Alors laissez-moi essayer à nouveau. La valeur de potluck est le mot porteur. Les Tolkien autorisent, ferment , exécutent, et voilà. Donc, nous avons sécurisé l'ensemble de notre API, ou au moins nous mettons la capacité d'avoir l'EPI sécurisé et à l'avenir, bien sûr, nous pouvons maintenant répliquer ce genre de politique de sécurité à notre application client. 32. Ajouter l'authenticité au projet Web: D' accord, donc nous sommes en train de faire une API de magasin de modification lourde afin faciliter l'authentification et l'autorisation dans une certaine mesure. Maintenant, tout ce que nous avons besoin de répliquer ces efforts dans notre interface utilisateur où nous devons être en mesure de permettre à l'utilisateur de se connecter. Et en fonction de leur rôle, ils devraient être capables de voir certaines choses ne le sont pas. Donc ici, je me connecte en tant qu'utilisateur admin et vous pouvez voir que j'ai fait quelques modifications au menu où je peux voir certains éléments que je ne pouvais pas avant. Alors regardons ce qui a été fait. Encore une fois, je ne peux pas faire le travail déjà et je vais vous guider parce que je ne veux pas vous ennuyer en me regardant taper. Donc étape numéro un, mettons-nous à jour notre code généré swag de fin parce que nous le modifions ou API. En conséquence, notre documentation a été modifiée. Nous avons donc besoin d'un nouvel ensemble de code pour représenter l'état actuel de l'API. Donc, une fois de plus, nous allons entrer dans swag ou l'exécution est faite à cinq. Nous mettons en avant notre URL et créons une copie locale. Et à peu près nous répliquons tous les paramètres le même espace de noms. Nous nous assurons que toutes les options sont cochées, injecter, générer l'interface, et nous assurons que vous êtes sur les détails et générer les détails et les types de classe. Et lorsque tout cela est fait, assurez-vous que votre chemin de fichier est correct, puis régénère. Sachez, c'est quelque chose que nous pourrions faire plusieurs fois sur un probablement aurait dû vous le montrer plus tôt, mais vous pouvez en fait aller dans le fichier et juste enregistrer cet espace de travail afin que vous ne soyez pas difficile de commencer à partir de zéro à chaque fois. Bon, donc je vais juste sauver ça. Et quand nous reviendrons, nous pouvons toujours rouvrir et ensuite simplement le sauvegarder à l'intérieur du projet. Vous pouvez l'enregistrer n'importe où. C' est très bien. Cependant, continuons et continuons avec notre code nouvellement généré, qui devrait savoir avoir les tâches ou le et, ou les objets de requête et de réponse pour nos opérations de connexion et d'enregistrement. Bon, maintenant que nous avons tout ça, mettons en place nos services d'authentification locaux. Dans nos contrats, nous allons avoir une nouvelle interface, I service d'authentification. Et nous allons avoir trois méthodes. Un pour authentifier, un pour enregistrer 12 logos. Cela aurait pu facilement être appelé login, n'a pas vraiment d'importance, mais c'est pour la connexion, c'est pour la distribution, et cela serait forcé de se déconnecter. Et bien sûr, pour toujours les contrats, il y a une mise en œuvre. Donc, dans les services, j'ai cette implémentation sous la forme de service d'authentification, qui va hériter du service HTTP de base ainsi que du contrat. Maintenant, il se passe un peu dans cette méthode et je vais vous guider étape par étape comme d'habitude. Donc, d'abord, j'ai besoin d'injecter mon accesseur de contextes HTTP. Et je vais avoir un champ privé pour le gestionnaire de jetons de sécurité JWT connaître certaines de ces classes et vous téléchargez. J' ai en fait vu cette classe à partir de ni traiter avec l'API, vous aurez besoin de bibliothèques supplémentaires. Donc, comme vous êtes invité à installer les bibliothèques, allez-y et faites cela, ainsi que de mettre les instructions using. Donc, dans notre constructeur, comme nous l'avons vu précédemment, j'injecte les icônes, le stockage local, et je contextes HTTP accesseur, qui est initialisé ici. Nous transmettons également cela au BCE ou au client et le stockage au VCE. Nous initialisons les manuels, donc ce gestionnaire de jetons ne pas être injecté, mais nous l'initialisons pour être une nouvelle instance de gestionnaire de jetons de sécurité JWT. Sachez pour les implémentations car bien sûr après cet héritage, il aurait vraiment besoin de l'implémentation. Ainsi, vous pouvez aller de l'avant et générer ces talons de méthodes et nous faire savoir, examiner ensemble ce qui doit aller dans chacun. Donc, pour l'authentification, en prenant le mot de passe e-mail et j'ai tout enveloppé dans une capture d'essai. Ce que nous essayons de faire est de générer une demande d'authentification. Donc, nous allons obtenir l'e-mail et l'analyseur à partir des paramètres. Et je ne sais pas si je vous l'ai montré avant, mais dans cette carrière, dans cette dernière version de C sharp, vous pouvez réellement initialiser un nouvel objet en voyant simplement le nom de l'objet de type de données est égal à nouveau, et puis vous venez avez vos valeurs, n'est-ce pas ? C' est tout ce que je fais là. Ensuite, je vois la réponse d'authentification var est égale à attendre l'appel des clients pour se connecter asynchrone en passant cette demande d'authentification. Maintenant, si le point de requête Tolkien n'est pas égal à point de chaîne, le serveur vide sans l'objet de requête comprend quelques choses. Il a l'ID de l'utilisateur, le, je pense que l'adresse e-mail sur d'autres choses, quelques choses sont venues sur ce que la seule chose que nous sommes vraiment intéressés à garder est un jeton parce que c'est tout ce que l'application devra utiliser pour voir ceci est qui l'utilisateur est. Donc, si le jeton n'est pas vide, alors ce que nous voulons faire est d'obtenir le contenu de Tolkien. Je vois que le contenu var Tolkien est égal au gestionnaire de jeton qui a été initialisé ici. Lisez JWT, jeton. Et puis on passe la ficelle. Donc, c'est en fait un type fort appelé jeton de sécurité JWT. D' accord, alors nous voulons les réclamations des Tolkien. Rappelez-vous les informations, l'e-mail, l'ID, tout ce qui a été envoyé, Bucky, et le jeton qui nous dit qui est cet utilisateur, nous avons besoin de tout cela. Donc je vais juste analyser les réclamations du jeton. Maintenant, c'est une méthode que j'ai Poutine et c'est ici où il retourne juste la liste des revendications. Alors rappelez-vous quand nous mettons en place l'outil peut nous rappeler que nous compilons la liste des membres et le compost et le mettre, encodé et le mettre dans Tolkien nulle part décoder afin que nous connaissions la liste des revendications. Donc, dans cette méthode, nous disons fondamentalement que les revendications var sont égales aux revendications de point de contenu jeton dot deux listes. Donc, cet objet de contenu de jeton entier nous permet de simplement récupérer les revendications sous la forme d'une liste de chaînes ou de listes de revendications plutôt. Et puis nous allons ajouter explicite. Le nom des types de réclamation est Tolkien points sujets. Donc peut-être qu'il y en avait, peut-être qu'il n'y en avait pas. Je le fais explicitement. Je te montre juste parce que peut-être tu ne sais pas ce que tu remets à Tolkien parfois. Donc, vous, si vous voulez être explicite, vous pouvez toujours ajouter votre propre propre propre avec votre propre nom comme nous l'avons vu auparavant. Et vous mettez la valeur qu'il devrait avoir. Après avoir fait tout cela, nous renvoyons la liste des réclamations. Bon, maintenant on a les nettoyages. J' ai besoin de créer un utilisateur pour mon up actuel. Donc, je vois les utilisateurs var égaux au principe des revendications et les principes des rêves auront une nouvelle entité Ed revendications avec les revendications qui viennent d'être prises de la Tolkien. Et nous utilisons l'authentification par cookie. Donc, une fois que cette personne est créée, nous stockons cet enregistrement utilisateur ou la session de cet utilisateur, la police qu'il n'y a pas d'utilisateur actuellement dans le système en tant que cookie. Donc, nous verrons comment cela est configuré plus tard dans le démarrage. Mais c'est ce que nous faisons. Et puis nous allons faire une connexion en voyant les contextes HDTP accesseurs. Donc, c'est notre bibliothèque vraiment cool au cas où vous n'en êtes pas très familier, qui vous permet d'accéder réellement au contexte des requêtes HTTP. Donc, tout se passe quand un utilisateur demande des données ou envoie des données, quoi qu' il soit, tout se passe dans le contexte d'une requête HTTP. Donc, cette bibliothèque utilise réellement un accès direct à ce pipeline de requête actuel et nous permet de manipuler des contextes HTTP et c'est injectable donc nous n'avons pas à le faire à partir des contrôles, peut être de n'importe où ailleurs. Donc, je peux dire donnez-moi le contexte HTTP dans lequel nous sommes et allez-y et signez cet utilisateur en utilisant le schéma d'authentification des cookies. Et nous allons stocker ce Tolkien dans un entrepôt local pour être gardé en sécurité. Rappelez-vous donc que nous avons le stockage à faible coût appelé par notre méthode de jeton porteur chaque fois que nous allons faire un appel. C' est pourquoi nous devons le stocker une fois que vous l'aurez, et ensuite nous allons juste retourner vrai. Donc, si la personne est authentifiée, nous faisons tout ça. Je retourne vrai. Si nous retournons faux, alors nous pouvons faire autre chose. Et vous verrez ça dans quelques minutes. C' est donc à peu près ce que fait l'authentification. Et s'il y avait une erreur dans ce try-catch, alors il retourne juste faux. Il y a eu une erreur, non ? Donc c'est authentifier. Et regardons registre, ce qui est beaucoup plus simple vraiment. Nous allons simplement formuler ces demandes d'enregistrement fonction de tous les paramètres qui auraient été transmis. Et cela aurait pu être très facilement un objet, mais c'est très bien. Vous pouvez y revenir plus tard lorsque nous créons la demande d'enregistrement en conséquence. Et puis nous passons cet appel HTTP asynchrone avec cette requête. Et puis si nous obtenons l'ID d'utilisateur MCI ou un problème peu profond réussi, sinon, ce n'était pas le cas. Sachez dans notre logo, nous faisons deux choses vraiment étaient juste effacer le stockage de toutes les valeurs de Tolkien qui étaient là. Et nous sommes également en train de signer et de détruire implicitement n'importe quel utilisateur. B est les cookies qui ont été créés lors de la signature CE. C' est à peu près tout ce que fait la ceinture de bûches. Bon, donc c'est tout pour notre service d'authentification. Pas trop compliqué, non ? Ensuite, nous avons besoin de l'interface utilisateur ou des interfaces que nous appellerons cette âme. J' ai créé à un contrôleur appelé utilisateurs Controller. Et ici, nous injectons I service d'authentification et avons deux options, une pour la connexion et 14 connexion avec notre article post. Donc, connectez-vous, il va juste retourner une vue et nous pouvons générer une vue assez facilement avec cela. Laisse-moi revenir en arrière. J' utilise en fait le site de connexion VM, créé une VM de connexion. Là, nous allons, qui applique certaines validations sont plus, mais je dirai, vous savez, nous pouvons toujours appliquer la validation d'un client a dit que je ne dois pas nécessairement compter sur l'API. Donc quelque chose comme se connecter. Vous ne devriez pas être en mesure de tenter de vous connecter sans que l'e-mail que je suis l'analyseur soit rempli. J' ai également un champ appelé URL de retour. Bon, donc chaque fois que vous essayez de vous connecter, nous allons exiger que vous ayez passe e-mail et où valide-t-il également les types de données avec ceux-ci ? Et puis dans l'option, nous allons générer une vue. Et je viens de dire augmenter de vous connecter. J' utilise les modèles de création parce que nous allons être, nous avons besoin d'une ferme. Et puis nous utilisons la VM de connexion pour cette génération ou plus après avoir fait tout cela, nous cliquons sur les ajouter, nous obtenons notre vue tout simplement pas que nous sommes habitués à voir dans notre dossier utilisateurs. Et c'est vraiment juste le formulaire de connexion, non ? J' ai mis l'URL de retour comme une URL cachée. Et nous avons une zone de texte pour notre email 14 mot de passe, que j'ai spécifié le type est mot de passe, donc ce sont les liens de caractères, bien sûr. Et puis le bouton dit login, savoir quand ce formulaire est soumis, nous prenons la VM de connexion et l'URL de retour. Donc, l'URL de retour va à la racine du contenu de l'URL ou du contenu de l'URL par défaut. Et nous allons avoir un drapeau qui dit est connecté, qui va être défini après notre pondération d'un appel au point de service d' authentification authentification où la politique dans l'e-mail du point de connexion et le mot de passe de connexion. Et si nous obtenons un booléen, alors nous pouvons retourner une redirection vers l'URL de retour. D'accord ? Sinon, nous allons ajouter une erreur d'état de modèle pour dire que la tentative de connexion a échoué ces dragon et nous retournons juste la vue avec la connexion. Alors rappelez-vous qu'une fois qu'il a causé cela et cela peut bloquer cela revient comme vrai. Cela signifie que vous auriez déjà créé un cookie, déjà créé cet enregistrement utilisateur ou cette session utilisateur. Et puis au moment où nous redirigeons, l'utilisateur aurait été connecté. Passons maintenant à notre mise en page et voyons certains des changements que nous avons apportés. Donc, dans notre mise en page, nous avions nos types de feuilles, lien ou URL juste ici dans cette section de menu. Donc, j'ai supprimé cela et je l'ai remplacé par ce beau, c'est un bloc de code. Et j'ai également mis dans ce partiel appelé connexion partielle. Mais regardons un peu de code que j'ai mis dans. Donc, dans cette liste UL ou non ordonnée où nous avons tous nos éléments nav ont mis dans une instruction if qui dit si l'utilisateur, donc l'utilisateur avec un U majuscule par défaut de regarder les principes des revendications, rappelez-vous que c'est ce que nous venons de créer dans ce service d'authentification, n'est-ce pas ? Donc, si cette entité d'ajout de point utilisateur est authentifiée, alors nous voulons le faire. Certains user.name de poulet est inscrit. Souviens-toi qu'on a envoyé la règle propre, non ? Donc, nous pouvons voir user.email minéral, chercher l'administrateur de rôle. Et si l'utilisateur est dans cette règle, alors nous affichons ces nombreux éléments. Donc, j'ai juste un autre élément de navigation avec une classe appelée liste déroulante et une balise d'ancrage qui dit Gérer. Et je ne vais pas passer par tous les personnages. Je vais juste faire défiler assez lentement pour que vous puissiez voir tout ce qui va dans cette balise d'ancrage. D' accord. Et puis en dessous, nous avons un div qui a les éléments de menu déroulant. Ainsi, vous pouvez simplement appuyer sur Pause et répliquer cela si nécessaire. D' accord, donc c'est comme ça que nous avons eu cet élément de liste déroulante dans le menu. Au moins si vous utilisez Bootstrap 4, qui vient par défaut lorsque vous avez scuffled ou la prédiction de fichier .net sait dans la connexion partielle, tout ce qu'ils ont fait était de créer une nouvelle vue de rasoir, n'a pas utilisé de modulaire et les doigts et les vides de vous lui ont donné certains noms soulignent la faible partielle où indique généralement que c'est une partie de toute façon. Et puis nous avons ce morceau de code où j'ai une autre URL avec la barre de navigation de classe. Et puis à l'intérieur de cette instruction avenue, l'utilisateur est authentifié. Ensuite, nous voulons un élément de liste qui montre le nom du point d'identité de point utilisateur. Alors rappelez-vous cette prétention de nom que nous avons dit explicitement. C' est ce que c'était de l'art. Donc c'est un bon, j'utilise une vitesse intermédiaire dans la barre de navigation. Donc, à cet écran juste là, et puis nous avons un bouton logo. Donc, le bouton Charger est en fait un formulaire qui va appeler l'action Logos dans le contrôleur de l'utilisateur. Et je viens d'inclure cette URL de retour juste là. Et puis ce bouton qui dit logos. Donc, si l'utilisateur est authentifié, il montre que d'autre. Nous voulons montrer le lien pour une sœur et un lien pour une connexion. Blessé assez franchement. Donc, s'ils ne sont pas connectés, nous voulons qu'ils puissent se connecter ou s'inscrire, sinon, leur montrer leur nom. Donc, vous pouvez aller de l'avant et répliquer ces lignes. Bien que la grande modification qui devait être faite était à notre startup. Donc, vous pouvez voir ici que bon nombre de choses sont arrivées. La dernière fois qu'on était là. Je crois que nous l'aurions eu jusqu'ici. Maintenant, nous avons toute cette procédure. C' est juste. Donc, tout d'abord, nous devons lui faire savoir que nous voulons ajouter l'accesseur de contextes HTTP, ce qui signifie que nous voulons lui permettre d'être injectable dans n'importe quelle autre classe, donc nous l'utilisons dans le service d'authentification oculaire. Cela nous permet d'accéder à cette installation. D' accord, alors je veux configurer les options de la politique de cookies, n'est-ce pas ? Donc, les services sont configurés options de politique de cookies ne sont nulle part dans le côté minimum responsable. Désolé, la vue minimale semble définir la politique. Il semble que plus d'un. D' accord. Donc, une fois de plus, c'est une application assez simple. Je ne suis pas prêt tout avec la sécurité, vous pouvez avoir des besoins de sécurité différents, nos propres cookies et vos politiques. Mais au niveau de base, c'est ce sur quoi nous sommes assis. Et puis je vais dire que les services dot ajouter l'authentification. Et nous ajoutons le schéma d'authentification par défaut des cookies. Et nous ajoutons juste des cookies. Ensuite, j'ajoute transitoire ou ajoute une distribution transitoire ou transitoire pour notre service d'authentification avec son implémentation, tout est, reste à peu près la même en ce que les services configurent la méthode des services. Mais dans notre Configure, nous voulons également nous assurer que nous ajoutons l'authentification et que nous avons ADD ou utiliser l'autorisation là aussi. Vous voudrez vous assurer que ces deux lignes sont des prisons. Et avant d'aller de l'avant, nous voulons également nous assurer que les politiques de cookies là-bas. Donc, les trois choses en fait, la politique de cookies, utiliser l'authentification et l'autorisation d'utilisation. Maintenant, une autre chose que vous voulez faire est de modifier vos services. Donc, sachez que nous savons que nous devons avoir le jeton porteur attaché à certains appels de service. Nous pouvons maintenant aller à un service. Donc, vous avez déjà le service de type feuille en cours d'exécution. Et puis nous pouvons appeler la méthode de jeton add porteur à l'intérieur de chacune de ces méthodes. Donc, juste avant de rencontrer cet appel client, nous voulons ajouter un jeton porteur. Et tout comme le dit un rafraîchissement au jeton porteur, si le jeton existe, alors allez-y et ajoutez-le à l'autorisation. Ok, prenez-la comme une bière. Alors rappelez-vous quand on teste, ça se balancerait. Quand nous avons dû tester le point de terminaison sécurisé où aller et voir l'espace du porteur, le jeton C'est tout ce que cela fait est juste de voir les valeurs d'en-tête d'authentification bière. Et nous ajoutons ce jeton. Et l'autorisation est l'en-tête par défaut, n'est-ce pas ? Donc c'est l'en-tête et ça ajoute le porteur. C' est mal appelé. Mettre une barrière accélère Tolkien pour nous. Quand on fait ça, on l'ajoute à ce client. Donc, au moment où le client fait l'appel, le jeton porteur est présent, et alors tout le reste peut circuler. Donc, vous pouvez juste aller de l'avant et ajouter ce jeton porteur parce que nous ne savons pas quand quelque chose sera sécurisé ne sont pas elle. Nous ne savons pas quel point de terminaison sera sécurisé sur l'API. Eh bien, ça n'a pas vraiment d'importance. Le fait est que nous savons que nous avons besoin d'une sécurité miroir. Et plus que probable, vous posséderiez votre API ou une API serait les verrous ne sont pas complètement à quiconque ne se connecte pas essaye de s'inscrire. Une fois que vous êtes connecté, vous devez avoir votre Tolkien à dire, ici je suis ces pour l'information. Maintenant, en tant que test, ce que nous allons faire est de revenir à notre contrôleur de types de feuilles dans l'API et de mettre et d'autoriser sur l'ensemble du contrôleur, ce qui signifie que vous ne devriez pas être en mesure d'accéder à l' un de ces avec tout votre jeton porteur, vous devriez obtenir un 40 1, ce qui signifie sur autorisé ou non autorisé, sur authentifié. Au contraire, si vous tentez d'accéder à l'un de ces points de terminaison à partir de l'API. D' accord ? Alors n'oubliez pas de tester, vous voulez vous assurer que vous avez sur plusieurs projets, plusieurs projets de démarrage, accédez aux propriétés de la solution et laissez l'API démarrer. Je commence par o débogage, disons vient plus vite et MVC, vous pouvez également commencer sans débogage si vous n'avez pas besoin d'aller ligne par ligne. Alors allons de l'avant et testons ça. Donc, nous avons notre application MVC, nous allons essayer de nous connecter. Alors laissez-moi mettre, mais des tentatives. Je sais que l'utilisateur ne pense pas que cette connexion et vous en donne quelques-uns, et puis il rebondit au-dessus de voir la tentative de connexion a échoué. Veuillez réessayer. D' accord. Dentiellement pris note. Essayons un que nous connaissons, puis essayons-le à nouveau. Et puis cette fois, nous sommes maintenant connectés été donc nous redirigé vers notre page d'accueil et pas ISI qui Gérer l'élément de menu, ce qui nous donne ces options parce que nous sommes en tant qu'administrateur. Et si je vais laisser des types, tout se charge. Pourquoi ? Parce que mon jeton est présent. Il sait que j'ai accès à l'information demandée. Oh, si j'aime beaucoup. Et laissez-moi essayer de me connecter à nouveau en tant qu'utilisateur régulier, alors la connexion va aller bien, mais il n'y a pas de gestion en ce moment. Que faire si cet utilisateur était debout au-dessus de l'épaule de l'administrateur et a vu que pour accéder aux types de feuilles et créer mon propre type de feuille, je peux le faire. Je vais essayer d'y arriver. Il va y aller, non ? Alors modifiez rectifiez cela. Nous avons quelques points d'attaque et encore une fois, nous sommes des options. Mettez en œuvre celui qui convient le mieux à votre situation. Mais à partir de l'application côté client, nous devrions savoir que certaines choses sont réservées aux administrateurs, les choses incertaines sont réservées aux utilisateurs ou peut-être pas réservées aux livres. Les utilisateurs ne devraient pas être en mesure d'accéder à certaines choses que les administrateurs peuvent faire. Donc, dans notre contrôleur de types de feuilles, il ne suffit probablement pas de dire autoriser car cela signifie que vous devez être connecté. Je pouvais également voir autoriser avec l'administrateur des rôles. Cela signifie donc que seuls les administrateurs devraient être en mesure d' entrer dans cette partie réelle de l'application. D' accord, donc ça m'épargnerait beaucoup de temps du côté client à essayer de comprendre, ok, quel est l'appel ? Guerrez-les peu importe parce que cette Autorisation s'occupera de toute cette situation pour moi. D' accord. Donc maintenant que j'ai autorisé seulement les administrateurs à être en mesure d'accéder au contrôleur de types de feuilles. Si je suis connecté en tant qu'utilisateur et que j'essaie d'aller à laisser les types manuellement. Donc, une fois de plus, il ne suffit pas de cacher le lien parce que si je le mémorise, je peux trianguler. Eh bien, vous voyez que l'accès est refusé et qu'il pointe vers une adresse qui n'existe pas. Eh bien, c'est bon. Ce qu'il nous dit l'accès refusé, hum, ou, vous savez, c'est dire qu'on ne peut pas y arriver. Cependant, si j'étais connecté en tant qu'administrateur, je pourrais facilement y naviguer parce que je réponds aux exigences. C' est donc un bon moyen de sécuriser votre application du client. Dit maintenant que cela étant dit, vous pouvez également le sécuriser de l'API dit parce que de la même façon que vous pouvez définir cette autorisation inondation sur le contrôleur de types feuille dans le client vers le haut ou tout type d'application que vous utilisez, que ce soit un blazer MVC ou angulaire, où que vous soyez assis, l'authentification dans ceux que vous pourriez plutôt notre autorisation, vous pouvez également définir cette autorisation sur l'API. Donc, le développeur de l'API peut également avoir des stipulations strictes quant à qui devrait pouvoir accéder à mon contrôleur parce que si ce n'est pas appliqué à la hausse, et alors nous pourrions toujours passer à l'API. Donc, en tant que développeur d'API, vous pourriez également être très strict et voir que seuls les administrateurs sont autorisés à chauffer ce point de terminaison entier, tout ce comportement, non ? Ou une suite de comportements. Donc, comme je l'ai dit, il y a peu d'options et vous pouvez toujours l'attaquer sous différents angles. Très bien, alors fermons toute cette activité avec quelques modifications et puis nous sommes à la maison libres au moins pour l'instant. Très bien, donc dans notre contrôleur d'utilisateurs, dans notre application, je veux faire une modification ici où je vérifie si le modèle Steve est valide. Donc, si vous êtes utilisé MVC et tout cela, vous ne pouvez pas continuer tant qu'il s'agit d'erreurs de validation et pas dans Logan VM, nous avons quelques validations. Nous voulons nous assurer que ceux-ci sont en contrôle et n'ont pas plu, c'est tout ce que nous appliquons cette validation avant même d'essayer cet appel d'API. Très bien, sinon il va juste ajouter cette nouvelle, cette erreur statique et retourner la vue avec les données et les erreurs. Pas de problème, pas de registre. Allons de l'avant et éradiquons celui-ci. Donc on va juste à View, New View, vue rasoir. Nous voulons nous inscrire avec notre modèle de création et notre classe serait d'enregistrer v0 m. Très bien, donc je ne suis pas sûr si je vous ai montré le registre, enregistrez VM, mais il ressemble à peu près à la demande d'enregistrement. Inscription, demandes, prénom, nom, adresse e-mail, nom d'utilisateur et mot de passe. Très bien, et si vous vouliez mettre Poutine en place, confirmez le mot de passe, mais pour l'instant c'est tout ce que nous avons. Et nous avons également ces attributs pour nous assurer qu'ils sont nécessaires. Donc, vous allez l'utiliser pour générer la vue. Et puis dans le, dans le post, ce que nous allons avoir est d'accepter cet enregistrement ou y a-t-il VM ? Sachez, j'ai apporté une modification à la méthode de registre et cela a quelques étapes à travers elle. Un dans le profil de mappage du profil ajouté pour le rayon de la VM et les demandes d'enregistrement à mémoriser ou de distribution sur demande est l'un de ces modèles générés avec la permission de n swag, non ? Donc je suis en train de balayer ce point parce que je l'ai écrit mais je n'ai vraiment pas aimé ça. Puis encore une fois, quand vous vous développez, parfois vous faites quelque chose d'une façon et ensuite vous faites des soins infirmiers. J' aurais pu être le centre du bit mieux et ça va poser problème avec le refactoring, non ? Donc, dans la méthode de registre, je prends note de notre paramètre de VM de registre et j'ai également mis à jour ou I service d'authentification pour refléter cela. Très bien, donc nul, ça prend tout l'objet au lieu de six paramètres. Donc c'est une autre chose avec des principes solides. Vous ne voulez pas passer à de nombreux paramètres dans une méthode. Donc, lorsque vous réalisez que vous dépassez probablement trois ou quatre, créez un objet. Donc, dans ce cas, nous n'en avions que deux. Je ne voulais pas qu'il le refactorise, mais celui-ci en avait environ cinq ou six. Donc, je l'ai refactoré pour simplement passer dans l'objet d'enregistrement. Et puis notre demande d'inscription est non, juste un mappage entre la demande d'inscription et notre VM d'enregistrement ou d'enregistrement. droite. Donc, bien sûr, j'ai dû injecter la partie supérieure de l'automne dans ce pour le mettre en place et en cours d'exécution. Et puis tout le reste reste à peu près le même. Revenons au contrôleur. Je connais POS dans cet appel de registre, je vérifie qu'il est créé ? Et puis si elle est créée, alors nous redirigeons. Donc ici, je suis juste assis l'URL pour être votre contenu. Je ne suis pas assis, c'est spécifiquement et on redirige. Sinon, nous avons un message et retournons la vue avec les données. Et il montrerait toutes les erreurs de validation en conséquence. Donc, laissez-nous également modifier notre service Auth au niveau de l'API parce que nous voulons employés s'inscrivent donc nous devons savoir que leurs employés, donc à ce moment ils s'inscrivent sur la base de notre devis est configuré non, que serait juste des utilisateurs. Il n'y aura aucune assignation de rôle. Nous devons donc veiller à ce que, lorsqu'ils s'inscrivent, nous connaissions leurs employés. Donc, dans notre service Auth, une fois de plus, dans notre projet d'identité sur l'infrastructure, droit, service OT, nous devons voir si le résultat a été réussi pour l'utilisateur de création. Ensuite, nous devons les affecter à la règle. Donc, nous allons juste ajouter cette ligne après qu'un point de résultat a réussi. Nous disons juste, Je vais attendre d'utiliser un gestionnaire ajouter à la règle utilisateur asynchrone, employé. Alors restons cette inscription pour un tour. Donc, je vais cliquer sur registre et remplir ça. Maintenant, une chose que je voulais pointer O, nous faisons nous pour l'e-mail et le nom d'utilisateur. Encore une fois, les contextes sont différents dans notre contexte, j'utilise la même valeur pour l'email et le nom d'utilisateur. Et puis on pourrait dire qu'on pourrait dire qu'il est viable. On leur demande les deux. Pourquoi ne pas simplement demander un et l'assigner dans le compartiment, ce qui est des arguments vérifiables, non ? Donc, dans votre situation, vous pouvez avoir besoin d'eux séparés, et ils peuvent avoir besoin d'être deux choses différentes. Ainsi, pas de problème juste vous donner le cadre. Donc, avant même de faire une distribution correcte et vous pouvez voir que la validation fonctionne réellement activement. Je ne peux pas procéder à tout ce qui est en place, n'est-ce pas ? Alors laissez-moi mettre les valeurs et ensuite aller de l'avant et appuyez sur registre. Et j'ai été redirigé ici. Donc vous en avez un autre, vous savez, je parle toujours des options parce qu'à ce stade je suis inscrit, mais je ne sais pas. n'y a aucune indication de voir que ça a réussi. Je suis retourné à la page d'accueil. Bien sûr, si j'essaie de me connecter, je peux me connecter mais l'utilisateur ne le sait pas. Donc en général, ou parfois ce que vous voyez, c'est qu' ils vous connecteraient réellement après un succès ou une distribution. Nous pouvons donc faire une simple modification pour que cela se produise. C' est simple modification consiste à appeler ou authentifier l'art. Nous sommes donc passés par leur distribution, nous avons obtenu une réponse si elle n'est pas vide et nous reviendrions vrai. Avant de retourner true, nous voulons juste appeler authenticate, que nous savons ce qu'il fait. Il déclenche en fait toute cette procédure de connexion, puis nous retournons true. Donc, dans notre contrôleur, nous pourrions facilement avoir une redirection à voir, au lieu de revenir à la page d'accueil, nous pourrions en fait lire nos deux adresses IP. Vous aurez avec succès la bannière d'amour, un message convivial à l'utilisateur afin qu'ils sachent exactement ce qui s'est passé. Très bien, donc c'est vraiment tout pour null, au moins plus tard, nous avons l'embellissement aura quelques modifications parce que même sur le null, nous ne nous concentrons pas ou compensons pour certaines flèches qui revenir de l'API. Alors. Nous avons dit que la gestion globale des erreurs à prendre en charge, mais plus tard, nous nous occuperons de cela, n'est-ce pas ? Non, nous nous concentrons uniquement sur la mise en œuvre ces fonctionnalités et sur le bon fonctionnement de tout ensemble. 33. Gestion de la décharge: Tous les bons gars, alors maintenant que nous avons ou configuration d'authentification, nous avons nos utilisateurs, ou au moins nos utilisateurs ont la capacité de s'inscrire et d'être configurés en tant qu'employés. Et tout ce que nous avons besoin de mettre dans la fonctionnalité qui permet aux administrateurs d'allouer les DS pour siéger les employés. Donc, cela commence par ceux qui modifient nos objets de domaine pour l'allocation des congés où nous allons ajouter l'ID d'employé parce que nous avons besoin de savoir à qui le nombre de jours pour ce type de feuille sur pour cette période a été affecté. Nous devons donc ajouter cela. Et ensuite, nous faisons une migration. Se souvenir que nous devons définir notre projet de démarrage sur l' API et le projet par défaut sur le projet de persistance. Et ou ajouter l'instruction de migration de tiret ressemblera à ceci. J' ai nommé mon ID employé ajouté pour l' allocation des congés et les contextes seraient le contexte DB de gestion des congés. Et puis après cela, nous exécutons cette mise à jour dans le même contexte. Donc, c'est notre fichier de migration. Vous faites juste la base de données de mise à jour et un sol qu'il est terminé et nous pouvons aller de l'avant. La prochaine chose que nous voulons faire est de créer un fichier de contrat ou une interface dans notre couche d'application sous le dossier d'identité, je l'appelle, j'utilise un service. Donc, nous allons avoir des opérations utilisateur spécialisées dans ce domaine, j'utilise un service qui peut être utilisé par nos gestionnaires. Donc je vais avoir celui-ci retourner une liste de type employé et ça s'appelle les employés get parce que nous voulons seulement allouer. Ce sont les employés savent que le département RH a dit que tout ce qu'ils ont vraiment besoin pour cette fonctionnalité est la possibilité d'aller à la page et de cliquer sur allouer, puis nous obtenons tous les employés et allouer. La valeur par défaut est pour la période, la période étant cette année. Bien sûr, nous ne voulons pas attribuer quoi que ce soit à un organisme qui n'est pas dans le rôle d'employé. Nous devons donc nous assurer d'avoir des employés. Employé est un modèle créé à l'intérieur du dossier d'identité. Et tout ce qu'il a vraiment, c'est l'ID, l'e-mail , le prénom, et rien de trop, pas trop provenant de la base de données juste dans une forêt et tout ce que cet employé pourrait être. Merci, nous avons notre implémentation qui vit dans le projet d'identité, et il utilise juste le service sous le dossier des services. Et il hérite du contrat. Et il injecte le gestionnaire d'utilisateurs par rapport à l'utilisateur d'application. Et puis notre méthode pour obtenir la liste des employés était juste à la recherche dans le gestionnaire d'utilisateurs, obtenir les utilisateurs inscrits asynchrone et nous passons dans ce rôle. Donc, cela nous garantit que nous recevons n'importe qui dans la base de données était un utilisateur qui a le rôle d'employé. Et puis nous retournons la liste des employés de type. Alors, où est-ce qu'il s'agit d'une liste d'utilisateurs d'application ? Donc, nous disons sélectionner à partir de cette liste dans de nouveaux objets de type employé. Et ils ne faisaient que réaffecter les valeurs en conséquence. Et puis nous terminons avec une liste de choses à faire dans ce retour. Donc, une fois que ce service sera appelé, nous allons utiliser cette méthode pour obtenir tous les employés. Ensuite, dans notre méthode d'enregistrement des services d'identité, bien sûr, nous devons l'ajouter I User Service. Donc, nous allons juste de l'avant et l'enregistrer en conséquence. Maintenant, cela va être suivi de quelques modifications à notre référentiel d'allocation Je quitte. Alors remontez aux contrats et trouvez notre original. Je vais quitter le dépôt d'allocation. A l'origine, nous aurions écrit l'implémentation pour toutes les capacités actuelles d'allocation de congés avec ces deux méthodes personnalisées. Mais alors, une fois de plus, règles de changement ont rendu les choses plus simples pour nous, problème sono, mais nous avons besoin de méthodes plus personnalisées pour accomplir ce que les RH avaient en tête. Donc, non, j'ai une tâche, nous retournons un booléen qui vérifie si l'allocation existe. Donc, nous obtenons l'ID utilisateur, ID de type feuille et la période. Et puis nous avons une autre tâche où je vois à des allocations. Donc, vous allez voir pourquoi j'ai aux allocations, même si nous avons déjà la méthode add générique, l'état sait que celui-ci prend une liste d' allocation de congé comme paramètre, connaissant l'implémentation. Que tu verras ce qui se passe ici. Donc, commençons par l'application existe. Une fois de plus la tâche renvoyant un booléen, en vérifiant s'il existe, nous obtenons ces trois paramètres, donc nous retournons juste les allocations de points de contexte DB que n'importe quel async où nous vérifions si l'ID de l'employé correspond à l'ID utilisateur être mince. Si l'ID de type feuille est beaucoup un en cours de transmission et la période autant que la période. Donc, nous revenons juste, oui, que l'allocation existe, sont connus pour nos allocations ont fait quelque chose un peu différemment ici puis avec l'annonce régulière. Parce que ce qui se passe, c'est que si nous l'autorisons à aller et cliquer sur Ajouter des allocations et qu'il y a 100 personnes là-bas. Ce que nous ne voulons pas faire est d'appeler la fonction add 100 fois. Donc EF Core nous a donné une méthode de plage d'annonces qui nous permet de simplement mettre dans toute une liste d'enregistrements à ajouter. Et il va l'empaqueter dans l'instruction SQL la plus efficace possible pour enregistrer les modifications. D' accord, c'est pourquoi j'ai écrit cette méthode personnalisée ici. Nous ajoutons donc une plage au lieu d'ajouter. Bon, maintenant que nous avons notre dépôt est à zéro, passons à notre gestionnaire et voyons quels changements sont nécessaires là-bas. Très bien, donc dans notre gestionnaire avait commenté ces lignes sont juste de les décommenter savent que nous sommes ici. Nous injectons donc notre service utilisateur dans notre commande ou créons l'allocation. Sachez que quelques autres changements seront nécessaires parce que notre création de détails demande trop d'informations basées sur ce que nous avons dit. La nouvelle opération ou le nouvel objectif est. On y arrivera dans quelques uns. Mais la rétine veut se concentrer sur ce que le gestionnaire fait après qu'il est, il a validé les données qui sont venues, à droite. Donc, après avoir validé ce qui est dans le DTO, nous procédons ensuite à essayer de compiler la liste des allocations à envoyer à la base de données. Voyons ce qui se passe ici. Tout d'abord, nous obtenons le type de feuille qui est alloué, non ? Donc, nous ferions des requêtes Je GET sous ce dépôt qui a déjà été injecté par la courtoisie du Fatah. On en avait besoin pour le validateur. Très bien, donc laissez ce point de dépôt GET requête point naïve allocation détail l'ID de type elif. Nous recevons tous les employés grâce à notre service à l'utilisateur. Nous avons fixé cette période aussi cette année. Ensuite, nous initialisons une liste d'allocations de congés. Ensuite, pour chaque employé qui est dans le système, nous vérifions si l'allocation existe. On continue. Sinon, nous voulons ajouter un nouvel enregistrement d'allocation où l'ID employé est égal à ID de point EMP et laisser dy par dt est égal au type feuille mais ID et le nombre de jours. Et la période est la bonne ? Maintenant, je ne suis pas stricte sur les règles d'affaires. Selon certaines règles commerciales, en fonction du point de l'année, cet emplacement devrait être différent, ce qui est parfaitement plausible. Quel que soit le masi à faire, vous appliquez ce calcul aux jours par défaut et vous l'avez appliqué. Mais le fait est que vous allouez les jours à l'employé à ce stade. Bien sûr, si vous vouliez obtenir ce Grendel, alors vous voudriez le faire sur une base individuelle plutôt qu' une opération en vrac pour tout le monde pendant une période entière d'un an, non ? Donc, vous pouvez jouer un peu avec elle. Mais en ce moment, nous avons juste affaire à une opération en vrac. Donc, après avoir ajouté tous ces enregistrements d'allocation à cette liste, alors nous attendons juste notre appel aux allocations dans notre référentiel, qui envoie sur la liste et EF Core, nous ferons le reste. Et puis nous pouvons voir que la réponse est vraie, succès est vrai plutôt, et le message est la création ou les allocations réussies, selon celui que vous préférez. Sachez pour nos crée allocation DTO, nous demandons le nombre de ceux-ci. Et nous avons demandé pour la période parce qu'au moins dans l'ancien système, qui sont capables de cliquer directement sur un employé et mettre dans le nombre de congés que nous allouons de l'argent sauvagement. Et la période pour laquelle nous l'allouons, comme l'a dit les RH, ils n'en ont pas besoin ou ne veulent pas, non ? Non, donc c'est bon. Nous pouvons toujours modifier notre DTL, le redimensionner un peu. Et bien sûr, cela aurait des effets d'ondulation avec l'ensemble de l'héritage des détails d'allocation. Donc ça veut dire que nous devons modifier plus que les champs, n'est-ce pas ? Donc, je devrais supprimer cet héritage et la note off pour modifier aussi le validateur pour ne pas inclure toutes les règles relatives à l'interface sont il est OF de supprimer cette inclusion Andon entière après avoir réécrit la règle juste pour le Crée. Donc, je viens de réécrire cette règle où nous validons l'ID de type feuille qui est demandé sont alloués pour, nous nous assurons qu'il est supérieur à 0 et nous vérifions s'il existe aussi. Maintenant, passons à notre API et laissez-le savoir qu' il devrait également renvoyer la réponse de la commande de base. Si tu ne l'as pas déjà fait. Assurez-vous de le faire de sorte que le document Swagger avec la mise à jour et deux modifications ultérieures doivent être pris en compte par notre nouveau client de service dans l'application. Parce que l'un, nous modifions les paramètres pour le DTO. Non, vous n'avez besoin que d'un seul paramètre. Et nous devons également faire savoir au serveur qu'il devrait s'attendre à la réponse de la commande de base. Donc maintenant que nous avons fait ces changements, Utilisons dans swag pour régénérer ce code client de service. Rappelez-vous toujours qu'il est préférable d'exécuter le projet. Et puis même si vous l'avez déjà enregistré, parce que je viens d'ouvrir ma version enregistrée de ce modèle. Même si vous l'avez enregistré, il est préférable de rouvrir le projet, recréer la copie locale, puis vous pouvez régénérer votre code C-Sharp. Donc maintenant, nous passons à notre application client où nous allons mettre en place notre contrat, C'est les implémentations et bien sûr, l'interface utilisateur. Donc maintenant tout ce que nous avons notre contrat. Je vais quitter le service d'allocation et il nous dit qu'il y a une réponse de retour avec le type int. Et ça va être appelé vocations créatives, et ça ne prend qu'un ID de type feuille. Une fois de plus, HR l'a simplifié pour nous. Donc, si vous aviez créé toutes les machines virtuelles et ainsi de suite, c'est moi qui aurait été exagéré en fonction des nouvelles exigences, mais c'est bon. Donc tout ce dont nous avons vraiment besoin, c'est de créer une allocation IV. Et puis dans l'implémentation que nous mettons dans le dossier des services, bien sûr, nous savons que nous héritons du service HTTP de base et de l'ID du service d'allocation, peu comme ce que nous avons fait, les types de feuilles, nous injectons également ou à faible coût et le client AAE dans ce service. Et puis dans notre méthode, c'est ses allocations de congé de créatinine, tout ce que nous avons notre type de réponse, qui est la réponse par rapport au type int. Nous créons notre détail, qui dans cette situation est vraiment juste le détail à voir. Le type de feuille a cette valeur. Très bien, donc nous savons que le détail de l'allocation de congé Créer, laisser, créer est maintenant mis à jour pour ne vouloir que cette valeur puisque nous avons mis à jour notre documentation et le code résultant à travers et slug, nous ajoutons à notre jeton porteur et nous sommes du blé Appelez. Très bien, donc je ne suis même pas le vrai peut, nous pouvons toujours doubler et nous assurer que le point de terminaison de l'API est protégé uniquement pour les administrateurs. Et nous pouvons aussi faire cette prédiction du côté de l'application, n'est-ce pas ? Donc, le jeton porteur est certainement important de se souvenir. Ça va toujours être important pour les communications de l'APEC. Donc, après que nous avons fait cela, nous vérifions si votre succès, puis nous le définissons sur true car il n'y a pas de données réelles revenir, parce qu'il n'y avait que retourner la réponse du B. Nous ne rendons pas une pièce d'identité ou quelque chose comme ça. Donc, je n'ai pas besoin de définir les données de réponse pour avoir vraiment une valeur. Et puis nous avons retourné des erreurs de compilateur réponse. Toucher des erreurs. Comme je l'ai déjà dit, assurez-vous que vous l'avez enregistré dans le point de démarrage CSS. Donc, vous ne faites tout simplement pas les balles ou le startup.js. Et s'il avait écrit les lignes, sans les commenter, alors décommenter, sinon, alors n' hésitez pas à savoir, mettez cette ligne. Maintenant, nous allons faire des modifications ou de l'interface utilisateur. Donc, le meilleur endroit que j'ai supposé pour mettre cette fonctionnalité pour une allocation en vrac de types de feuilles est sur le type de feuille LR. Donc, sur cette page, je viens d'ajouter un nouveau formulaire où nous aurons avocat avec le même type de visa d'identification de route gars pour le voir chercher formule à supprimer. Donc, ici, nous répétons le formulaire. Donc, comme je l'ai mentionné, parfois bip, au lieu d'avoir plusieurs formes, aurait un et ensuite utiliser JavaScript pour déclencher le formulaire unique. Mais c'est bon dans cette situation, tout ce que je veux savoir, c'est que ça marche bien ? Donc, nous avons l'ASB réel et allouer. Il prend le même ID d'itinéraire et nous avons un bouton qui dit allouer. Et celui-ci dit juste, Êtes-vous sûr de vouloir allouer à tous les employés ? C' est l'invite que vous auriez. Maintenant, nous avons une méthode de post dans notre contrôleur de types de feuilles appelé Hello Kate. Donc j'ai juste mis celui-là juste en dessous de la suppression, n'est-ce pas ? Donc, dans notre cas, nous essayons d'obtenir la réponse du service d'allocation des congés. Donc, sous-point a dit que nous devons injecter ça dans notre contrôleur. Bon, donc on a essayé d'obtenir la réponse. J' utilise juste le contrôle M et O, il suffit de noter pour réduire tout le code afin que vous puissiez l'utiliser pour les fichiers de code B. Donc, notre méthode d'allocation va appeler le service d'allocation créer des altercations, en passant cet ID. Et puis s'il réussit à rediriger vers l'action vers l'index. Et bien, je vais juste retourner une mauvaise demande ici juste au cas où elle n'aurait pas réussi. Donc on sait que ce n'était pas elle. Plus tard, vous pouvez ajouter un peu de jQuery ou quelque chose pour gérer le type de retour d'une meilleure manière, mais bon, non, nous ne priorisons pas cela. Nous voulons juste nous assurer de mettre en place toutes les choses et les fondations, n'est-ce pas ? Alors, prenons celui-là pour un tour. Essayons d'allouer. N' oubliez pas de mettre sur plusieurs projets de démarrage. Et après avoir connecté en tant qu'utilisateur admin, nous naviguons vers nos types de feuilles, puis nous essayons d'allouer. Donc encore notre invite Etes-vous sûr que nous cliquons sur OK, et nous recevons une erreur. Nous obtenons une erreur, HTTP Error 400. Donc, cela indique cette mauvaise demande. Bon, donc quelque chose s'est mal passé. Donc, après avoir traqué et suivi cette erreur, il a atterri ici dans le validateur. Donc, ce qui se passe, c'est que lorsque nous créons, il n'est pas considéré comme valide que créer une allocation de congé V2 n'est pas valide. C' est parce qu'il voit qu'un type de feuille n'existe pas. Maintenant, nous savons que c'est impossible parce que nous avons juste cliqué sur le type de feuille. C' est dans la même ligne. Nous savons qu'il existe et que la flèche est juste ici. Donc c'est mon, euh, mais donc je les tests unitaires auraient probablement attrapé que nous avons déjà écrit dans Unittest. Donc, nous devons passer du temps à suivre ces choses ne le font pas. Mais le fait est que Nous devrions revenir si elle existe, parce que nous voyons si elle existe ou est vraie. Il doit donc exister. Donc, cela doit être vrai. Donc je ne devrais pas revenir, ne revenant pas vrai ou pas aérer. Donc c'est une erreur de ma part. Donc, à cause de cette erreur, devra en fait aller à chaque validateur juste pour être sain. Assurez-vous donc qu'aucun de ces validateurs ne fait la même erreur. Maintenant, la bonne chose est que nous en avons créé des centraux. Donc, nous n'avons pas beaucoup, beaucoup de changements pour moi. Donc, ceux décollent qui ne signent pas le type de feuille existe, vérifier et nous devrions être bons pour aller. Bon, alors essayons encore celle-là. Essayons de faire les allocations. Bon, donc nous sommes de retour et essayons d'allouer à nouveau. Nous arrivons à notre invite, il fait son truc, et la page se rafraîchit donc il n'y a pas d'indicateurs, non ? Nous pourrions bien sûr, en citant quelques messages pour dire, vous savez, cette action appellera ceux qui ont été achevés avec succès. Mais le fait qu'il a vraiment rafraîchi la page selon notre code. Si elle réussit, redirigez vers l'index de la plage actuelle, ce qui est bon. Il a été infructueux donc dans la demande de beurre. Donc, au moins, nous savons que notre allocation fonctionne. Laissez-nous vérifier dans la base de données pour voir ce que nos emplacements ont été créés. Et nous voyons ici que nous avons des allocations pour feuille de type 1 pour la période de 2021 et pour l'employé auquel il est affecté. Donc, nous avons trois employés dans le système ou IL-3 employés dans mon système, nous sommes probablement juste en voir un ou deux si vous avez l'utilisateur prédéfini et il a créé un utilisateur depuis. Mais le fait est que nous avons autant d'employés dans le système, vous auriez ces allocations. Donc, si je le fais à nouveau avec la sécurité, qui est id2, cliquez, je localise, cliquez sur OK, et fait son truc. Si je rafraîchis ces données, nous allons voir des allocations pour les congés de maladie pour tous les employés. Donc l'allocation div ne fonctionne pas. C' est ce que les illustrations RH, c'est ce qu'ils obtiennent. Donc, plus tard, vous voyez le de la base pour étendre cela, si vous vouliez donner un écran dédié, vous devriez aller pêcher l'employé, leur permettre d'éditer l'allocation de la vallée de l'argent. Et puis, vous savez, pour configurer votre gestionnaire et votre point de terminaison API pour qu'ils soient spécifiques à cela. On ne va pas obtenir ça détaillé maintenant. Nous voulons juste faire les fonctions de base. Et jusqu'à présent, nous avons fini avec l'allocation des congés. 34. Gestion des demandes de congé - Partie 1 - Employé: D' accord les gars, donc nous sommes en train de tourner à Nestlé et nous passons au module suivant, qui sera notre module de demande de congé. Donc, notre voyage ici commence par une modification à un objet de domaine de demande de congé où nous ajoutons l'ID d'employé , d' accord, parce que celui qui est connecté est celui qui va faire la demande. Nous devons donc être en mesure de dire que cette demande vient de cet utilisateur. Comme d'habitude, après une modification de nos objets de domaine, nous avons notre commande de migration et ensuite nous avons notre commande update database. Donc tu peux aller de l'avant et faire ces deux-là. Et une fois que vous avez terminé avec succès, nous pouvons passer à notre prochaine activité. Laissez-nous passer en revue les détails de nos demandes de congé. Nous avons donc dit que la Quest D2 doit avoir la date de début et de fin, le type de feuille étant appliqué, ainsi que les demandes de commentaires. Notez qu'il n'y a rien de terrible l'identifiant de l'utilisateur, non ? Donc, vous vous demandez probablement, ok, alors comment pouvons-nous savoir quel utilisateur est connecté à la fois ? Rappelez-vous donc que nous utilisons l'authentification Tolkien, ce qui signifie qu'entre le MVC sur l'API, nous pouvons accéder à différents bits d'informations à partir du Tolkien. Un bit d'informations dans le jeton serait l'ID de cet utilisateur. Cependant, je ne veux pas y accéder depuis l'un de ces endroits car je n'ai pas besoin d'y accéder jusqu'à ce que je crée vraiment une demande de congé. Et nous avons le gestionnaire ici qui est pris, que les requêtes de commande ou les commandes objet. Et puis il va de l'avant et de le valider , puis de créer la requête si elle est valide, puis de la passer la base de données. Cela signifie donc qu'entre ces deux étapes, nous devons nous assurer de mettre ces nouvelles données d'identification d'employé. Rappelez-vous donc que nous avions utilisé le buck de l'accesseur de contexte lorsque nous faisions l'authentification dans l'application MVC. La chose cool à ce sujet est que nous sommes capables d'utiliser cet accesseur de contexte tout le chemin ici dans notre couche d'application, dans nos commandes. Nous allons donc accéder au contexte HTTP de l'API à partir de l'intérieur du gestionnaire. De cette façon, nous n'avons pas à y accéder jusqu'à ce que ce soit absolument nécessaire. Donc, dans le fichier de démarrage de l'API, je vais ajouter le services.js contextes HTTP accessor inscriptible, l'appel de méthode swat Swagger doc. Ceci, me permet alors d'injecter dans la commande mon accesseur de contextes HTTP. Et je peux aller de l'avant et initialiser le champ, mais j'ai besoin d'une bibliothèque pour cela, et c'est l'abstraction de noyau ASP NET Microsoft dot. Alors allez-y et installez la dernière version. J' utilise NuGet, renommez notre champ selon notre convention de nommage. Et puis à l'intérieur du gestionnaire, je peux facilement enregistrer var ID utilisateur est égal à mon contexte HTTP accessor dot contextes HTTP, point utilisateur revendication point premier ordre par défaut. C' est une bouchée, mais évaluons ce qui se passe ici. Jusqu' à présent, nous avons obtenu le principe des réclamations. Ce principe de revendication est le même principe que nous sommes capables de construire dans l'application locataire en vertu du Tolkien, d'accord, donc parce que le jeton vient de notre client à l'API, nous sommes en mesure d'accéder aux informations de jeton à partir du gestionnaire avec l'autorisation de l'API. Et puis nous pouvons accéder à cet utilisateur, regarder à l'intérieur de la liste des revendications et trouver le premier étage par défaut qui a la même clé de type de nom. Cependant, vous voulez évaluer que ce qu'un type ici correspond au nom revendiqué que nous lui aurions donné pour l'ID d'utilisateur. Donc c'est une autre raison que je suggère de ne pas utiliser les chaînes magiques parce qu'une erreur d'orthographe ici pourrait jeter tout le truc. Ce que nous pouvons faire dans l'activité de nettoyage plus tard. Mais en ce moment, nous recevons cette réclamation UID, que nous sommes assis manuellement. Et puis j'utilise juste la valeur par défaut ou quatre, si elle est petite, nous n'obtenons pas une autre exception, mais je reçois vraiment la valeur. Très bien, donc c'est comme ça que j'obtiens le nom d'utilisateur. Maintenant que j'ai cet ID utilisateur, plus tard, je peux voir le point de demande de congé demandant l'ID d'employé est l'ID d'utilisateur. Maintenant, je l'ai fait tout le chemin ici parce que je peux vouloir utiliser cet ID utilisateur et une autre opération plus tard. Donc je le garde ici. Et une autre chose qui pourrait nous intéresser est l'adresse e-mail. Donc ne pas ici, nous recevons l'e-mail d'une manière légèrement différente. Nous voyons l'adresse e-mail est égale à ses contextes GTP accessor, tous cet user.name trouver en premier. Et puis nous cherchons la revendication exacte par e-mail par son type. Puisqu' il fait une technique différente de ce que nous avons fait ici. Et nous obtenons cette valeur. Donc, vous pouvez prendre plusieurs approches pour obtenir cela. Ces bits d'information parce qu'il aurait pu juste obtenir le principe des réclamations en un seul coup et ensuite utiliser la première loi de recherche, la première loi par défaut par la suite pour obtenir n'importe quel morceau d'information que vous voulez. Pas de problème, mais au moins vous savez ou savez comment obtenir l'adresse e-mail afin que nous puissions savoir dire à cette adresse e-mail et envoyer notre e-mail au moment approprié. Maintenant, avant de passer de ce gestionnaire particulier, il y a d'autres opérations d'entretien interne que je voudrais effectuer avant permettre à un utilisateur de procéder à une demande de congé. Et alors pensons à ce qui doit se passer exactement au cours de ce processus. Sur un utilisateur doit indiquer qu'il veut avoir un certain type de feuille pendant une certaine période. Ils peuvent ajouter des commentaires supplémentaires s'ils le souhaitent. Et puis ils soumettent ça. Ils ne peuvent obtenir cette demande que s'ils ont l'allocation. Donc, ça veut dire qu'on ne va même pas le mettre dans le système. Si ce qu'ils ont demandé dépasse leur allocation actuelle. S' ils le demandent et que leur allocation est présente, alors c'est bon. Plus tard, quand un administrateur approuve cela, alors nous allons de l'avant et faisons quelques déductions pour assurer que quand ils ont demandé cinq jours, alors le 5D est moins dans leur allocation. Ce sont donc les choses sur lesquelles nous voulons nous intéresser. Maintenant, c'est un, c'est le plus compliqué des modules. Il y a donc beaucoup de travail à faire ici. Commençons donc par la vérification de l'allocation, parce que s'ils n'ont pas l'allocation, alors ils ne peuvent pas avoir une opération valide à l'avenir, n'est-ce pas ? Alors allons de l'avant et injectons ou je laisse le référentiel d'allocation dans le système. Et alors ce que nous voulons faire, c'est être en mesure de rechercher l'allocation pour cet employé en particulier, qui est une méthode que nous n'avons pas R. Alors passons à cette histoire et mettons-en œuvre cela. Donc, nous créons une tâche qui renvoie l'allocation de congé, j'appelle les allocations GetUser et prend cet ID utilisateur de chaîne ainsi que l'ID de congé, à droite, donc nous allons sauter ici et aller de l'avant et implémenter le dans la classe de référentiel d'implémentation. Et puis ce que nous allons faire ici est de faire une recherche et retourner notre contexte DB en regardant les allocations de congé, trouver le premier ordre par défaut où l'ID employé correspond l'ID utilisateur et l'ID de type feuille correspond à la feuille. Pas de déjouer le gestionnaire. Je peux aller de l'avant et obtenir cette allocation en appelant référentiel d'allocation de congé allocations d'utilisateurs Git, en passant l'ID d'utilisateur et ce congé de point de demande, l'ID de type feuille de point de détail. Je vais maintenant calculer le nombre de jours demandé. Donc je fais juste un rapide Caucasien entre la date de fin et la date de début pour obtenir le nombre total de jours. Et je m'assure que je l'obtiens mais comme un entier. Et puis je vais dire si le nombre de jours demandé est supérieur au nombre de jours dans votre dossier d'allocation. Je vais ajouter cette erreur de validation. Donc, cette société aurait pu arriver ici, comme nous le voyons, je le fais gestionnaire et j'utilise le résultat de validation fluide pour simplement ajouter cela parce que dans le cas où ce n'est pas valide, je veux m'assurer que cette validation est aussi présent. Et donc quand il est retourné avec les erreurs qui seront également là. Non, je fais cela dans le gestionnaire, mais j'aurais pu facilement le faire dans le validateur aussi. Mais alors bien sûr, j'aurais dû injecter tout cela et créer une validation personnalisée sur la NDA pour m'assurer que je fais ce calcul et tout. Donc je vous donne juste les options en fonction de votre situation. Vous voudrez peut-être garder toutes ces choses à l'intérieur des validateurs. Vous n'utilisez peut-être même pas le validateur. Donc vous pourriez faire toute cette validation ici. Cela dépend de la façon dont vous voulez mettre votre code d'application. Donc maintenant, nous pouvons juste aller de l'avant et nettoyer n'importe quoi d'autre dans ce gestionnaire, nous pouvons avoir à revoir les données, mais au moins nous regardons comment nous développons notre gestionnaire et commençons à mettre d'autres choses dans leur vie HTTP, contexte, gestionnaire, accès ou autre, désolé. Donc, quand nous passons à autre chose, vous pouvez nettoyer tous les petits messages en cours de route et vous assurer que votre code peut compiler. Donc juste une construction rapide. Maintenant, passons rapidement à notre application. Nous voulons obtenir la fonctionnalité dans laquelle un employé peut demander un congé avant tout avant de mettre en place d'autres fonctions administratives et quoi que ce soit, n'est-ce pas ? Je veux donc que nous nous assurions que nous ayons ce modèle de vue. Je l'aurais présenté avant, mais laissez les requêtes VM et téléchargez tous les modèles de vue ici. Et ces modèles de vue proviennent vraiment du code existant en grande partie. Donc, le Create leave requests, VM, et qui prend la date de début, la date de fin, l'heure, l'ID feuille, et une zone pour les commentaires. Non, je sauterais au contrat pour le service de demande de congé où nous avons quelques méthodes que nous ne mettons pas toutes en œuvre pour l'instant, nous avons affaire à un crédit pour que vous puissiez aller de l'avant et les mettre toutes. Et créez l'implémentation du service correspondant et lui permettre de toutes les implémenter. Mais en nous concentrant sur la méthode de création, ce que nous avons est similaire à ce que nous avons fait avec les types de feuilles. Cependant, vous remarquerez que j'ai une ligne rouge sous la partie où je demande une réponse. C' est parce qu'en ce qui concerne le service IA , le client ou, ou insérer du code, nous ne cherchons toujours qu'une tâche. C' est parce que dans l'API, je dois faire deux choses. J' ai besoin de laisser la documentation ou que sur la poste, il devrait prendre la réponse de la commande de base. Rappelez-vous que nous avions équipé tous nos gestionnaires pour le rendre. Et c'est essentiel parce que lorsque nous utilisons n swag pour régénérer ou coder, ce que je suis sur le point de faire, alors il saura qu'il devrait s'attendre à ce type de réponse. Encore une fois, créez la copie locale la plus récente, allez-y et générez et sachez que cela est fait lorsque je saute à mon code, il n'y a pas de lignes rouges car maintenant il sait qu' il retourne la réponse de la commande de base. Donc tout est bon. Très bien, donc c'est fondamentalement ce que nous faisons dans la création de la demande de feuille. Donc, concentrons-nous maintenant sur la configuration du contrôleur et le code de support. Je suis allé de l'avant et j'ai créé un contrôleur avec des opérations de lecture-écriture, vous savez, pour le faire, non. Et j'ai injecté le service de type feuille et le service de demande de congé. Donc, vous vous demandez probablement, ok, pourquoi ai-je besoin du service de demande de type feuille et de congé si je ne crée que des demandes de congé, eh bien, le fait est que la vue que j'ai déjà créée a besoin d'avoir un drop- pour les types de feuilles parce que quand quelqu'un vient demander un congé, c'est basé sur votre flux. Mais la façon dont nous le construisons, ils viennent demander, laissez cela off pour sélectionner dans une liste déroulante qui laisse le type pour lequel ils choisissent, la date de début, la date de fin. Ensuite, ils sont en mesure de mettre leurs commentaires avant d'aller de l'avant et de sélectionner la demande. D' accord, donc c'est essentiellement ce que je fais et c'est le point de vue qui vient de l'ancien système. Donc littéralement, j'ai copié et collé cette vue de l'ancien système. La seule mise à jour a été que nous modifions le modèle pour devenir le nouveau modèle par opposition à n'importe quelle nouvelle espèce là-bas. Mais je vous montre juste que c'est la même classe. Ainsi, vous pouvez toujours aller chercher le fichier de code et simplement copier et coller. Et vous devriez être à zéro comme des quantités d'alpha. C' est pour ça que c'est là. Je n'utilise aucun sélecteur de date. Je ne complique pas encore l'interface. Donc je retire ça. Amis Becker Notre juste en utilisant perles de type d'entrée en fonction du Sélecteur de date par défaut donné à nous par le navigateur. Donc Buck dans le contrôleur, nous devons préparer cette liste déroulante avant le chargement de l'interface. Donc, au lieu de quatre, obtenez la méthode Create, ce que j'ai est un appel au service de type feuille pour obtenir tous les types de feuille, stockez-les dans cette variable. Et puis j'ai des éléments de type feuille où je crée une nouvelle liste de sélection avec des types de feuille et en utilisant id et name comme clé et les champs de texte. Et puis je crée le nouveau modèle où je passe dans les types de feuilles en tant qu'élément de type feuille. Donc, se souvenir crée des demandes de congé. Nous avons eu cet œil public innombrable sélectionner cette propriété d'élément, et cela aurait facilement été liste de sélection. D' accord ? Donc, celui qui fonctionne, mais nous permet de travailler avec sélectionnez ceci parce qu'il est en fait plus facile de taper sur le travail avec. Donc c'est tout ce qui se passe ici. Et puis nous retournons la vue montrant le modèle. Connaissant la méthode post, nous suivons à peu près la même procédure si l'état du modèle est valide. Parce que rappelez-vous que dans notre modèle de vue, nous avons quelques règles de validation, donc nous voulons nous assurer que tout est satisfait avant de pouvoir continuer. En fait, je me rends compte que je manque une règle de validation sur l'ID de type feuille lui-même. Ils doivent donc sélectionner un ID de type feuille avant de pouvoir continuer. D' accord, alors laisse-moi juste les espacer tous pour que tu puisses tout voir. On y va. Donc, si l'état du modèle est valide, alors allez de l'avant et largeur sur la réponse du travail du service de demande de congé, qui va essayer de créer une demande de congé. Et puis si cela réussit, alors nous pouvons rediriger vers l'index. n'y a pas de page d'index ici pour l'instant, mais ce n'est pas un problème. Et puis nous pouvons ajouter n'importe quel modèle, les flèches d'état du modèle provenant de nos erreurs de validation de réponse. Mais alors si la page doit se recharger, ce que nous devons faire est de recharger la liste de sélection des types de feuilles, n'est-ce pas ? Donc, une chose avec les listes déroulantes au cas où vous n'êtes pas si familier avec eux. Chaque fois que vous chargez la page, vous devez charger cette liste. Nous avons donc chargé la page premier niveau, où charger cette liste, puis retourner le modèle. Nous devons faire la même chose ici. Qu' est-ce que nous avons déjà les données provenant du modèle ? Nous avons donc juste besoin de réaffecter les données à la liste de sélection nouvellement chargée avant de retourner le pH avec les erreurs qui doivent être affichées. Maintenant, je parie autoriser le discours qui est assez standard pour le moment. Et dans notre fichier de mise en page, nous avons quelques changements. J' ai donc mis les liens là seulement pour que les employés puissent aller et créer notre point de vue. Ma feuille, je n'ai pas encore fait mon congé, mais voici nos liens, non ? Donc, dans la même chose C'est vérifier si l'utilisateur est authentifié. Je vois si c'est un employé qui est connecté parce que les administrateurs n'ont pas d'allocations, donc ils n'ont pas besoin d'aller et les demandes partent, n'est-ce pas ? Donc, si c'est un employé qui est connecté, alors ils peuvent voir deux nouveaux cygnes NoveLink aller aux demandes et créer. Et ça dit que les demandes partent, même si je vais partir, ce que nous n'avons pas encore fait, mais nous y arrivons lentement mais sûrement, non ? Donc, après avoir fait tout cela, allons de l'avant et définissons ou plusieurs projets de démarrage une fois de plus et testez cela. Alors maintenant, je vais me connecter en tant qu'administrateur de l'utilisateur, mais l'employé. Et une fois que je fais ça, je vois mes deux liens dans la barre de navigation. Donc, quand je vais aux demandes de congé, je reçois cette erreur. C' est une erreur 403 et je le vois et je sais exactement pourquoi. J' ai donc mentionné que nous sommes encore à compenser toutes les exceptions qui pourraient être lancées via l'API. C' est l'un d'eux. Il s'agit d'un 43 qui est une exception non autorisée. Le problème est que lorsque nous testions les points d'extrémité des donneurs de lot d'hôtel, nous avions défini un administrateur autorisé sur l'ensemble des contrôleurs de type feuille. Donc, sachez que cet employé a besoin d'avoir la liste des types de feuilles afficher pour lui. L' application fait cette demande sur ce point de terminaison, mais il n'est pas un administrateur. Donc, ce que nous pouvons faire ici est t l'auteur est hors ou au moins les rôles stipulation hors de l'autorisé et seulement autoriser ceux qui sont en augmentation les données de sorte que le post PUT et supprimer ces ajustements effectués. On peut réessayer cette opération. Et voilà, donc non, nous pouvons y naviguer en toute sécurité en tant qu'employé. Essayons donc de demander des congés de vacances. Donc, je crois que cette rubrique, vous pouvez voir qu'elle remonte jusqu'à Janvier, je suppose que le début de l'heure, nous pouvons toujours définir des valeurs par défaut parce que vous ne voulez probablement pas cette étendue de temps. Mais on ne va pas faire ça. Farnell, ce que je vais faire, c'est simplement sélectionner le 1er janvier au 5 janvier et remarquer que c'est le mois, l'année. C' est le format qu'il utilise. Tout cela est personnalisable, mais nous n'entrerons pas dans tout l'original. Donc congé de vacances. Et puis quand je demande de partir, je reçois une autre erreur. Donc, cette erreur, c'est dire que le paramètre ne peut pas être nul. Donc, je soupçonne que c'est une flèche revient de notre API qui n'est pas gérée une fois de plus, mais passons en mode de débogage et voyons exactement quel est le problème. Et voici le coupable. La partie cool c'est que nous essayons d'obtenir l'adresse e-mail. Alors laisse-moi revenir un peu. Nous avons l'utilisateur, nous avons les réclamations. Et si vous regardez là-dedans, nous avons la revendication de l'adresse e-mail. D'accord. Donc l'adresse e-mail est présente. Cependant, je crois que j'utilise la mauvaise valeur de réclamation ici. Dites si je retourne à l'endroit où a généré le JWT, qui est dans le service d'authentification. J' ai utilisé le même nom de réclamation qui était simplement e-mail. Droit. Donc, si je clique avec le bouton droit de la souris ou que je clique sur la touche Ctrl, vous verrez qu'il s'agit simplement d'un message texte statique. Cependant, en revanche, il est en fait de voir que propre avec une clé différente. Et cette clé est plus adaptée au schéma de savon XML. Et ce type de revendication serait en fait, ou ce texte serait effectivement présent dans les types propres. Alors laissez-moi arrêter et aller de l'avant et changer cela pour nettoyer les types pensée e-mail. Donc, il a échoué sur la récupération de l'adresse e-mail et c'est pourquoi nous ne l'avons pas fait. Eh bien, vous avez cette erreur, non ? Donc si nous vérifions notre table de demandes de congé, je suis presque sûr que nous allons vraiment voir des données, non ? Donc vous voyez ici que nous avons des congés annuels et c'est donc à chaque fois qu'il a été acheté, n'est-ce pas ? Donc, cela fonctionne en effet. C' était juste un échec lors de la récupération de l'adresse e-mail. Donc, avec ce correctif, nous devrions être en mesure de passer sans entrave. Mais alors vous voyez que quelque chose de complètement sans rapport avec l'opération de clé a causé l'échec, qui est une sorte de raison pour laquelle nous avons essayé toute cette capture d'essai pour simplement envoyer l'e-mail sans déranger tout le reste. Eh bien, nous voyons que c'est aussi un point d'échec. D' accord, on vient de le réparer. Eh bien, nous pourrions théoriquement prendre cela et aussi le placer à l'intérieur de la capture d'essai afin que tout ce qui concerne un e-mail ne génère pas d'erreur. Maintenant que nous avons le processus de demande, ne nous laissez pas faire de pause et quand nous reviendrons, nous examinerons leur processus d'approbation. 35. Gestion des demandes de congé - Partie 2 - Administration: Maintenant que nous avons notre demande de congé sur l'employé a dit, ne pas. Nous devons réellement mettre d'autres choses afin que l'administrateur puisse réellement voir les demandes en attente et approuver ou rejeter. Maintenant, cela vient avec quelques changements de rupture pour résoudre les gestionnaires et quelques autres requêtes, certains des détails, pas mal de choses que nous avons faites jusqu'à présent, mais comme d'habitude, je vais juste vous expliquer toutes les modifications nécessaires quelque part pour commencer off avec la graisse qui est effectivement allé de l'avant et créé cette classe de constantes de coût pour les types de réclamation sont discutés. Retirer les chaînes magiques comme mettre en UID plusieurs corps, non ? J' ai donc créé un type de revendications personnalisées, juste une classe statique publique. C' est en constantes sous le projet d'application. Et nous avons des inconvénients publics String UID égale UID. Donc, cela nous permet maintenant dans le service d'authentification de dire que les phénotypes costumes pointent UID et passent cela dans et partout ailleurs que nous pouvons avoir besoin de référencer ce type de plaine côtière comme nous l'avons fait dans les autres gestionnaires. Ensuite, nous pouvons simplement aller de l'avant et dire que les types de réclamation personnalisés point UID. Sachez qu'une autre modification que je fais est à notre service utilisateur. J' avais une méthode pour que tous les employés aient maintenant une autre pour obtenir seulement un employé basé sur l'ID utilisateur. Très bien, donc dans l'implémentation de cette méthode, fondamentalement je dis juste obtenir l'employé trouver par ID et puis je retourne un nouvel objet employé avec les différents champs inclus. Sachez que j'ai également mis à jour notre liste de demandes de congé, DTO, et j'ai ajouté les dates de début de l'heure, et en fait, celles qui n'étaient pas là auparavant, ainsi que l'objet de l'employé et l'ID de l'employé demandeur. Alors sachez que lorsque l'administrateur consulte la liste des demandes, ils peuvent voir ce que les demandes, dates de début et de fin de la demande de cetera, ainsi que les détails de la personne qui l'a demandée, auraient fait un des modifications semblables aux demandes de congé pour lesquelles nous avons veillé à inclure des renseignements sur les employés. Maintenant, une modification rapide au mappeur et à ce stade est facultative parce que je veux que vous pensiez de manière critique, pas seulement faire ce que je fais, mais y penser. Nous avons un champ appelé données demandées dans les objets de domaine de requêtes de congé. Donc, cela a été créé comme il a été modélisé à partir du système précédent. Rappelez-vous maintenant que nous sommes en train d'affiner le système et de nous débarrasser de certaines des redondances et citons les escargots. Et je pense que c'est l'un de ces citations fonctionne parce que les demandes de date qui est vraiment la date créée. Donc, nous sommes déjà en train de capturer la date. Chaque enregistrement est créé. Je n'ai pas besoin de mettre à nouveau le demandé, et franchement, nous ne l'avons pas fait dans un gestionnaire quand la requête est entrée. Donc, ce que je fais ici, c'est que je fais en fait un mapping, notre mappage personnalisé pour nos certains champs. Donc, je vois que chaque fois que vous mappez de l'objet de domaine au DTO, regardez dans le détail ou la destination, et obtenez le champ de date demandé. Et puis je veux que cela soit mappé directement à tout ce est dans le domaine de la création et laisser l'objet de domaine de requête. Très bien, donc encore une fois, c'est facultatif. Quelle sincérité, comment les frais que je viens de vous montrer la puissance de l'automne supérieure nous aide à juste grandir, assurez-vous que toutes les données sont là, il est pertinent et approprié endroit. Maintenant, passez à nos gestionnaires. J' ai donc apporté quelques changements dans le gestionnaire de demandes de congé et l'allocation et la perte de congé pour la liste et le détail. Donc, je vais commencer par la liste puisque celle-ci, je pense, a plus de changements qu'autrement. Donc, un, j'ai modifié la demande pour avoir cet indicateur pour dire est connecté utilisateur, qui signifie, essayons-nous d'obtenir la liste des demandes de congé pour l'utilisateur connecté sont pour un administrateur. Donc, dans le gestionnaire, j'injecte l'accesseur des contextes HTTP ainsi que je l'utilise. Ne croyez pas qu'ils sont là avant. Connaissez certains qui les injectent et tout ce qui n'était pas là avant. Non, n'hésitez pas à aller de l'avant et à reproduire. Mais alors à l'intérieur du gestionnaire, ce que je fais différemment, non, j'initialise les demandes de congé en haut, en haut. Et j'ai une autre liste pour le détail qui sera retourné, qui dans ce cas est la liste des demandes de congé PTO. Ensuite, je vérifie si la demande dit que c'est pour l'utilisateur connecté ou non, n'est-ce pas ? Donc, si c'est pour l'utilisateur connecté, je veux aller de l'avant et obtenir cet ID utilisateur là. J' utilise ma constante, voir comment belle et propre qui a l'air. Très bien, donc j'obtiens l'ID utilisateur et j'ai mis en œuvre une autre méthode pour obtenir des demandes de congé avec des détails relatifs à l'ID utilisateur. Alors passons à cette implémentation de méthode. Donc, dans le contrat pour je laisse des demandes que je dois obtenir des demandes de congé avec des détails, l'original que nous avons écrit ensemble et ce nouveau avec l'ID utilisateur de chaîne. Donc, celui avec l'ID utilisateur ajoute fondamentalement simplement une condition où l'ID demandeur sur l'enregistrement est égal à l'ID utilisateur transmis. Nous incluons toujours les détails du type de feuille et nous renvoyons cette liste. Maintenant, après avoir fait tout cela, j'ai utilisé le service utilisateur pour obtenir l'employé par rapport à l'ID utilisateur qui est, là. Et puis je fais un mappage de l'objet domaine dans nos détails. Ensuite, pour chaque objet de requête dans la liste des demandes ou des détails, nous lui attribuons une valeur d'employés. Donc, une fois de plus, ce serait si je suis connecté en tant qu'utilisateur et que je voulais voir ma liste de demandes. Ça va gérer ça. Maintenant, si l'administrateur le demande, c' est à peu près la même chose qu'avant, où nous avons juste tous les détails. Et puis pour chaque demande, nous allons vraiment chercher l'employé à la volée, non ? Donc, alors que nous connaissons l'employé parce que je suis l'utilisateur connecté, donc ce n'est qu'un de moi. Nous ne savons pas qu'il y a beaucoup d'employés différents. Donc, pour chaque demande, nous allons chercher cet employé et le mettre à l'intérieur de ça. Et à la fin de la journée, nous retournons les demandes. De même, je fais une opération similaire pour les allocations de congé, où je récupère toutes les allocations de la base de données ont une méthode similaire et à peu près ce code ressemble de la même façon. Très bien, donc juste de la même façon que nous ajoutons la demande de congé d'allocation naïve avec des détails relatifs à l'ID d'utilisateur. C' est la même méthode implémentée comme celle pour ou allocations de congé où l'ID employé est l'ID utilisateur et nous sommes la même instruction if. Nous avons ajouté le même genre d'inondation à notre demande, n'est-ce pas ? Donc demandez-nous qui est connecté utilisateur et ensuite nous avons la déclaration if. S' il est connecté, alors à peu près la même procédure que nous venons de voir. Par rapport aux allocations de congés. Cependant, alors j'ai obtenir les détails des demandes de congé. C' est alors que vous voulez une demande de congé. Alors imaginez-le. Lorsque l'administrateur voit la liste des demandes de congé, il ou elle doit cliquer sur cette demande pour ensuite aller à un écran pour voir si elle est en attente, elle est approuvée ou être en mesure d'approuver des centaines ou rejetée à ce moment-là. Droit. J' ai donc modifié les demandes get avec détails où j'ai mis dans cette ligne pour inclure les informations sur les employés. Donc à peu près toutes les modifications jusqu'à présent sont juste jetées dans le feu que nous devons mettre dans les informations sur les employés. Donc, puisque nous avons mis à jour cette classe de requête, nous devons savoir, laisser notre point de terminaison ou notre comportement reflète ce nouveau paramètre, non ? Donc au bout du compte, je vais passer dans un booléen. Est-ce l'utilisateur connecté que nous recherchons ? Si c'est ce que je fais par défaut dans les chutes, n'est-ce pas ? C' est ainsi que vous pouvez mettre dans un paramètre par défaut où si vous ne fournissez pas de valeur, alors c'est faux, non ? Donc, quelle que soit sa valeur, nous allons le passer dans l'objet requête, puis le gestionnaire rencontrera la décision comme nous venons de le voir. Donc, j'ai fait cela à la fois dans les allocations de congé et le gestionnaire de demandes de congé obtient. Comme d'habitude, une fois que vous mettez à jour votre EPA, tout ce qui a le bleu est tourné pour avoir quoi que ce soit dans le contrôleur, vous voulez réexécuter et swag et obtenir une nouvelle copie de ce code client. Ne voulez pas revenir à notre application client. Nous allons regarder notre contraste. Donc, les quelques prochaines que je veux absolument faire attention seraient l' approbation de la demande et d'obtenir la liste des demandes de congé d'administrateur. D' accord, et nous avons aussi besoin d'obtenir des demandes de congé par carte d'identité. Donc, au moins ces trois dernières doivent être mises en œuvre dès maintenant. J' ai donc d'autres méthodes là-bas, et à la fin de ce cours, elles seront mises en œuvre. Mais je ne vais pas passer trop de temps sur le trou du lapin d'essayer d'obtenir chaque fonctionnalité dans. Pour ce module, nous allons simplement nous concentrer sur le fait que l'employé puisse demander un congé et que l'administrateur puisse l'approuver ou le rejeter. Donc, après avoir inclus ces trois méthodes dans le contrat, nous passons à la mise en œuvre. Donc, bien sûr maintenant, je suis sûr que vous avez mis à jour votre code client. Donc tout ce que j'ai ici devrait fonctionner pour toi. Donc, pour la demande de congé approuvée, ce que nous faisons est de prendre int id et le drapeau ou le booléen pour voir est qu'il est approuvé Oui ou non. Ensuite, nous allons formuler ou des demandes où nous mettons en place des détails d'approbation de demande de congé de changement, et nous transmettons ce approuvé et l'ID. Et puis nous attendons le client appelant l'approbation de changement async, où il envoie sur l'identifiant et la demande. Notre demande de congé est assez simple. Il retourne juste le modèle de vue des demandes de congé. Nous ajoutons notre jeton de porteur bien sûr, ce que nous avons également fait dans l'approbation de la demande. Et puis nous allons de l'avant et essayons de Fitch à partir des demandes de congé get-go, obtenir une synchronisation avec mon ID et retourner la version baladée de la demande de congé sous la forme de la demande de feuille ViewModel. Nous regarderons cela dans quelques uns encore une fois. La prochaine méthode remarquable serait la get admin leave demandes par liste. Maintenant, je vais expliquer ce que je veux est dans la demande initiale sur ce que nous avions fait, c'est que nous avons reçu toutes les demandes de congé et que nous avons essayé de les regrouper et ensuite. Est-ce pour le total des demandes de congé, est-ce pour combien sont approuvées en attente, et cetera, etc. ? C' est exactement ce que je fais ici. Donc, je reçois toutes les demandes de congé et les notes cette fois j'ai ce paramètre est connecté à l'utilisateur deux-points faux. Je nomme juste le périmètre. Cette partie est en fait facultative, mais je la trouve utile. Donc, c'est que je ne peux pas me rappeler ce que la valeur signifie vraiment en termes d'appel de fonction. Mais je passe dans les chutes parce que ce n'est pas l'utilisateur connecté. C' est l'administrateur, non ? Donc, l'administrateur reçoit toutes les demandes de congé, puis je suis juste créer ce modèle de demande de congé d'administrateur modèle de vue. Et nous transmettons le nombre total de demandes, combien sont approuvées, rejetées, et nous mettons dans la liste des demandes de congé en général, et nous retournons le modèle. D' accord, donc une fois de plus, tout est lourd qui se passe à l'intérieur du service ? Non, à l'intérieur de nos configurations de mappings, je l'ai mis à jour pour refléter certains des nouveaux mappages que nous pouvons attendre. Donc, pour un détail de demande de congé pour quitter la VM de demande, il y a une légère différence dans le type de données entre les actes. D' accord, Donc d'un côté, nous avons datetime, mais alors le détail qui est généré via ou dans le code swag nous donne réellement un décalage datetime. Je ne suis pas tout à fait sûr pourquoi il fait cela, mais la solution serait que lorsque nous cartographions, nous disons juste quatre membres soignés demandés, aller de l'avant et le mapper à partir du temps de points demandé. Et nous le faisons pour la date de début, et nous le faisons pour la date de fin. Et cela va effectivement prendre soin de cette erreur. Donc, si vous ne le faites pas, si vous voulez le tester, vous pouvez les commenter. Essayez d'exécuter le code qui nécessiterait un mappage. Et puis vous verrez cette erreur supérieure d'automne disant que le mappage échoue pour les champs liés à la bêta. Très bien, de sorte que vous pouvez le faire pour les demandes de congé de quitter les demandes, VM, laisser les détails de la liste des demandes de congé à la VM demandes de congé. Et puis en plus de ces nouveaux, j'en ai aussi un ici pour l'employé où j'ai également créé la machine virtuelle de l'employé, qui ressemble exactement à l'employé ETO connaître à l'intérieur du fichier modèle de demande de congé voir. Examinons simplement certains des modèles de vue, au moins ceux qui sont absolument nécessaires pour que nous puissions compléter cette activité. Nous avons donc ajouté la machine virtuelle de l'employé avec employé à l'intérieur de cette vue modèles, bien sûr, nous verrons finalement deux propriétés avec le même nom. Il va essayer de les cartographier, non ? Donc, il est implicite que l'employé va mapper à l'employé du détail au ViewModel, n'est-ce pas ? Nous avons également la requête admin ViewModel que nous n'avons pas nécessairement regardé avant, non. C' est donc comme ces champs et le total des demandes, les demandes approuvées, demandes en attente, les demandes rejetées et la liste des demandes de congé. Ainsi, vous pouvez aller de l'avant et vous assurer que vous avez une représentation pour le ViewModel dans votre code. Mais revenir à notre contrôleur des demandes de congé est C. Vous savez que j'ai trois nouvelles actions sont 14, l'index, une pour les détails et une pour approuver les demandes. Donc, index qui prendra modèle et ce modèle sera de type admin quitter Requêtes Voir VM ou ce qu'il appelle le point de service de demande de congé get, levier admin, liste de quêtes sont l'administrateur verra cette page où une fois de plus ces statistiques et la liste des demandes en suspens seront affichées. Notre méthode de détails sera essentiellement là quand ils voient la liste et ils cliquent sur l'un des éléments. Et puis nous voulons aller chercher que laisser les demandes avec tous ses détails et retourner la vue en conséquence. Ensuite, nous avons le Approuver les demandes, pas approuver les demandes va essentiellement voir aller de l'avant et approuver la demande, il post HTTP. Donc, nous allons mettre une ferme sur cette page où nous allons appeler cela passer ID de demande de congé ainsi que si elle est approuvée ou non. Donc, s'ils approuvent ou rejettent n'importe lequel, il le transmettra. Et puis vous voyez comment il passe à l'API, au gestionnaire et ce qui se passe avant d'implémenter ces vues. Cependant, je veux simplement que nous fassions le suivi complet de ce qui se passe lorsqu'il est approuvé. Donc, je vais sauter sur les mises à jour, le gestionnaire de requête qui a subi un certain nombre de changements aussi. Et je vous guiderai à travers ça. C' est, bien sûr, vous faites une pause et répliquez comme vous le devez. Donc, nous savons injecter le dépôt Qi Shun en plus de tout ce qui a été injecté dans ce fichier. Et la raison en est que nous devons pouvoir déduire l'allocation lorsqu'il y a une approbation. Donc ce que nous faisons ici est de refactoriser notre méthode gérée pour cela. Donc, je reçois les demandes de congé d'abord, et puis je vois si nous traitons d'un détail de demande de congé que je veux exécuter la validation parce que ce qui se passait initialement ou la façon dont nous avons écrit le code initialement, le était en cours d'exécution, même si cela était nul ou non. Sachez si le test de validation pour valider notre null, alors cela va également lancer une erreur. Et jetez tout. Donc, nous validons simplement notre demande de congé DTO quand elle est présente. Et si tout va bien, nous allons de l'avant et faisons notre cartographie et nos mises à jour. Maintenant. Sinon, si c'est le détail des demandes de changement dv qui n'est pas nul, qui dans ce cas de l'approbation est alors pas plutôt que d'attendre la méthode de statut d'approbation de changement de dépôt de demandes de congé passant dans la requête. Et la graisse que nous voulions notre prouvé. Ensuite, je vais dire si le point de requête change le détail d'approbation, c'est approuvé, valeur point, si c'est vrai, n'est-ce pas ? C' est tout cela qui évalue vraiment l'équivalent à vrai. Mais bien sûr, lorsque vous traitez avec des Booléens, vous n'avez pas nécessairement à voir l'équivalent de vrai. On peut juste voir si le booléen, non ? Et nous n'avons pas à nous soucier d'une autre exception parce qu'elle devrait toujours l'être, elle devrait toujours avoir une valeur. Donc c'est un autre objet que nous pouvons faire vers le détail parce que maintenant je pense que nous l'avons rendu nullable, ce qui non, nous pensons que c'est faux. Il devrait toujours avoir une valeur tellement que je vais supprimer ce booléen et nous pouvons mettre à jour notre code client swag en conséquence, mais plus tard, nous pouvons le faire. Donc, je suis en train de mettre à jour ce détail pour toujours être soit vrai ou faux. Donc, si c'est vrai, alors nous obtenons l'allocation pour l'employé. Donc, l'allocation var est égale pour obtenir des applications utilisateurs. C' est une nouvelle méthode. Donc, cette nouvelle méthode, une fois de plus, vous le mettez à l'intérieur du contrat. Mais lorsque vous l'implémentez, il prend essentiellement la chaîne en utilisant l'ID utilisateur et l'ID de type feuille. Alors on y va et on dit, donne-moi l'allocation de feuilles. abord, notre asynchrone par défaut, où l'ID employé est beaucoup l'ID utilisateur transmis et l'ID de type feuille correspond à celui transmis. Donc, après avoir fait tout cela, nous transmettons l'employé demandeur aux côtés des demandes de congé. Donc, nous avons la demande de saut ici. Nous avons l'employé qui l'a demandé et nous connaissons le type de feuille courtoisie de la demande une fois de plus. Et puis on va dire, donne-moi le numéro de B, non ? Donc, nous avons déjà vu que dans la création sont dans la demande plutôt, combien de D sont demandés. Dans cette situation, vous pourriez prendre une autre décision. Vous pourriez décider de stocker le nombre de D dans la base de données à partir du moment ou calculé à la volée comme nous le faisons, non. Donc c'est à vous de décider. Quoi qu'il en soit, nous obtenons le nombre de bières, nous allons de l'avant et adoptons le nombre de ceux-ci à partir du nombre de jours pour l'allocation. Et puis nous exécutons une mise à jour pour cette allocation, puis retournons. Non, en termes de nos vues que beaucoup nos contrôleurs, nous avons créé l'index et nous avons créé les détails. En vérité, l'index est une copie fractionnée de ce qui vient de l'ancien code. Donc, si vous avez téléchargé l'ensemble du code source ou vous pouvez très bien, C'est sur GitHub. Vous pouvez réellement tout retirer de cette page d'index des demandes de congé correspondant et s'il vous plaît ici, je n'ai rien modifié. Toute modification nécessaire serait due à des différences de nommage. Par exemple, ici, j'ai item.name employé au lieu de item.name employé demandant. En dehors de cela, cependant, le code est à peu près le même. Maintenant, pour les détails, j'ai fait quelques modifications parce que dans le code original, nous avions répété cette section d'alerte trois fois. Et ce que nous avons fait, c'est que nous avons dit, si approuvé, alors montrer ce code d'alerte avec un nom de classe différent à un texte caché différent. Sinon, si c'est vrai, alors montrez-le à nouveau avec le droit. Donc, au lieu de répéter ça et c'est une autre partie, sèche, ne te répète pas. Alors entrez facteur, vous voulez toujours dire, eh bien, quelque chose doit être répété à un moment donné, non ? Ou une opération doit être refaite. Mais lequel puis-je refaire avec le moindre chemin de résistance R, ce qui serait plus facile à maintenir à long terme. Donc, mon refactorisation de ce qui a été fait dans les détails d'origine pH serait que je crée deux variables ici. Un intéressant, un pour le titre, le texte de titre. Et puis si l'approbation est nulle, alors je donne ClassName et frappe prend leurs valeurs. Si c'est vrai, je leur donne des valeurs différentes, et cetera, pour. Et puis je charge le div avec l'autre à un moment où je passe dynamiquement ce nom de classe et les textes de titre, parce que tout le reste à l'intérieur de cette alerte sera le même indépendamment, non ? Donc je dis le nom de l'employé et ensuite j'ai mis dans le modèle lot le prénom et le nom de famille de l'employé. La date demandée est qu'ils ont demandé de revenir du modèle. Et puis à peu près tout le reste est le même jusqu'à la dernière partie où nous vérifions si elle est approuvée ou non. Donc, au lieu d'avoir à lier des boutons comme le code original les avait jamais dans les fermes où ils ont discuté pourquoi les forums sont beaucoup plus sécurisés. Donc, pour la méthode post est l'axone prouver demande. Et dans celui-ci, j'ai l'ID qui est un caché, et il a une valeur pour l'idée de module ont également un autre caché qui a le nom approuvé et la valeur est vraie. Je répète que le flux pour le rejet, sauf que la valeur pour l'approuvé est false. Donc, quand ils cliquent sur l'un de ces boutons va appeler les demandes d'approbation, qui va alors obtenir l'ID et les coûts approuvés que nous ne sommes pas juste passés par ce que le gestionnaire fait avec toutes ces informations. Très bien, donc nous avons ce module depuis un certain temps, et c'est généralement le module le plus difficile et le plus long. J' ai essayé de réduire le temps autant que possible, mais il y a encore beaucoup à faire, mais au moins vous avez les concepts fondamentaux pour que vous puissiez le prendre et continuer. Alors laissez-nous juste prévisualiser à quoi ressemblera ces demandes de congé du point de vue de l'administrateur. Et les demandes hebdomadaires de clive veront la liste des demandes de congé. J' en ai donc déjà approuvé et rejeté un et c'est à quoi ressemble ce code. Et celui-ci est en attente d'approbation et nous voyons la date de début, la date de fin, le type de congé annuel, le nom de l'employé, tout est sympa et, vous savez, crachez pour nous. Donc, si je clique sur Review, nous allons à la page où il est dit en attente d'approbation qu'ils ont demandé et puis je peux approuver ou rejeter. Donc, si je clique sur Approuver, alors il redirigera en supposant qu'il n'y a pas d'erreurs. Et en fait, il y a une erreur. Très bien, Donc le problème ici est que j' utilise le code de la création afin de faire le calcul, ce qui est complètement incorrect parce que je devrais utiliser objet de demande de levier et ne pas demander le détail des demandes de congé de points, accord, alors laissez-moi juste mettre à jour cela et nous pouvons recommencer cette opération. Bon, alors essayons encore. Je vais cliquer sur Approuver. Et là, nous voyons que ce n'est pas approuvé. Sachez que le problème que nous allons devoir résoudre plus tard est le fait que nous avons plusieurs opérations en cours sur plusieurs tables. Mais devine ce qui s'est passé ? Un participant et l'autre partie ne l'ont pas fait, ce qui signifie que cela a été approuvé, mais la déduction n'a pas eu lieu parce que nous avons eu un échec sur ce lac. Droit. Donc, nous avons effectivement fait l'approbation avec succès, mais alors la partie de la déduction n'a pas traversé, donc elle n'a pas été mise à jour. Et ce que nous voudrions faire est de faire quelque chose comme notre rôle buck, ce devrait être tout ou rien. Donc, si une partie des champs alors tout devrait se sentir. C' est là que l'unité de travail entre en jeu ou au niveau de la base de données que nous appelons des transactions. Donc, plus tard, nous examinerons tous ces problèmes d'entretien avec notre application. Chaque fois qu'une application aussi grande, vous devez faire attention à ces choses. 36. Unité de travail pour des opérations en lots: Dans cette leçon, nous allons mettre en place un middleware global de gestion des exceptions pour notre API. Donc, ce qui se passe, c'est que nous avions des exceptions personnalisées que nous avons créées depuis presque le début du projet. Nous avons lancé des exceptions à certains moments dans nos gestionnaires. Cependant, nous n'avons pas nécessairement dit l'API entière qu'elle devrait répondre lorsque des exceptions sont lancées. Donc, bien sûr, vous voudrez toujours échouer gracieusement s'il y a un type d'exception, nous voulons renvoyer un code qui est indicatif du type d'exception. Par exemple, j'ai mis à jour tous mes gestionnaires de mise à jour pour lancer également une exception introuvable. Donc, pour savoir, laissez-moi juste corriger celui-là. Tellement ouvert à savoir. Je n'avais pas le code. Si vous aviez déjà le code, alors c'est bien. C' est des félicitations pour toi, non ? Mais nous lançons des exceptions de validation lorsque la validation échoue. Mais alors ce qui se passe si l'enregistrement à trouver n'était pas le téléphone, alors nous voulons une exception non trouvée. Donc, j'ai ajouté que sur chaque chèque pour voir si l'allocation de congé est trouvé, si les demandes de congé, C'est un bateau à mettre à jour son téléphone et si le congé désolé, le type de feuille, leur but. Si le type de feuille est le téléphone, nous lançons juste une exception introuvable. D' accord ? Donc, lancer l'exception est assez facile. manipuler est une autre chose. Donc, notez qu'il n'y a pas de captures d'essai sur. Ce serait un peu autoritaire en avant d'essayer de mettre la capture d'essai et tout le monde. Donc, ce que nous allons faire est de configurer et de gérer les exceptions middleware au niveau de l'API parce que le contrôleur utilise des médias pour l'appeler un gestionnaire, mais nous n'avons pas non plus de prises de piste ici, donc nous revenons toujours, ok ? Mais puis il y a des moments où l'exception est levée et il Ok, peut être jeté. Et dans l'API est littéralement juste jeter un peu de réponse aléatoire sur le client. Nous voulons nous assurer de savoir ce qui est jeté. Alors allez-y et créez un nouveau dossier dans le projet API appelé middleware. Et dans ce dossier, créez un fichier appelé middleware d'exception. C' est donc notre intergiciel d'exception croisée. Et je vais juste vous guider à travers ce que ça va faire sur le web ou les détails. Donc, nous avons une classe dans ce fichier, dans cette autre classe appelée détails d'erreur. Je vous promène juste à travers les parties les plus simples d'abord. Et les détails de l'erreur ont juste le type d'erreur et un message d'erreur. Donc au moins, nous pouvons toujours informer le client que c'est ce qui a mal tourné fonction des circonstances auxquelles nous sommes confrontés. Maintenant. Tout ce qu'il dit que nous avons à l'intérieur de la classe pour middleware exceptionnel, nous avons un champ privé en lecture seule appelé next, et c'est de type requête délégué. Donc, nous instancions cela dans le constructeur. Et puis nous avons une méthode appelée appeler un évier. Donc, AsyncTask public invoque async et il prend un paramètre appelé contextes HTTP. Nous avons donc déjà regardé ce que les contextes HTTP nous permettent de faire. Fondamentalement, il nous permet de voir la requête, la réponse, tout avec un workflow entier entre le client et serveur est stocké à l'intérieur de ces contextes HTTP. Donc ça va agir comme un intercepteur, va essayer de voir. Il va dire faire l'option suivante qui devrait être complétée via les contextes HTTP. C' est essentiellement ce que ça fait. Elle. Les contextes HTTP font votre option suivante. S' il y a une exception, attrapons-la et nous la gérerons. Maintenant, passons à la façon dont nous gérons ça. Donc, l'exception de handle de tâche privée est le collecteur où vous donnant le contexte HTTP et l'exception qui a été interceptée. Sachez que nous disons juste que nous voulons qu'une réponse poncée soit une application Slash JSON parce que c'est l'API. Donc, nous savons que tout ce que nous répondrons sera sous la forme de JSON. Nous définissons également une erreur de serveur interne par défaut, école d'état du code d'état HTTP est par défaut celle qui est 500. Ensuite, nous allons dire que le résultat est égal à, je ne veux jamais sérialiser les objets dans une nouvelle instance de flèche avec le message d'exception. Bon, donc on sérialise tout ça dans les résultats nuls quand on passe à l'interrupteur. Où voir fondamentalement quel type d'exception est-ce, parce que l'exception est le type de données de base. Mais comme nous l'avons vu, nous avons nos propres exceptions. Nous avons l'exception de validation, nous avons le laissez-moi sortir l'exception des demandes de beurre. Nous avons l'exception introuvable. Donc, nous pouvons rendre compte de tous ces comptes pour une mauvaise demande. Je ne comptabilise pas la validation. Moi. Allez-y et mettez-le à jour. Donc ce que nous faisons ici maintenant, c'est de voir me dire quel genre d'exception c'est. Je sais que c'est une exception, mais quel type était ce n'était vraiment pas si mauvaise demande. Une exception de validation doit plutôt je ne suis pas trouvé. Basé sur le seul point à faire, c'est que nous allons changer le statu quo. Donc, c'est par défaut 50, 100. qui signifie que si c'était juste l'exceptionnel, peut-être que c'était au niveau de la base de données, peut-être que c'était une panne de réseau que nous ne pouvons pas boucler. Et quatre, alors c'est définitivement un 500. 500 signifie que c'est un système, le système que l'API utilise, c'est la faute du système. Cependant, de mauvaises requêtes indiqueraient que vous êtes en faute en tant que client, mais vous m'avez envoyé des données d'ordures. Donc je vais vous dire que c'est une mauvaise demande, qui est il y a 400 ans. Si c'est une exception de validation, c'est aussi une sorte de mauvaise requête parce que vous m'avez envoyé des données, mais vous pouvez toujours regarder et voir quel autre code pourrait ou mieux pour le type d'exception. D' accord, mais tu veux toujours rester dans la gamme 400 avec des codes d'erreur, non ? Donc c'est là que nous sommes. Donc je veux dire pour toi, c'est seul. Donc celui-ci dit Mais la requête et puis l'exception non trouvée est un 40, ce qui signifie que je ne pouvais pas trouver ce que vous cherchez. Donc 40 pour donc si rien de tout cela n'était le cas, alors nous venons de casser et ça resterait comme un 500. Ensuite, nous voyons répondre avec le code d'état et retourner avec le résultat. Résultat, c'est-à-dire le message entier qui faisait partie du message d'exception. Alors rappelez-vous que lorsque nous sommes en train de mettre en place nos exceptions ou de jeter nos exceptions de nos chasseurs, étaient toujours assis le message. Et ce message est ce qui est en train de se sérialiser ici. On m'envoie bokeh a déclenché cette réponse. Null si vous voulez qu'il soit un peu plus explicite. Parce que tout ce que nous faisons est d'envoyer une flèche avec un message d'exception, nous pourrions utiliser nos détails d'erreur. J' aurais pu dire de nouveaux détails d' erreur, puis le message d'erreur serait le message et le type d'erreur pourrait être autre chose. Donc, je dirais Eric Type Tool et ensuite probablement juste dire l'échec, notre erreur, quoi que ce soit afin que vous puissiez faire preuve de créativité. Je veux dire, c'est à vous de voir ce que, encore une fois, c'est ce qu'ils obtiendraient dans leur réponse, quoi que vous mettiez là. Donc, un mode que nous avons fini de configurer ce middleware, nous devons passer au fichier de démarrage pour l'API. Et l'encartement de la Configurer sexuelle. On va lui dire d'utiliser le middleware. Donc je vais juste le faire juste au-dessus de tout le reste. Je ne veux pas dire que DOT utilise le middleware, exception sur le middleware. Allez-y et ajoutez les références manquantes. Et on y va. Donc, nous avons tous notre middleware essayant d'attraper globalement, puis de gérer gracieusement la façon dont il répond à n'importe quel client qui est son appel. Je voulais juste revenir à l'implémentation une fois de plus et avoir un ajustement rapide. Je ne sais pas pourquoi j'ai eu si c'était au départ. Donc, avec les résultats de l'exception de validation, nous voulons vraiment que les erreurs d'exception soient dans le corps, n'est-ce pas ? Donc les messages de validation, une chose, très bien. Mais alors nous voulons que les résultats soient égaux à la sérialisation JSON de la validation des flèches, non ? Donc, une fois de plus, vous avez beaucoup d'options sur la façon de gérer la situation. Donc, nous sommes assis le message d'exception par défaut, mais nous le remplissons dans le cas de l'erreur de validation. Donc, ce sera la liste des erreurs. 37. Gestion d'exception API: Très bien les gars, bienvenue. Cette leçon est inspirée par le point d'échec que nous avons vu lorsque nous modifions l'état d'approbation des demandes de congé, nous avons vu qu'une partie de l'opération était terminée et que l'autre partie a échoué. Mais alors nous avons besoin des deux parties pour réellement fonctionner avant de pouvoir mettre à jour la base de données. Donc, ce que nous faisons maintenant, c'est mettre en place ce que nous appelons une unité de travail, qui dit fondamentalement que j'ai tout ce travail à faire. J' ai tous ces points de contact. Je vais faire toutes les opérations et ensuite faire un commit final dans la base de données, nous réussirons ou non. Donc, ce que nous avions était chaque dépôt enregistrant les modifications de son propre chef. Donc, si cela, s'il y avait une opération qui nécessitait deux dépôts pour enregistrer d'un côté que les autres champs, alors nous aurions dans des données cohérentes dans la base de données et nous voulons éviter cela. Je suis donc allé de l'avant et j'ai mis en place ce contrat de travail afin que nous sachions où vivent les contrats dans votre dossier de persistance d'application I unité de travail. Il hérite de moi jetable. Et c'est essentiellement juste faire référence aux trois interfaces de référentiel que nous connaissons. Très bien, donc je laisse l'allocation, laisse les demandes et le type de feuille, et il a une méthode qui dit que l' implémentation de Save nodes vit dans le même dossier que l'implémentation pour les autres référentiels. C' est donc l'unité de dossier des dépôts de couche de persistance. Donc, à l'intérieur de cette implémentation, nous héritons des unités de travail. Nous avons notre contexte DB en cours d'injection. Très bien, et nous avons référencé tout le dépôt, donc j'ai des champs privés pour chaque dépôt. Donc mal guidé ce fichier agit comme si je m'inscrirais pour les dépôts que nous avons, veux maintenir les référentiels uniques. Parfois, vous verrez effectivement une unité de travail où elle est construite autour des référentiels génériques. Donc, et chaque implémentation sera juste générique car il y a tellement de méthodes uniques dans nos dépôts veulent garder le dépôt unique est référencé ici. Donc plus tard dôme, nous avons en fait la propriété publique que beaucoup est chacun et laissez-moi juste BreakLine afin que vous puissiez le voir plus clairement. Donc le public, je quitte le dépôt d'allocation, ça va s'appeler le dépôt d'allégations DV. Je suis fondamentalement, nous effectuons juste je reçois donc nous voyons, Donnez-moi le champ privé et s'il est nul dans initialiser une nouvelle instance de l'implémentation du référentiel d'allocation de feuilles et passer dans ce contexte que nous injectez-le dans. Parce que rappelez-vous que chaque implémentation a ce contexte en cours d'injection. Très bien, c'est pourquoi nous devons nous assurer d'injecter dans le contexte et ensuite nous le transmettons à chacun. Donc, ces trois lignes ressemblent la même barre dans les noms et les types référencés. Ensuite, nous avons une méthode d'élimination qui va être appelée en arrière-plan où nous venons de jeter le contexte, puis supprimer la collecte finale des ordures. Et puis notre tâche d'enregistrer va avoir nos modifications de sauvegarde. Donc, en d'autres termes, vous ferez tout ce qui serait mettre, nous ajouterions, fera tout ce qu'il est. Ces référentiels doivent faire individuellement, mais nous faisons ensuite une dernière Sauvegarder. Très bien, donc après que vous avez implémenté cela ou que vous avez répliqué tout cela. Jetons un coup d'oeil à certains des changements qui sont nécessaires dans les autres dépôts. Commençons donc par un référentiel générique. Avant ce que nous avions étaient des individus Enregistrer les modifications dans l'annonce, la suppression et les méthodes de mise à jour. Bon, donc maintenant je reçois ce Groenland parce qu'il n'y a plus d'appel asynchrone à l'intérieur de ces tâches asynchrones ? Eh bien, nous pouvons aborder cela plus tard, mais mon point est que j'ai supprimé toutes les lignes Enregistrer les modifications de ces méthodes particulières parce que nous ne voulons pas qu'elles voient si nous devons faire plusieurs choses. Vous voulez ajouter quelque chose et supprimer quelque chose et faire une mise à jour. Nous voulons un commit final dans la base de données. Tout ou rien par unité de travail se trouve dans chaque gestionnaire. Parce que rappelez-vous, les gestionnaires traitent essentiellement de scénarios. Nous voulons donc que le scénario complet soit terminé, tout ou rien. Nous avons donc supprimé toute la mer de modifications du référentiel générique ainsi que de tout autre référentiel individuel qui aurait pu avoir une sauvegarde des modifications en cours d'utilisation. Donc, comme dans les allocations où la moyenne devait enregistrer les modifications, j'ai supprimé cela. Et dans les demandes de congé, nous avons eu les modifications Enregistrer en cours à l'intérieur de cette méthode pour mettre à jour, à droite. Pour modifier le statut d'approbation, j'ai supprimé tout cela. Maintenant, avec ces suppressions, nous devons mettre à jour nos gestionnaires pour qu'ils s'adaptent correctement. Donc, je vais passer aux demandes de congé Créer, et je vais vous montrer exactement quel genre de refactoring se produirait. Premièrement, nous aurions interagi avec deux ou trois référentiels dans ce gestionnaire. Donc j'aurais injecté je quitte le dépôt, je quitte le dépôt d'allocation, et cetera, et cetera. Sachez que nous n'avons qu'à injecter ou une unité de travail. Et avant d'aller plus loin, permettez-moi de signaler que nous savons qu' il faut l'enregistrer au lieu de l'enregistrement des services de persistance. Au même endroit où vous auriez enregistré tous les dépôts où nous commençons juste notre unité de travail. Donc, cela en fait un composant injectable. Bon, maintenant on peut remplacer tous les individus par l'unité de travail I. Non, tu es confronté à un tas de lignes de FRD. Eh bien, sachez où vous aviez le dépôt de type de soulignement comme champ privé. Vous pouvez maintenant remplacer cela par un référentiel de type feuille de point de travail parce que vous lui donnez le même référentiel juste à travers l'unité de travail. Donc c'est comme notre registre pour tous les dépôts hors de moi. Mention de ça tout à l'heure. Donc, je mets juste en évidence tous les changements que j'aurais fait savoir que j'utilise l'unité de travail sur l'unité de travail carrée pour le dépôt d'allocation de congé, unité de quatre pour le dépôt de demandes de congé. Et puis, lorsque nous avons une opération qui augmente les données, nous faisons une Sauvegarder. Tu vois ça ? Maintenant, pendant que je suis dans ce gestionnaire de demande de congé de création, je voulais juste souligner un autre point d'échec que j'ai vu dans mes tests et que vous avez probablement rencontré et je veux juste que nous l'abordions ici. C' est là qu'il n'y a pas d'allocation parce que j'ai essayé demander un congé de maternité avec une employée qui n'a pas de congé de maternité. Donc, vous avez deux façons de faire face à ça. Premièrement, vous pouvez seulement, vous pouvez filtrer cette liste de types de feuilles uniquement sur les types de congé qui sont alloués à cet utilisateur. Ainsi, l'utilisateur ne serait jamais en mesure de demander quelque chose pour lequel il n'a pas d'allocation. Et franchement, je pense que c'est une bonne façon de faire à cela crée un nouvel appel de dépôt où vous obtenez ces listes pointues et vous avez envoyé, mais pas des moindres, je pense que c'est assez facile. J' ai cependant fait un ajustement dans ce gestionnaire dans l'intervalle pour dire obtenir l'allocation. Alors rappelez-vous que nous avons l'allocation et ensuite nous avons calculé le d est demandé. Et si le d est demandé, dépassé, alors nous avons ajouté une erreur de résultats de validation, non ? Ce que je fais ici, c'est que je vois si l'allocation ne l'est pas. Donc avec la nouvelle version de C Sharp, vous n'avez pas à voir est équivalent à savoir que le poste vacant est non, non ? Donc, si cela revient comme null, alors nous ajoutons une erreur de résultat de validation pour l'ID de type feuille, disant que vous n'avez aucune allocation pour ce type de feuille. Donc, c'est un ajout simple, sinon. Vous pouvez aller de l'avant et répliquer cela ou vous pouvez essayer vous-même pour obtenir la liste filtrée pour cet utilisateur particulier qui est sur le point de demander un congé et afficher uniquement les types de feuilles pour lesquelles ils sont éligibles, selon le cas. Passons maintenant au gestionnaire de commande de la mise à jour leave requests, qui est l'endroit où nous avons vu les points de défaillance réels que nous essayons d'aborder MAINTENANT avec l'unité de travail. Donc, une fois de plus, injecter seulement les unités ont été forcées dans ce gestionnaire. Et tu verras que c'est beaucoup plus compact, non ? Et puis chaque ligne, vous avez juste à dire que les unités sont quatre points le référentiel approprié et point point la méthode. Sachez quand on augmente les données. Rappelez-vous que nous avons dit que si la demande arrive avec le DTO, alors nous allons de l'avant et faisons notre mappage appelé mise à jour. Et puis je vais appeler les unités de travail pour sauver. D' accord. Plus tard, ne pas s'il s'agissait de l'approbation de la demande de modification et c'est là que nous avons vu la faute, nous allons aller de l'avant et changer leur approbation. Et puis si elle était approuvée, alors elle mettrait à jour l'allocation. Et puis celui-ci a fonctionné, mais puis ce seul domaine, donc il a été approuvé et la personne de ceux-ci n'a pas été adopté, ce qui a causé une incohérence. Donc non, cette personne serait partie en vacances pendant 10 jours et reviendra et nous reviendrons voir que c'est encore souvent ceux-ci et rompu plie et personne ne le remarquerait. Nous allons donc nous assurer que notre système n'est pas en faute. À droite. Nous avons donc mis à jour la modification de l'état d'approbation. Très bien. Ensuite, si elle est approuvée, nous mettons à jour le nombre de jours et ensuite nous économisons. Donc, si cela échoue, cela se produit dans la base de données. Maintenant, avec ce changement et l'unité de l'endroit où est introduit, c'est en fait un facteur plus important parce que vous devrez réellement aller dans chaque gestionnaire qui traitait d'augmenter les données et une unité de travail d'injecteur pour probablement changer les anciennes références aux référentiels, partout dans le monde. Et puis trois, assurez-vous que vous appelez la méthode de sauvegarde de l'unité de travail. Maintenant que vous avez fait ce facteur de risque énorme, d'accord ? Et surtout quand vous avez fait cela pour le gestionnaire de commande de type feuille et d'autres points de discorde qui apparaîtront sont nos tests unitaires. Parce que rappelez-vous, au moins nous avons fait les tests unitaires pour le gestionnaire de commande de type feuille ensemble et savons que vous changez l'injection, vous changez quelque chose à ce sujet. Donc, en fait, si vous compilez à ce stade, vous obtiendrez probablement quelques erreurs dans les fichiers de test parce que null certaines choses n'existent plus. C' est 12. Le fait que l'opération a changé en général, nous devons mettre à jour les artistes. Commençons par les simulations parce que c'est probablement là que vous obtenez la première erreur que le repo Mach n'existe plus ou que les garçons moqueurs ne sont plus du type dont il a besoin. C' est très bien. Donc, ce que j'ai fait est créer un nouveau fichier Mock que j'appelle des unités de travail fictives. Et c'est le même principe que la fumée précédente, où j'instancie juste un simulacre de notre unité de travail. Ça s'appelle obtenir des unités de travail. C' est une méthode. Et j'ai simulé, vous w est égal à une nouvelle instance de l'unité de travail simulé. Non, j'ai le type de feuille fictive. Permettez-moi de corriger ce repo de type feuille fictive. C' est à ça qu'on avait affaire, non ? C' est donc le test que nous avons écrit pour tester les types de feuilles. Sachez que j'utilise l'unité où je dois me moquer du dépôt à l'intérieur de l'unité de travail. Et j'ai déjà le code pour se moquer des unités du dépôt de type elif, désolé, d'accord, donc j'ai déjà ça. Cette méthode n'a pas à changer du tout. D'accord. Nous le remplissons avec des données de test et nous avons fait tout cela. Non, j'ai besoin de mettre ce Mach dans la maquette de l'unité de travail. Donc tout ce que je fais ici, c'est de voir des simulations. Le repo de type est égal à appeler cette classe simulée et obtenir le référentiel de type feuille. Et puis mon avis de configuration est que le référentiel de type feuille retournera cet objet simulé. Puis je rentre ces unités de travail fictives. Donc maintenant dans le test réel pour le gestionnaire de type feuille, et je viens de commenter certaines des lignes juste pour vous montrer ce que j'ai changé exactement. J' ai introduit un nouveau champ de type simulateur I unités de travail appelé simulateur. Vous aurez w, w unité de travail. Et puis je l'ai instancié à l'intérieur du constructeur en appelant mes unités fictives de points de travail a2 ou de fourche. Ensuite, tout le reste reste le même. Ne pas aligner. Eh bien pour moi, 42, 43, où je vois que le gestionnaire n'est pas une nouvelle instance qui prend l'unité de travail fictif par opposition à l'ondulation simulée a précédemment utilisé et cet objet, alors tout le reste coulera. Donc au moins ne pas dans les tests que nous avons à dire unité simulée de l'objet point de travail, dépôt de type feuille de point obtient tout. De même l'unité simulée de l'objet point de travail dépôt lifo point obtient tout. Sinon, les tests vont passer et vous êtes prêt à y aller. Donc, une fois de plus, les tests unitaires vous montreraient des points de remplissage ou des points de défaillance potentiels dans différentes parties de votre application juste au cas où ils le seraient, ou ils ont subi des activités massives de refactorisation. Mais c'est vraiment tout pour cette activité où nous ajoutons les unités de travail. J' espère que vous en voyez la valeur et que nous continuerons à améliorer notre application dans les leçons qui suivront. 38. Expirer le jeton: Dans cette leçon, nous allons mettre en place un middleware global de gestion des exceptions pour notre API. Donc, ce qui se passe, c'est que nous avions des exceptions personnalisées que nous avons créées depuis presque le début du projet. Nous avons lancé des exceptions à certains moments dans nos gestionnaires. Cependant, nous n'avons pas nécessairement dit l'API entière qu'elle devrait répondre lorsque des exceptions sont lancées. Donc, bien sûr, vous voudrez toujours échouer gracieusement s'il y a un type d'exception, nous voulons renvoyer un code qui est indicatif du type d'exception. Par exemple, j'ai mis à jour tous mes gestionnaires de mise à jour pour lancer également une exception introuvable. Donc, pour savoir, laissez-moi juste corriger celui-là. Tellement ouvert à savoir. Je n'avais pas le code. Si vous aviez déjà le code, alors c'est bien. C' est des félicitations pour toi, non ? Mais nous lançons des exceptions de validation lorsque la validation échoue. Mais alors ce qui se passe si l'enregistrement à trouver n'était pas le téléphone, alors nous voulons une exception non trouvée. Donc, j'ai ajouté que sur chaque chèque pour voir si l'allocation de congé est trouvé, si les demandes de congé, C'est un bateau à mettre à jour son téléphone et si le congé désolé, le type de feuille, leur but. Si le type de feuille est le téléphone, nous lançons juste une exception introuvable. D' accord ? Donc, lancer l'exception est assez facile. manipuler est une autre chose. Donc, notez qu'il n'y a pas de captures d'essai sur. Ce serait un peu autoritaire en avant d'essayer de mettre la capture d'essai et tout le monde. Donc, ce que nous allons faire est de configurer et de gérer les exceptions middleware au niveau de l'API parce que le contrôleur utilise des médias pour l'appeler un gestionnaire, mais nous n'avons pas non plus de prises de piste ici, donc nous revenons toujours, ok ? Mais puis il y a des moments où l'exception est levée et il Ok, peut être jeté. Et dans l'API est littéralement juste jeter un peu de réponse aléatoire sur le client. Nous voulons nous assurer de savoir ce qui est jeté. Alors allez-y et créez un nouveau dossier dans le projet API appelé middleware. Et dans ce dossier, créez un fichier appelé middleware d'exception. C' est donc notre intergiciel d'exception croisée. Et je vais juste vous guider à travers ce que ça va faire sur le web ou les détails. Donc, nous avons une classe dans ce fichier, dans cette autre classe appelée détails d'erreur. Je vous promène juste à travers les parties les plus simples d'abord. Et les détails de l'erreur ont juste le type d'erreur et un message d'erreur. Donc au moins, nous pouvons toujours informer le client que c'est ce qui a mal tourné fonction des circonstances auxquelles nous sommes confrontés. Maintenant. Tout ce qu'il dit que nous avons à l'intérieur de la classe pour middleware exceptionnel, nous avons un champ privé en lecture seule appelé next, et c'est de type requête délégué. Donc, nous instancions cela dans le constructeur. Et puis nous avons une méthode appelée appeler un évier. Donc, AsyncTask public invoque async et il prend un paramètre appelé contextes HTTP. Nous avons donc déjà regardé ce que les contextes HTTP nous permettent de faire. Fondamentalement, il nous permet de voir la requête, la réponse, tout avec un workflow entier entre le client et serveur est stocké à l'intérieur de ces contextes HTTP. Donc ça va agir comme un intercepteur, va essayer de voir. Il va dire faire l'option suivante qui devrait être complétée via les contextes HTTP. C' est essentiellement ce que ça fait. Elle. Les contextes HTTP font votre option suivante. S' il y a une exception, attrapons-la et nous la gérerons. Maintenant, passons à la façon dont nous gérons ça. Donc, l'exception de handle de tâche privée est le collecteur où vous donnant le contexte HTTP et l'exception qui a été interceptée. Sachez que nous disons juste que nous voulons qu'une réponse poncée soit une application Slash JSON parce que c'est l'API. Donc, nous savons que tout ce que nous répondrons sera sous la forme de JSON. Nous définissons également une erreur de serveur interne par défaut, école d'état du code d'état HTTP est par défaut celle qui est 500. Ensuite, nous allons dire que le résultat est égal à, je ne veux jamais sérialiser les objets dans une nouvelle instance de flèche avec le message d'exception. Bon, donc on sérialise tout ça dans les résultats nuls quand on passe à l'interrupteur. Où voir fondamentalement quel type d'exception est-ce, parce que l'exception est le type de données de base. Mais comme nous l'avons vu, nous avons nos propres exceptions. Nous avons l'exception de validation, nous avons le laissez-moi sortir l'exception des demandes de beurre. Nous avons l'exception introuvable. Donc, nous pouvons rendre compte de tous ces comptes pour une mauvaise demande. Je ne comptabilise pas la validation. Moi. Allez-y et mettez-le à jour. Donc ce que nous faisons ici maintenant, c'est de voir me dire quel genre d'exception c'est. Je sais que c'est une exception, mais quel type était ce n'était vraiment pas si mauvaise demande. Une exception de validation doit plutôt je ne suis pas trouvé. Basé sur le seul point à faire, c'est que nous allons changer le statu quo. Donc, c'est par défaut 50, 100. qui signifie que si c'était juste l'exceptionnel, peut-être que c'était au niveau de la base de données, peut-être que c'était une panne de réseau que nous ne pouvons pas boucler. Et quatre, alors c'est définitivement un 500. 500 signifie que c'est un système, le système que l'API utilise, c'est la faute du système. Cependant, de mauvaises requêtes indiqueraient que vous êtes en faute en tant que client, mais vous m'avez envoyé des données d'ordures. Donc je vais vous dire que c'est une mauvaise demande, qui est il y a 400 ans. Si c'est une exception de validation, c'est aussi une sorte de mauvaise requête parce que vous m'avez envoyé des données, mais vous pouvez toujours regarder et voir quel autre code pourrait ou mieux pour le type d'exception. D' accord, mais tu veux toujours rester dans la gamme 400 avec des codes d'erreur, non ? Donc c'est là que nous sommes. Donc je veux dire pour toi, c'est seul. Donc celui-ci dit Mais la requête et puis l'exception non trouvée est un 40, ce qui signifie que je ne pouvais pas trouver ce que vous cherchez. Donc 40 pour donc si rien de tout cela n'était le cas, alors nous venons de casser et ça resterait comme un 500. Ensuite, nous voyons répondre avec le code d'état et retourner avec le résultat. Résultat, c'est-à-dire le message entier qui faisait partie du message d'exception. Alors rappelez-vous que lorsque nous sommes en train de mettre en place nos exceptions ou de jeter nos exceptions de nos chasseurs, étaient toujours assis le message. Et ce message est ce qui est en train de se sérialiser ici. On m'envoie bokeh a déclenché cette réponse. Null si vous voulez qu'il soit un peu plus explicite. Parce que tout ce que nous faisons est d'envoyer une flèche avec un message d'exception, nous pourrions utiliser nos détails d'erreur. J' aurais pu dire de nouveaux détails d' erreur, puis le message d'erreur serait le message et le type d'erreur pourrait être autre chose. Donc, je dirais Eric Type Tool et ensuite probablement juste dire l'échec, notre erreur, quoi que ce soit afin que vous puissiez faire preuve de créativité. Je veux dire, c'est à vous de voir ce que, encore une fois, c'est ce qu'ils obtiendraient dans leur réponse, quoi que vous mettiez là. Donc, un mode que nous avons fini de configurer ce middleware, nous devons passer au fichier de démarrage pour l'API. Et l'encartement de la Configurer sexuelle. On va lui dire d'utiliser le middleware. Donc je vais juste le faire juste au-dessus de tout le reste. Je ne veux pas dire que DOT utilise le middleware, exception sur le middleware. Allez-y et ajoutez les références manquantes. Et on y va. Donc, nous avons tous notre middleware essayant d'attraper globalement, puis de gérer gracieusement la façon dont il répond à n'importe quel client qui est son appel. Je voulais juste revenir à l'implémentation une fois de plus et avoir un ajustement rapide. Je ne sais pas pourquoi j'ai eu si c'était au départ. Donc, avec les résultats de l'exception de validation, nous voulons vraiment que les erreurs d'exception soient dans le corps, n'est-ce pas ? Donc les messages de validation, une chose, très bien. Mais alors nous voulons que les résultats soient égaux à la sérialisation JSON de la validation des flèches, non ? Donc, une fois de plus, vous avez beaucoup d'options sur la façon de gérer la situation. Donc, nous sommes assis le message d'exception par défaut, mais nous le remplissons dans le cas de l'erreur de validation. Donc, ce sera la liste des erreurs. 39. Expirer le jeton: D' accord, donc nous continuons à améliorer notre application, et cette fois nous nous concentrons sur notre application client. Donc, quelques scénarios ici que nous n'avons pas pris en compte, ou du moins nous les avons probablement rencontrés, mais nous ne les avons pas complètement abordés. Numéro 1, quand vous réalisez probablement maintenant que si vous vous êtes connecté il ya environ une heure et le proche Buffon votre tour d'utiliser un système. Ils obtiennent des exceptions de l'API pour 100 car le jeton qui est là, même si vous êtes affecté à l'application, tolkien est expiré. Donc le client remonte les choses, c'est bon. Mais lorsque vous essayez d'accéder à l'API et d'envoyer sur un jeton fixe, l'AICPA le rejette et l'application ne sait pas quoi faire. Donc, vous obtenez probablement ces pages d'exception. Et d'autre chose est que nous voulons configurer votre propre page personnalisée pour quand une demande de navigation non autorisée est envoyée. qui signifie que vous êtes un utilisateur, mais que vous essayez d'accéder à une page d'administration. Vous auriez vu MIGA l'erreur et vous avez probablement atteint la flèche où il essaie d'aller à une page appelée Access denied, qui est l'une des pages par défaut que nous n'avons pas éraflé dans cette application cliente. Donc, je vais vous montrer comment nous pouvons profiter encore plus de l'ensemble du contexte HTTP, le pipeline de requête. Nous l'avons juste fait avec la gestion des exceptions pour l'API et tout ce que nous allons regarder sur l'application cliente et comment nous pouvons gérer ces différents scénarios d'une manière globale. Commençons donc par le middleware costal que j'ai configuré. Et j'appelle son intergiciel de requête. Certains l'appellent demande le middleware parce que je voulais m'asseoir entre toutes les requêtes de navigation qui se produisent jamais dans notre application. Et puis tout comme nous l'avons vu avec l'API, nous pouvons toujours intercepté, interrogé et ensuite prendre une décision comme le mot devrait aller si elle répond à un certain critère sur. Mais commençons par un dossier appelé middleware dans le MVC et le fichier est appelé requêtes, le middleware. Donc, cela va être une classe publique qui prend le délégué de la requête suivante. Et j'injecte aussi mon service de stockage local va, rappelez-vous que c'est là que nous accédons au Tolkien à tout moment. Donc, nous allons de l'avant et les initialisons dans le constructeur, et ensuite nous avons notre tâche de méthode, invoquer un puits. Donc cette méthode a un gros essai, n'est-ce pas ? J' ai gagné un gros essai. Alors on va essayer. Et la ligne la plus simple serait tout comme nous l'avons vu dans l'API, serait aussi simple. Essayez d'attendre la prochaine vente aux enchères, puis attraper et gérer toutes les exceptions. D' accord. Cependant, avant d'aller de l'avant et de lui permettre d'essayer la prochaine action, nous voulons faire quelques vérifications. Donc la vérification que nous faisons est, et bien un, nous obtenons les points de terminaison. Donc, cette ligne EP représente le point final. Donc, les contextes HTTP pointent les fonctionnalités, obtenez la fonctionnalité de point de terminaison AI et obtenez les points de terminaison, ce qui signifie où allez-vous, où vous utilisez l'outil Rosing. Ensuite, je vais voir, est-ce que ces points finaux ont un attribut de métadonnées ? Alors rappelez-vous quand nos contrôleurs, ce sont essentiellement des attributs de métadonnées, non ? Donc, a-t-il un attribut de métadonnées, type d'attribut d'autorisation ? Eh bien, autorisé est de type autoriser attribut. Donc, je vois partout où vous naviguez outil, y a-t-il un attribut autorisé ne contrôle jamais ou sont jamais point de fin a un auteur comme attribut va à la maison n'a pas d'utilisateurs, n'a pas. Donc, si c'est le cas, ce qui signifie que nous avons quelque chose, ce n'est pas nul, alors nous voulons dire, ok, puisque ce point de terminaison est autorisé pour s'assurer qu'il y a un Tolkien et encore plus pour que ce jeton soit valide. Donc, je vais dire que l'attribut auteur n'est pas égal à null. Ou désolé, si ce n'est pas égal à null, alors donnez-moi le stockage local. Tolkien, d'accord, alors va vérifier s'il existe. Et puis je vois aussi que c'est valide parce que je suppose qu'il est valide en tout temps. Cependant, si elle existe, nous devons le valider encore plus d'âme, n'est-ce pas ? Donc je vois si le Tolkien existe, puis obtenir le Tolkien réel, puis j'utilise la poignée de sécurité, le gestionnaire de Tolkien. Nous savons ce dont nous avons besoin pour injecter une déclaration using pour cela. Et puis je vois Obtenir le contenu Tolkien, puis obtenir l'expiration, puis vérifier si l'expiration est faite. D' accord. Donc, si la date d'expiration est inférieure au point datetime 10, ce qui signifie que nous avons nous sommes loin ou où aucun passé, quel que soit le temps qui restera comme exploration, alors le jeton n'est pas valide. Ensuite, je vais dire si le jeton n'est pas valide ou le Tolkien n'existe pas, et remarquez les signes d'exclamation. Donc, cela aurait facilement pu être équivalent à false, qui est ce que je vais faire pour augmenter la lisibilité. Donc, si l'un d'entre eux est faux, alors nous voulons appeler une méthode que j'ai créée ci-dessous appelée sinusoïdes et rediriger le passage dans le contexte HTTP. Ainsi, les contextes HTTP vivent. De ce middleware, pas de problème, nous passons juste le long et puis nous revenons. Donc, cela signifie que n'importe quelle option est dite ici pointe l'option suivante. Nous n'arriverons jamais à celle-là si nous interceptons à ce stade. Aucun autre que je fais est si l'attribut auth a les règles. Donc, nous pouvons effectivement mettre en plusieurs lignes, vous pouvez voir la virgule d'administrateur, cette virgule qui, tant de règles que vous devez vérifier. Mais dans ce cas, je veux juste m'assurer que si les attributs de l'auteur, comme nous le voyons ici, sont limités aux administrateurs et que l'utilisateur n'est pas dans le rôle d'administrateur. Ensuite, je veux rediriger vers la maison barre oblique non autorisée. Donc c'est quand il était prêt à l'accès refusé par défaut. Donc, nous sommes juste en train de le remplacer et de voir aller à notre page personnalisée. Veuillez rediriger et retourner. Donc, si le jeton est valide, mais que vous n'êtes pas un administrateur essayant d'accéder à un chemin d'administrateur vers lequel nous allons rediriger, et c'est la fin de cela. Maintenant, il y a des situations où nous pourrions attraper une exception en essayant de passer par cette opération. L' une de ces situations serait avec l'API. Donc, parfois, il peut y avoir un problème de synchronisation avec l'heure, ce qui signifie que nous pouvons considérer le Tolkien comme n'étant pas expiré et valide. Mais quand il passe à l'EPA, l'EPA lance encore une exception en voyant 40 un an non autorisé. Très bien, donc dans cette situation, ce que nous allons faire est de déconnecter et de rediriger ont également une situation similaire au middleware d'exception API, où nous voyons l'exception. S' il s'agit d'un type d'exception API, effectuez cette action. Sinon il suffit de rediriger vers la page d'erreur barre oblique générale, de rediriger et de casser. Alors regardons ce qui se passe dans ce Seinfeld et redirigeons. Tout ce que nous faisons, nous vous envoyons tous hors du contexte http, tout comme ce que nous aurions des milliards, j'utilise un service, le temps des logos. Et puis nous allons vous rediriger vers le chemin pour les utilisateurs slash login. Donc boulons de la page de connexion, puis aller de l'avant et rediriger, puis nous revenons. C' est tout ce qui se passe à l'intérieur de ces zones. D' accord ? Et puis, fondamentalement, cela rend toujours ça là. Donc si tout ça est sauté, tout ça est sauté. n'y a pas d'attribut, alors allez-y et encerclez la requête suivante. Si nous attrapons une exception, soit nous allons à la page d'erreur ou nous supposons que si c'est une exception API, Sénat et rediriger, Bien sûr, il peut y avoir différents types d'exceptions EPA sont des scénarios différents avec eux. Ainsi, vous pourriez facilement avoir une autre méthode costale pour voir si l'exception API est de type. Ce type de réponse va ensuite à ce type de discours car cet objet d'exception EPA contient réellement du code de réponse. Donc, nous pouvons obtenir le code d'état plutôt. On y va, on peut obtenir le code d'état qui est renvoyé. Donc, si c'est 40, 1, alors sinus Alton redirige. Si c'est peut-être 500, alors faites-le. Rappelez-vous donc que nous avions configuré nos différents types de codes de réponse dans l'API. Donc on sait qu'on peut obtenir des demandes de beurre, on peut obtenir une validation, on ne peut pas avoir de téléphone, non ? Donc, basé sur le type de code d'état que nous attendons de l'API, il reviendra dans l'exception et ensuite nous pouvons le gérer. C' est donc une façon rapide et sale de gérer ce qui se passe lorsque les Tolkien sont expirés ou si nous avons différentes exceptions que nous ne sommes pas en mesure de gérer. Et comme vous voyez plus d'exceptions, bien sûr, vous pouvez mettre plus de capacités de gestion dans le middleware. Non. Rapidement dans la maison. Certains redirigent vers ou est-ce que je redirige vers un accès refusé ou non autorisé discours. Il n'y a rien de fonds qu'il est créé dans le contrôleur de maison et une nouvelle action n'est pas autorisée. Et j'ai juste une page qui dit littéralement que ce texte n'est pas autorisé. C' est tout ce qui se passe. Il y a jumbotron pas autoriser, sorte que vous pouvez devenir fou avec votre créativité. Trouvez un PCC personnalisé agréable. Vous ne transmettrez pas la sortie nette. C' est tout ce qui se passe vraiment. Alors testons ça. Je vais juste essayer de naviguer vers une page que je sais que je ne peux pas obtenir trop tant que je ne suis pas connecté. Et puis vous voyez pas autorisé. D'accord. À ce stade, nous pourrions probablement voir s'il y a une tentative d'Ambrose vers une page où il y a une balise non autorisée et l'utilisateur n'est pas mal, authentifié, puis redirigé vers la page de connexion, n'est-ce pas ? Cela serait plus logique si je suis connecté en tant qu'utilisateur. Et une fois que je reçois, je donne juste des idées à tenir, pour contrôler votre application grandit si j'essaie de me connecter en tant qu'utilisateur régulier. Et puis j'essaie encore une fois d'arriver à la page d'administration, je ne suis pas autorisé. Cependant, je peux naviguer vers une page où je suis autorisé par l'outil Bowl et que je reçois une erreur. Donc je n'ai même pas testé celui-ci correctement et c'est juste devant vous et c'est bien. Il est bon de voir que ces échecs provoqueraient ceci est une autre exception. Et c'est plus que probable parce que j'ai la règle d'authentification sans attribut L'auteur avec plus de règles, n'est-ce pas ? J' essaie donc d'arriver à un endroit qui n'a pas de lignes dans les attributs auth. Et puis à cause de cet échec est attraper l'exception. Donc maintenant, il va aller à la page d'erreur barre oblique d'accueil, qui va juste dire qu'il y avait une erreur en essayant de terminer votre commande. Donc, bien sûr, c'est un hareng rouge parce que ce n'est pas vraiment le problème. J' essaie d'accéder à cette page. D'accord. Je ne suis pas autorisé. Cela semble un peu mieux si j'ai essayé d'arriver à l'une des demandes créées. D' accord, donc c'est là. Donc, chaque fois qu'il y a un drapeau d'autorisation avec plus de lignes, cela va lancer une erreur. Et c'est ce qui se passe Parce que les demandes de congé sont autorisées, mais il n'y a pas de règle de stipulation. Alors refluons à ça rapidement. Et c'était une bonne zone à obtenir car cela a inspiré un beaucoup meilleur et beaucoup plus fonctionnel bits de code dans ce refactor. Donc, je me suis débarrassé de certaines des ficelles magiques et je pense que la situation comptable beaucoup plus globale en ce qui concerne les règles, les stipulations, non ? Au départ, c'était juste si vous n'êtes pas administrateur, alors vous ne pouvez pas entrer. Mais si vous avez plusieurs rôles et même des utilisateurs avec plusieurs rôles, vous voulez vous assurer de tenir compte de toutes les situations, n'est-ce pas ? Donc, dans cette situation, j'ai dit que si les rôles de point d'authentification ou les attributs d'auteur ne sont pas égaux à null, il y a des rôles dans la liste. Ensuite, allez-y et obtenez le rôle de l'utilisateur. Bon, donc on a le rôle de type de réclamation. Bien sûr, vous n'avez pas besoin de mettre une instruction using pour cela. Et puis nous obtenons cette valeur. Ensuite, je vois si la liste des règles ne contient pas cette règle. Très bien, donc plusieurs rôles pourraient être utilisés pour sécuriser le point de terminaison. Un utilisateur peut avoir plusieurs rôles. Si cet utilisateur n'a aucun rôle et cela ne tient compte que de notre utilisateur avec une seule règle. Laisse-moi, laisse-moi revenir. C' est lorsqu'un seul rôle est attribué à un utilisateur. Vous devrez peut-être faire un peu plus fini, peut-être un pour chaque boucle ou utiliser autre méthode pour savoir si l'une des règles des utilisateurs, dans l'une des règles et à la place dans les attributs, mais juste, et tout ce que nous obtenons le une règle pour l'utilisateur et vérifier si la liste des règles sur les adolescents que le rôle de l'utilisateur. Et si ce n'est pas le cas, alors ils sont non autorisés pour cette demande particulière. Et c'est fondamentalement tout. Donc, vous pouvez jouer avec cela et vous pouvez voir que cette variable complète, mais si vous n'écrivez pas la citation assez attentivement, cela pourrait jeter l'application et abandonner un petit écran d'une erreur quand il n'y a vraiment rien de mal ou quand c'est de ta faute. Donc, vous voulez être très prudent quand vous avez 18 citation pour le middleware. Mais c'est vraiment très puissant. 40. Améliorer la vérification des données: Dans cette leçon, nous allons chercher à améliorer la vérification. Donc, jusqu'à présent, nous avons implémenté une certaine quantité d'audit dans nos modifications de sauvegarde où nous prenons chaque entité une fois qu'elle est hors entité de domaine de base, nous obtenons à définir les données de dernière modification et le gros créé automatiquement. Nous n'avons pas à le faire chaque fois que nous créons ces objets pour être sauvés, n'est-ce pas ? Donc, ce que nous allons faire est de créer un second contexte DB qui va réellement prendre en charge cet audit parce que ce que nous ne faisons pas actuellement est d'ajouter les noms de l'utilisateur ou le nom de l'utilisateur pour le créé par le dernier modifié par. Nous avons donc besoin d'un moyen d'amener l'utilisateur à terminer l'action dans la base de données automatiquement. Nous avons donc commencé cette activité avec un tout nouveau fichier que j'appelle contexte DB auditable. Maintenant, c'est une classe abstraite et elle hérite du contexte DB. Il a un constructeur qui est très similaire à la scène précédente dans le contexte DB de gestion des congés, sauf qu'il ne prend que le contexte DB , les options, donc il n'est pas tapé ou c'est dans l'autre, vous l'auriez vu comme il a réellement tapé pour le contexte DB. Eh bien, nous ne faisons pas ça cette fois, nous prenons juste des options. Très bien, alors nous avons notre propre implémentation d'un changement de sauvegarde. s'agit donc pas d'une tâche asynchrone virtuelle publique de remplacement. Retourner les modifications de sauvegarde int. Il prend un paramètre appelé nom d'utilisateur de chaîne, que je suis par défaut pour être système, ce qui signifie que si aucun nom d'utilisateur n'est fourni, alors le système est ce qui ira dans cette colonne de nom d'utilisateur. Donc, vous pouvez le faire si vous le souhaitez. Si vous avez une valeur par défaut, sinon vous pouvez simplement rencontrer cette valeur nulle. Donc, une fois de plus, ce n'est pas un remplacement. Donc, nous avons en fait la même chose pour chaque boucle qui traverse l'entrée et les blessures des camionneurs de changement basé sur la détection pour les entités de base. D' accord. Et puis nous disons d'aller de l'avant et de définir la date de dernière modification et la date ajoutée ou la date de création à chaque fois qu'une date est ajoutée. Maintenant, avant de continuer, je voudrais filtrer davantage cela parce que l'instructeur CI camionne tout si c'est non modifié, si c' est tout détaché, nous n'avons pas besoin de ces changements sur les choses tenues ne pas être modifié ou ajouté. Donc, je vais ajouter un filtre supplémentaire à cela où je vois obtenir ces entrées, les analyser dans l'entité de domaine de base. Mais où leurs états, donc q-dot état est ajouté ou modifié. Nous sommes donc intéressés uniquement à placer ces champs d'audit sur tout ce qui est mis à jour ou créé. Donc, alors je peux savoir, disons l'entité point d'entrée dernier modifié par est égal au nom d'utilisateur qui est passé. Très bien, et puis la similitude, je peux voir que CreatedBy est le nom d'utilisateur qui est passé. Bon, donc tout ça juste pour s'assurer que nous avons le nom d'utilisateur présent. Mais après cela, nous allons voir le résultat var est égal à 08 base. Donc, BS est encore une fois le contexte DB. Donc basé dot save change async, puis nous retournons ce résultat. Examinons maintenant les changements nécessaires pour les contextes DVI de gestion des congés d'origine. Un, je n'ai pas besoin de remplacer, voir si les changements ici à nouveau, donc je peux supprimer cela complètement. C' est un outil que je sais doit hériter des contextes DB vérifiables. C' est donc ce contextes DVI hérite de celui auditable, qui hérite alors des contextes DVI pour le auditable donne sa propre version. Je vais voir si les changements avant qu'il appellera la base Save Changes, ce qui est courtoisie des contextes DVI de toute façon. Donc, avec tout cela fait, nous pouvons maintenant modifier nos unités de travail. Parce que rappelez-vous, sachez que nous avons mis en œuvre que nous avons notre C de changements qui se produisent ici. Et cela est appelé dans le contexte. Avec cela injecté dans, je peux descendre à ma fonction de sauvegarde et je peux voir le nom d'utilisateur est égal aux contextes HTTP accesseur contextes HTTP, l'utilisateur trouve le prénom l'ID d'utilisateur parce que rappelez-vous que c'est là que nous sommes stockage de l'ID utilisateur. Donc bien, oui, donc j'utilise juste les types de réclamation personnalisés dot UID. Une autre raison que nous voulons éviter beaucoup de CNS extrême et pratique et propre qui ressemble, et nous obtenons cette valeur afin que nous puissions passer ce nom d'utilisateur dans cette méthode, qui sauterait ensuite ici, démarre des choses d'audit, puis enregistrer le changements réels dans le contexte DB et retourner les résultats si nous en avons besoin. C' est ainsi que vous pouvez améliorer l'audit. Donc, avec ce contexte DB auditable assis entre l'unité de travail et les contextes DVI réels. Il y a peu de choses que vous pouvez faire ici. Certaines personnes auraient en fait envie d'une base de données d'audit réelle, d'une table d'audit ou d'un ensemble de tables. Ils veulent enregistrer chaque axone qui est effectué contre ces entités, pas seulement assis ces champs, mais peut-être les répliquer ailleurs. Tout cela pourrait arriver ici. Je ne dirai pas que tout cela pourrait causer des limites. Mais j'ai vu où les gens font réellement un audit à part entière entre ceci, ce morceau de code et ce peu de code, non ? Donc unité, donc pour s'étend sur tout. Et puis pour chaque entité qui est là en attente d'être sauvée, nous les manipulons. Et puis on les sauve. 41. Conclusion: Je tiens à remercier les gars de m'en tenir à la fin de ce cours où nous n'avions pas nécessairement un système de gestion des congés des DSE entièrement fonctionnel à la fin de ce cours. Mais nous avons examiné quelques techniques avancées. Je sais que vous pouvez l'emporter et l'appliquer à vos routines quotidiennes. Pendant la durée de ce cours, nous avons écrit du code modulo testable, maintenable et réutilisable, et nous avons été sensibles aux principes architecturaux solides. Nous avons mis en œuvre la mer QRS et les médias à des modèles. Nous avons examiné les pratiques exemplaires en matière de séparation des préoccupations. Nous avons implémenté une API. Nous avons regardé comment le sécuriser avec l'authentification JWT et tenir pour consommer cela et l'utiliser à notre avantage dans une application client, nous avons beaucoup fait ensemble et je suis très reconnaissant une fois de plus pour votre dévouement et votre soutien et vous avez des suggestions. N' hésitez pas à les laisser dans la boîte à suggestions. Et je suis toujours ouvert aux commentaires. Merci encore une fois et en avoir un grand.