Architectures courantes des applications webCommon web application architectures

« Si vous pensez qu’une bonne architecture est coûteuse, faites l’expérience d’une mauvaise architecture. »"If you think good architecture is expensive, try bad architecture." – Brian Foote and Joseph Yoder- Brian Foote and Joseph Yoder

La plupart des applications .NET conventionnelles sont déployées sous forme d’unités individuelles qui correspondent à un exécutable ou à une application web unique s’exécutant dans un seul domaine d’application IIS.Most traditional .NET applications are deployed as single units corresponding to an executable or a single web application running within a single IIS appdomain. Cette approche est le modèle de déploiement le plus simple et sert très bien de nombreuses applications publiques internes et plus petites.This approach is the simplest deployment model and serves many internal and smaller public applications very well. Toutefois, même avec ce déploiement en unités individuelles, la majorité des applications métier non triviales tirent avantage à avoir leur logique séparée en plusieurs couches.However, even given this single unit of deployment, most non-trivial business applications benefit from some logical separation into several layers.

Qu’est-ce qu’une application monolithique ?What is a monolithic application?

Une application monolithique est une application qui se comporte de façon totalement autonome.A monolithic application is one that is entirely self-contained, in terms of its behavior. Elle peut avoir des interactions avec d’autres services ou magasins de données pendant son exécution, mais son comportement est fondamentalement géré en interne. L’ensemble de l’application est généralement déployée comme une seule unité.It may interact with other services or data stores in the course of performing its operations, but the core of its behavior runs within its own process and the entire application is typically deployed as a single unit. Quand une application monolithique doit faire l’objet d’une mise à l’échelle horizontale, en général, l’application entière est dupliquée sur plusieurs serveurs ou machines virtuelles.If such an application needs to scale horizontally, typically the entire application is duplicated across multiple servers or virtual machines.

Applications tout-en-unAll-in-one applications

L’architecture d’une application peut se réduire à un seul projet.The smallest possible number of projects for an application architecture is one. Dans cette architecture, toute la logique de l’application est contenue dans un seul projet, compilé dans un assembly unique et déployé comme une seule unité.In this architecture, the entire logic of the application is contained in a single project, compiled to a single assembly, and deployed as a single unit.

Tout nouveau projet ASP.NET Core, créé dans Visual Studio ou à partir de la ligne de commande, est au début une simple application monolithique « tout-en-un ».A new ASP.NET Core project, whether created in Visual Studio or from the command line, starts out as a simple "all-in-one" monolith. Le projet contient le comportement complet de l’application, y compris la logique de présentation, métier et d’accès aux données.It contains all of the behavior of the application, including presentation, business, and data access logic. La figure 5-1 montre la structure de fichiers d’une application à projet unique.Figure 5-1 shows the file structure of a single-project app.

Application ASP.NET Core à projet unique

Figure 5-1.Figure 5-1. Application ASP.NET Core à projet unique.A single project ASP.NET Core app.

Dans un scénario de projet unique, la séparation des préoccupations s’obtient par l’utilisation de dossiers.In a single project scenario, separation of concerns is achieved through the use of folders. Le modèle par défaut inclut des dossiers distincts pour les responsabilités des modèles, vues et contrôleurs du schéma MVC, ainsi que des dossiers supplémentaires pour les services et les données.The default template includes separate folders for MVC pattern responsibilities of Models, Views, and Controllers, as well as additional folders for Data and Services. Dans cette organisation, les détails de présentation doivent être limités autant que possible au dossier Vues, et les détails d’implémentation de l’accès aux données doivent être limités aux classes stockées dans le dossier Données.In this arrangement, presentation details should be limited as much as possible to the Views folder, and data access implementation details should be limited to classes kept in the Data folder. La logique métier doit résider dans les services et les classes contenus dans le dossier Modèles.Business logic should reside in services and classes within the Models folder.

La solution monolithique à projet unique est simple, mais elle présente certains inconvénients.Although simple, the single-project monolithic solution has some disadvantages. Le nombre de fichiers et de dossiers augmente à mesure que le projet grossit et devient plus complexe.As the project's size and complexity grows, the number of files and folders will continue to grow as well. Les éléments sensibles de l’interface utilisateur (modèles, vues, contrôleurs) résident dans plusieurs dossiers qui ne sont pas regroupés par ordre alphabétique.User interface (UI) concerns (models, views, controllers) reside in multiple folders, which aren't grouped together alphabetically. Cela devient un réel problème quand des constructions de niveau interface utilisateur supplémentaires, telles que des filtres ou des classeurs de modèles (ModelBinder), sont ajoutées dans leurs propres dossiers.This issue only gets worse when additional UI-level constructs, such as Filters or ModelBinders, are added in their own folders. La logique métier est répartie entre les dossiers Models et Services, mais les dépendances entre les classes contenues dans ces dossiers ne sont pas clairement indiquées.Business logic is scattered between the Models and Services folders, and there's no clear indication of which classes in which folders should depend on which others. Cette mauvaise organisation au niveau du projet se traduit fréquemment par la création de code spaghetti.This lack of organization at the project level frequently leads to spaghetti code.

Pour résoudre ces problèmes, les applications se transforment souvent en solutions à projets multiples, où chaque projet est censé résider dans une couche spécifique de l’application.To address these issues, applications often evolve into multi-project solutions, where each project is considered to reside in a particular layer of the application.

Présentation des couchesWhat are layers?

Quand une application devient complexe, un moyen de gérer cette complexité est de scinder l’application selon ses responsabilités ou préoccupations.As applications grow in complexity, one way to manage that complexity is to break up the application according to its responsibilities or concerns. Cette approche suit le principe de séparation des préoccupations et peut aider à maintenir une structure de code en pleine croissance, afin que les développeurs puissent facilement trouver où certaines fonctionnalités sont implémentées.This approach follows the separation of concerns principle and can help keep a growing codebase organized so that developers can easily find where certain functionality is implemented. L’architecture en couches offre d’autres avantages que la simple organisation du code.Layered architecture offers a number of advantages beyond just code organization, though.

En effet, l’organisation du code en couches permet également la réutilisation des fonctionnalités communes de bas niveau dans l’ensemble de l’application.By organizing code into layers, common low-level functionality can be reused throughout the application. Cette possibilité est intéressante, car elle réduit la quantité de code à écrire et permet la standardisation de l’application sur une implémentation unique, selon le principe DRY (« Ne vous répétez pas »).This reuse is beneficial because it means less code needs to be written and because it can allow the application to standardize on a single implementation, following the don't repeat yourself (DRY) principle.

Avec une architecture en couches, les applications peuvent appliquer des restrictions sur les échanges autorisés entre les différentes couches.With a layered architecture, applications can enforce restrictions on which layers can communicate with other layers. Cette architecture permet d’obtenir l’encapsulation.This architecture helps to achieve encapsulation. De cette façon, quand une couche est modifiée ou remplacée, seules les couches qui interagissent avec elle sont impactées.When a layer is changed or replaced, only those layers that work with it should be impacted. En limitant l’interdépendance des couches, l’impact des modifications peut être atténué afin qu’une modification donnée n’impacte pas l’application entière.By limiting which layers depend on which other layers, the impact of changes can be mitigated so that a single change doesn't impact the entire application.

Les couches (et l’encapsulation) facilitent le remplacement des fonctionnalités dans l’application.Layers (and encapsulation) make it much easier to replace functionality within the application. Par exemple, une application peut initialement utiliser sa propre base de données SQL Server pour la persistance, mais plus tard choisir d’utiliser une stratégie de persistance basée sur le cloud ou située derrière une API web.For example, an application might initially use its own SQL Server database for persistence, but later could choose to use a cloud-based persistence strategy, or one behind a web API. Si l’application a correctement encapsulé son implémentation de persistance dans une couche logique, cette couche spécifique à la SQL Server peut être remplacée par une nouvelle qui implémente la même interface publique.If the application has properly encapsulated its persistence implementation within a logical layer, that SQL Server-specific layer could be replaced by a new one implementing the same public interface.

Outre la possibilité de permuter des implémentations en réponse à des changements ultérieurs dans les exigences, les couches d’application facilitent également la permutation des implémentations pour les besoins de test.In addition to the potential of swapping out implementations in response to future changes in requirements, application layers can also make it easier to swap out implementations for testing purposes. Au lieu d’écrire des tests qui s’exécutent sur la couche des données réelles ou sur la couche de l’interface utilisateur de l’application, vous pouvez remplacer ces couches durant la phase de test par des implémentations fictives qui fournissent des réponses connues aux requêtes.Instead of having to write tests that operate against the real data layer or UI layer of the application, these layers can be replaced at test time with fake implementations that provide known responses to requests. Grâce à cette approche, les tests sont beaucoup plus faciles à écrire et beaucoup plus rapides à exécuter par rapport à l’exécution de tests sur l’infrastructure réelle de l’application.This approach typically makes tests much easier to write and much faster to run when compared to running tests against the application's real infrastructure.

La mise en couches logiques est une technique courante pour améliorer l’organisation du code dans les applications d’entreprise. Le code peut être organisé en couches de plusieurs façons.Logical layering is a common technique for improving the organization of code in enterprise software applications, and there are several ways in which code can be organized into layers.

Notes

Les couches représentent une séparation logique au sein de l’application.Layers represent logical separation within the application. Si la logique de l’application est répartie physiquement entre plusieurs serveurs ou processus séparés, ces différentes cibles de déploiement physiques sont appelées niveaux.In the event that application logic is physically distributed to separate servers or processes, these separate physical deployment targets are referred to as tiers. Il est possible, et relativement courant, de déployer une application en N couches sur un seul niveau.It's possible, and quite common, to have an N-Layer application that is deployed to a single tier.

Applications avec une architecture en N couches conventionnelleTraditional "N-Layer" architecture applications

La figure 5-2 illustre l’organisation la plus courante d’une logique d’application en couches.The most common organization of application logic into layers is shown in Figure 5-2.

Couches d’application standard

Figure 5-2.Figure 5-2. Couches d’application classiques.Typical application layers.

Ces couches sont souvent abrégées comme ceci : UI (couche d’interface utilisateur), BLL (couche métier) et DAL (couche d’accès aux données).These layers are frequently abbreviated as UI, BLL (Business Logic Layer), and DAL (Data Access Layer). Avec cette architecture, les utilisateurs effectuent des requêtes par le biais de la couche UI, qui interagit uniquement avec la couche BLL.Using this architecture, users make requests through the UI layer, which interacts only with the BLL. La couche BLL, à son tour, peut appeler la couche DAL pour les requêtes d’accès aux données.The BLL, in turn, can call the DAL for data access requests. La couche UI ne doit pas directement adresser des requêtes à la couche DAL, ni interagir avec persistance directement par d’autres moyens.The UI layer shouldn't make any requests to the DAL directly, nor should it interact with persistence directly through other means. De même, la couche BLL doit uniquement interagir avec persistance en passant par la couche DAL.Likewise, the BLL should only interact with persistence by going through the DAL. De cette manière, chaque couche a sa propre responsabilité connue.In this way, each layer has its own well-known responsibility.

Cette approche en couches classique a un inconvénient, à savoir que les dépendances de compilation s’exécutent de haut en bas.One disadvantage of this traditional layering approach is that compile-time dependencies run from the top to the bottom. Autrement dit, la couche UI dépend de la couche BLL, qui dépend elle-même de la couche DAL.That is, the UI layer depends on the BLL, which depends on the DAL. La couche BLL, qui contient généralement la logique la plus importante de l’application, est dépendante des détails d’implémentation de l’accès aux données (et souvent de l’existence d’une base de données).This means that the BLL, which usually holds the most important logic in the application, is dependent on data access implementation details (and often on the existence of a database). Il est souvent difficile de tester la logique métier dans ce type d’architecture, car il faut utiliser une base de données de test.Testing business logic in such an architecture is often difficult, requiring a test database. Le principe d’inversion des dépendances peut être une solution à ce problème, comme vous le verrez dans la section suivante.The dependency inversion principle can be used to address this issue, as you'll see in the next section.

La figure 5-3 montre un exemple de solution qui scinde l’application en trois projets par responsabilité (ou couche).Figure 5-3 shows an example solution, breaking the application into three projects by responsibility (or layer).

Application monolithique simple avec trois projets

Figure 5-3.Figure 5-3. Application monolithique simple constituée de trois projets.A simple monolithic application with three projects.

Même si cette application utilise plusieurs projets à des fins d’organisation, elle reste déployée en tant qu’unité simple et ses clients interagissent avec elle en la considérant comme une application web unique.Although this application uses several projects for organizational purposes, it's still deployed as a single unit and its clients will interact with it as a single web app. Cela simplifie nettement le processus de déploiement.This allows for very simple deployment process. La figure 5-4 montre comment une application de ce type peut être hébergée en utilisant Azure.Figure 5-4 shows how such an app might be hosted using Azure.

Déploiement simple d’une application web Azure

Figure 5-4.Figure 5-4. Déploiement simple d’une application web AzureSimple deployment of Azure Web App

Quand l’application doit grossir, des solutions de déploiement plus complexes et robustes peuvent être nécessaires.As application needs grow, more complex and robust deployment solutions may be required. La figure 5-5 montre un exemple de plan de déploiement plus complexe qui prend en charge des fonctionnalités supplémentaires.Figure 5-5 shows an example of a more complex deployment plan that supports additional capabilities.

Déploiement d’une application web sur Azure App Service

Figure 5-5.Figure 5-5. Déploiement d’une application web sur Azure App ServiceDeploying a web app to an Azure App Service

En interne, l’organisation de ce projet en plusieurs projets par responsabilité facilite la maintenance de l’application.Internally, this project's organization into multiple projects based on responsibility improves the maintainability of the application.

Il est possible d’augmenter ou de diminuer la taille des instances de cette unité pour tirer parti de l’extensibilité à la demande sur le cloud.This unit can be scaled up or out to take advantage of cloud-based on-demand scalability. L’augmentation de la taille des instances revient à ajouter de l’UC, de la mémoire, de l’espace disque ou d’autres ressources sur le ou les serveurs qui hébergent votre application.Scaling up means adding additional CPU, memory, disk space, or other resources to the server(s) hosting your app. Le scale-out revient à ajouter des instances supplémentaires de ces serveurs, qu’il s’agisse de serveurs physiques, de machines virtuelles ou de conteneurs.Scaling out means adding additional instances of such servers, whether these are physical servers, virtual machines, or containers. Quand votre application est hébergée sur plusieurs instances, un équilibreur de charge assigne les requêtes aux différentes instances de l’application.When your app is hosted across multiple instances, a load balancer is used to assign requests to individual app instances.

L’approche la plus simple pour mettre à l’échelle une application web dans Azure est de configurer la mise à l’échelle manuellement dans le plan App Service de l’application.The simplest approach to scaling a web application in Azure is to configure scaling manually in the application's App Service Plan. La figure 5-6 illustre le tableau de bord Azure qui permet de configurer le nombre d’instances au service d’une application.Figure 5-6 shows the appropriate Azure dashboard screen to configure how many instances are serving an app.

Mise à l’échelle du plan App Service dans Azure

Figure 5-6.Figure 5-6. Mise à l’échelle du plan App Service dans Azure.App Service Plan scaling in Azure.

Architecture propreClean architecture

Les applications conçues selon le principe d’inversion des dépendances et les principes DDD (conception pilotée par le domaine) présentent au final plus ou moins la même architecture.Applications that follow the Dependency Inversion Principle as well as the Domain-Driven Design (DDD) principles tend to arrive at a similar architecture. Les noms donnés à cette architecture ont beaucoup varié au fil des années.This architecture has gone by many names over the years. Au début, on l’a nommée architecture hexagonale, puis architecture ports-adaptateurs.One of the first names was Hexagonal Architecture, followed by Ports-and-Adapters. Plus récemment, on l’a appelée architecture en oignon ou architecture propre.More recently, it's been cited as the Onion Architecture or Clean Architecture. Cette dernière désignation, architecture propre, est celle utilisée pour qualifier l’architecture utilisée dans ce livre électronique.The latter name, Clean Architecture, is used as the name for this architecture in this e-book.

L’application de référence eShopOnWeb utilise l’approche propre à l’architecture pour organiser son code en projets.The eShopOnWeb reference application uses the Clean Architecture approach in organizing its code into projects. Vous pouvez trouver un modèle de solution que vous pouvez utiliser comme point de départ pour votre propre ASP.NET Core sur le référentiel GitHub /cleanarchitecture .You can find a solution template you can use as a starting point for your own ASP.NET Core on the ardalis/cleanarchitecture GitHub repository.

L’architecture propre met la logique métier et le modèle d’application au centre même de l’application.Clean architecture puts the business logic and application model at the center of the application. Au lieu que la logique métier dépende des préoccupations de l’accès aux données ou d’une autre infrastructure, cette dépendance est inversée : les détails de l’infrastructure et de l’implémentation dépendent du noyau de l’application.Instead of having business logic depend on data access or other infrastructure concerns, this dependency is inverted: infrastructure and implementation details depend on the Application Core. Cette fonctionnalité est obtenue en définissant des abstractions, ou interfaces, dans le noyau de l’application, qui sont ensuite implémentées par les types définis dans la couche d’infrastructure.This functionality is achieved by defining abstractions, or interfaces, in the Application Core, which are then implemented by types defined in the Infrastructure layer. Cette architecture est souvent représentée sous la forme d’une série de cercles concentriques, à l’image des couches d’un oignon.A common way of visualizing this architecture is to use a series of concentric circles, similar to an onion. La figure 5-7 montre un exemple de ce style de représentation architecturale.Figure 5-7 shows an example of this style of architectural representation.

Architecture propre ; représentation des couches en oignon

Figure 5-7.Figure 5-7. Architecture propre ; représentation des couches en oignonClean Architecture; onion view

Dans ce diagramme, le flux des dépendances va du cercle extérieur vers le cercle le plus intérieur.In this diagram, dependencies flow toward the innermost circle. La couche Noyau de l’application tire son nom de sa position au cœur de ce diagramme.The Application Core takes its name from its position at the core of this diagram. Par ailleurs, comme vous pouvez constater sur le diagramme, la couche Noyau de l’application n’a aucune dépendance vis-à-vis des autres couches de l’application.And you can see on the diagram that the Application Core has no dependencies on other application layers. Les entités et les interfaces de l’application se trouvent au centre même du diagramme.The application's entities and interfaces are at the very center. Juste après vers l’extérieur, mais toujours dans la couche Noyau de l’application, viennent les services de domaine, qui implémentent généralement les interfaces définies dans le cercle central.Just outside, but still in the Application Core, are domain services, which typically implement interfaces defined in the inner circle. À l’extérieur de la couche Noyau de l’application, les couches Interface utilisateur et Infrastructure dépendent toutes deux de la couche Noyau de l’application, mais elles ne dépendent pas (nécessairement) l’une de l’autre.Outside of the Application Core, both the UI and the Infrastructure layers depend on the Application Core, but not on one another (necessarily).

La figure 5-8-X illustre un diagramme de couches horizontal plus classique, qui reflète mieux la dépendance entre la couche Interface utilisateur et les autres couches.Figure 5-8 shows a more traditional horizontal layer diagram that better reflects the dependency between the UI and other layers.

Architecture propre ; représentation horizontale des couches

Figure 5-8.Figure 5-8. Architecture propre ; représentation horizontale des couchesClean Architecture; horizontal layer view

Notez que les flèches pleines représentent les dépendances à la compilation, tandis que la flèche en pointillé représente une dépendance à l’exécution uniquement.Note that the solid arrows represent compile-time dependencies, while the dashed arrow represents a runtime-only dependency. Dans une architecture propre, la couche Interface utilisateur interagit avec les interfaces définies dans la couche Noyau de l’application au moment de la compilation. Dans l’idéal, elle ne doit pas avoir connaissance des types d’implémentation définis dans la couche Infrastructure.With the clean architecture, the UI layer works with interfaces defined in the Application Core at compile time, and ideally shouldn't know about the implementation types defined in the Infrastructure layer. Or, au moment de l’exécution, ces types d’implémentation sont nécessaires à l’exécution de l’application. Ils doivent donc être définis et transmis aux interfaces de la couche Noyau de l’application via l’injection de dépendances.At run time, however, these implementation types are required for the app to execute, so they need to be present and wired up to the Application Core interfaces via dependency injection.

La figure 5-9 est une représentation plus détaillée de l’architecture d’une application ASP.NET Core conçue selon ces recommandations.Figure 5-9 shows a more detailed view of an ASP.NET Core application's architecture when built following these recommendations.

Diagramme d’architecture de ASP.NET Core suivant l’architecture propre

Figure 5-9.Figure 5-9. Diagramme d’une architecture ASP.NET Core propre.ASP.NET Core architecture diagram following Clean Architecture.

Comme la couche Noyau de l’application ne dépend pas de la couche Infrastructure, il est très facile d’écrire des tests unitaires automatisés pour cette couche.Because the Application Core doesn't depend on Infrastructure, it's very easy to write automated unit tests for this layer. Les figures 5-10 et 5-11 montrent comment les tests s’intègrent à cette architecture.Figures 5-10 and 5-11 show how tests fit into this architecture.

UnitTestCore

Figure 5-10.Figure 5-10. Tests unitaires, couche Noyau de l’application isolée.Unit testing Application Core in isolation.

IntegrationTests

Figure 5-11.Figure 5-11. Tests d’intégration, implémentations dans Infrastructure avec des dépendances externes.Integration testing Infrastructure implementations with external dependencies.

Comme la couche Interface utilisateur n’a pas de dépendance directe vis-à-vis des types définis dans le projet Infrastructure, il est tout aussi simple de permuter les implémentations, que ce soit pour faciliter les tests ou pour répondre à une évolution des exigences de l’application.Since the UI layer doesn't have any direct dependency on types defined in the Infrastructure project, it's likewise very easy to swap out implementations, either to facilitate testing or in response to changing application requirements. Grâce à la prise en charge et à l’utilisation intégrée de l’injection de dépendances dans une application ASP.NET Core, cette architecture est la plus performante pour organiser des applications monolithiques non triviales.ASP.NET Core's built-in use of and support for dependency injection makes this architecture the most appropriate way to structure non-trivial monolithic applications.

Pour les applications monolithiques, le noyau de l’application, l’infrastructure et les projets d’interface utilisateur sont tous exécutés en tant qu’application unique.For monolithic applications, the Application Core, Infrastructure, and UI projects are all run as a single application. La figure 5-12 illustre un exemple d’architecture d’exécution d’une application.The runtime application architecture might look something like Figure 5-12.

Architecture ASPNET Core 2

Figure 5-12.Figure 5-12. Exemple d’architecture d’exécution d’une application ASP.NET Core.A sample ASP.NET Core app's runtime architecture.

Organisation du code dans une architecture propreOrganizing code in Clean Architecture

Dans une architecture propre, les responsabilités de chaque projet sont clairement établies.In a Clean Architecture solution, each project has clear responsibilities. À cet effet, certains types sont communs à chaque projet et vous trouverez souvent plusieurs dossiers correspondant à ces types dans le projet en question.As such, certain types belong in each project and you'll frequently find folders corresponding to these types in the appropriate project.

Noyau d’applicationApplication Core

La couche Noyau de l’application contient le modèle métier, qui définit les entités, les services et les interfaces.The Application Core holds the business model, which includes entities, services, and interfaces. Ces interfaces incluent des abstractions pour les opérations qui seront effectuées à l’aide de l’infrastructure, telles que l’accès aux données, l’accès au système de fichiers, les appels réseau, etc. Parfois, les services ou les interfaces définis au niveau de cette couche doivent fonctionner avec des types non-entité qui n’ont pas de dépendances sur l’interface utilisateur ou l’infrastructure.These interfaces include abstractions for operations that will be performed using Infrastructure, such as data access, file system access, network calls, etc. Sometimes services or interfaces defined at this layer will need to work with non-entity types that have no dependencies on UI or Infrastructure. Ils peuvent alors être définis comme objets de transfert de données (DTO).These can be defined as simple Data Transfer Objects (DTOs).

Types de la couche Noyau de l’applicationApplication Core types
  • Entités (classes persistantes du modèle métier)Entities (business model classes that are persisted)
  • InterfacesInterfaces
  • ServicesServices
  • Objets DTODTOs

InfrastructureInfrastructure

Le projet Infrastructure inclut généralement des implémentations de l’accès aux données.The Infrastructure project typically includes data access implementations. Dans une application web ASP.NET Core conventionnelle, ces implémentations comprennent la classe DbContext d’Entity Framework (EF), les objets Migration EF Core qui ont été définis, ainsi que les classes d’implémentation de l’accès aux données.In a typical ASP.NET Core web application, these implementations include the Entity Framework (EF) DbContext, any EF Core Migration objects that have been defined, and data access implementation classes. La méthode la plus courante pour abstraire le code d’implémentation de l’accès aux données est d’utiliser le modèle de conception de référentiel.The most common way to abstract data access implementation code is through the use of the Repository design pattern.

En plus des implémentations de l’accès aux données, le projet Infrastructure doit contenir les implémentations des services qui interagissent avec les préoccupations de l’infrastructure.In addition to data access implementations, the Infrastructure project should contain implementations of services that must interact with infrastructure concerns. Ces services doivent implémenter les interfaces définies dans la couche Noyau de l’application, et la couche Infrastructure doit donc référencer le projet Noyau de l’application.These services should implement interfaces defined in the Application Core, and so Infrastructure should have a reference to the Application Core project.

Types de la couche InfrastructureInfrastructure types
  • Types EF Core (DbContext, Migration)EF Core types (DbContext, Migration)
  • Types d’implémentation de l’accès aux données (référentiels)Data access implementation types (Repositories)
  • Services spécifiques de l’infrastructure (par exemple, FileLogger ou SmtpNotifier)Infrastructure-specific services (for example, FileLogger or SmtpNotifier)

Couche d’interface utilisateurUI Layer

Dans une application ASP.NET Core MVC, la couche Interface utilisateur est le point d’entrée de l’application.The user interface layer in an ASP.NET Core MVC application is the entry point for the application. Ce projet doit référencer le projet Noyau de l’application, et ses types doivent interagir avec l’infrastructure uniquement par le biais des interfaces définies dans la couche Noyau de l’application.This project should reference the Application Core project, and its types should interact with infrastructure strictly through interfaces defined in Application Core. Les instanciations directes des types de la couche Infrastructure (ou les appels statiques à ces types) ne doivent pas être autorisées dans la couche Interface utilisateur.No direct instantiation of or static calls to the Infrastructure layer types should be allowed in the UI layer.

Types de couche d’interface utilisateurUI Layer types
  • ContrôleursControllers
  • FiltresFilters
  • AffichagesViews
  • ViewModelsViewModels
  • DémarrageStartup

La classe Démarrage est responsable de la configuration de l’application, mais aussi de la transmission des types d’implémentation jusqu’aux interfaces, pour permettre le fonctionnement correct de l’injection de dépendances au moment de l’exécution.The Startup class is responsible for configuring the application, and for wiring up implementation types to interfaces, allowing dependency injection to work properly at run time.

Notes

Pour configurer l’injection de dépendances dans la section ConfigureServices du fichier Startup.cs associé au projet Interface utilisateur, celui-ci doit référencer le projet Infrastructure.In order to wire up dependency injection in ConfigureServices in the Startup.cs file of the UI project, the project may need to reference the Infrastructure project. Cette dépendance peut très facilement être supprimée en utilisant un conteneur d’injection de dépendances personnalisé.This dependency can be eliminated, most easily by using a custom DI container. Dans cet exemple, l’approche la plus simple est d’autoriser le projet Interface utilisateur à référencer le projet Infrastructure.For the purposes of this sample, the simplest approach is to allow the UI project to reference the Infrastructure project.

Conteneurs et applications monolithiquesMonolithic applications and containers

Vous pouvez créer une application (ou service) web unique et monolithique, et la déployer en tant que conteneur.You can build a single and monolithic-deployment based Web Application or Service and deploy it as a container. En interne, l’application peut ne pas être monolithique, mais être organisée en bibliothèques, composants ou couches.Within the application, it might not be monolithic but organized into several libraries, components, or layers. D’un point de vue externe, l’application est considérée comme un conteneur unique, de la même façon qu’un processus, une application web ou un service unique.Externally, it's a single container like a single process, single web application, or single service.

Pour gérer ce modèle, vous déployez un seul conteneur pour représenter l’application.To manage this model, you deploy a single container to represent the application. Pour effectuer une mise à l’échelle, vous ajoutez simplement des copies supplémentaires avec un équilibreur de charge en frontal.To scale, just add additional copies with a load balancer in front. Cette simplicité provient de la gestion d’un seul déploiement dans un seul conteneur ou une seule machine virtuelle.The simplicity comes from managing a single deployment in a single container or VM.

Figure 5-13

Vous pouvez inclure plusieurs couches internes, composants ou bibliothèques dans chaque conteneur, comme illustré dans la figure 5-13.You can include multiple components/libraries or internal layers within each container, as illustrated in Figure 5-13. Cependant, d’après le principe des conteneurs selon lequel « un conteneur fait une chose et la fait dans un seul processus », ce modèle monolithique peut être une source de conflit.But, following the container principle of "a container does one thing, and does it in one process", the monolithic pattern might be a conflict.

Cette approche présente des inconvénients si/quand l’application grandit, nécessitant sa mise à l’échelle.The downside of this approach comes if/when the application grows, requiring it to scale. Si l’application entière est mise à l’échelle, cela n’est pas vraiment un problème.If the entire application scales, it's not really a problem. Toutefois, dans la plupart des cas, la mise à l’échelle est nécessaire pour quelques parties de l’application seulement, mais elle est inutile pour d’autres composants moins utilisés.However, in most cases, a few parts of the application are the choke points requiring scaling, while other components are used less.

Dans l’exemple classique du commerce électronique, c’est probablement le composant des informations produit qui a le plus besoin d’être mis à l’échelle.Using the typical eCommerce example, what you likely need to scale is the product information component. Les clients qui recherchent des produits sont beaucoup plus nombreux que ceux qui en achètent.Many more customers browse products than purchase them. Plus de clients utilisent leur panier d’achat que ceux qui utilisent le pipeline de paiement.More customers use their basket than use the payment pipeline. Moins de clients ajoutent des commentaires ou consultent leur historique d’achat.Fewer customers add comments or view their purchase history. De même, seule une poignée d’employés, d’une seule région, doivent généralement gérer le contenu et les campagnes marketing.And you likely only have a handful of employees, in a single region, that need to manage the content and marketing campaigns. La mise à l’échelle de la conception monolithique déploie tout le code plusieurs fois.By scaling the monolithic design, all the code is deployed multiple times.

En plus du problème de la mise à l’échelle globale, quand des modifications sont apportées à un seul composant, il faut refaire un test complet de l’application entière et redéployer intégralement toutes les instances.In addition to the "scale everything" problem, changes to a single component require complete retesting of the entire application, and a complete redeployment of all the instances.

L’approche architecturale monolithique est fréquemment choisie pour le développement dans les organisations.The monolithic approach is common, and many organizations are developing with this architectural approach. Beaucoup de ces organisations sont satisfaites des résultats obtenus, mais certaines se heurtent aux limites de ce modèle d’architecture.Many are having good enough results, while others are hitting limits. Les organisations ont souvent conçu leurs applications d’après ce modèle, car les outils et l’infrastructure étaient trop complexes pour concevoir des architectures orientées services (SOA). Par ailleurs, elles ne voyaient pas la nécessité de changer de modèle tant que leur application ne grossissait pas trop.Many designed their applications in this model, because the tools and infrastructure were too difficult to build service-oriented architectures (SOA), and they didn't see the need until the app grew. Si vous vous heurtez aux limites de l’approche monolithique, la prochaine étape logique pour vous est peut-être de scinder votre application pour mieux tirer parti des conteneurs et des microservices.If you find you're hitting the limits of the monolithic approach, breaking up the app to enable it to better leverage containers and microservices may be the next logical step.

Figure 5-14

Le déploiement d’applications monolithiques dans Microsoft Azure est possible en utilisant des machines virtuelles dédiées pour chaque instance.Deploying monolithic applications in Microsoft Azure can be achieved using dedicated VMs for each instance. Avec Azure Virtual Machine Scale Sets, vous pouvez facilement mettre à l’échelle les machines virtuelles.Using Azure Virtual Machine Scale Sets, you can easily scale the VMs. Azure App Service peut également exécuter des applications monolithiques et facilement mettre à l’échelle des instances sans nécessiter une gestion des machines virtuelles.Azure App Services can run monolithic applications and easily scale instances without having to manage the VMs. Azure App Service peut également exécuter des instances uniques de conteneurs Docker, ce qui simplifie le déploiement.Azure App Services can run single instances of Docker containers as well, simplifying the deployment. Avec Docker, vous pouvez déployer une seule machine virtuelle comme hôte Docker et exécuter plusieurs instances.Using Docker, you can deploy a single VM as a Docker host, and run multiple instances. Vous pouvez gérer la mise à l’échelle à l’aide de l’équilibreur de charge Azure, comme indiqué dans la figure 5-14.Using the Azure balancer, as shown in the Figure 5-14, you can manage scaling.

Le déploiement sur les différents hôtes peut être géré avec les techniques de déploiement traditionnelles.The deployment to the various hosts can be managed with traditional deployment techniques. Les hôtes Docker peuvent être gérés à l’aide de commandes exécutées manuellement, telles que docker run, ou de manière automatisée, comme les pipelines de livraison continue.The Docker hosts can be managed with commands like docker run performed manually, or through automation such as Continuous Delivery (CD) pipelines.

Application monolithique déployée comme conteneurMonolithic application deployed as a container

L’utilisation de conteneurs pour gérer les déploiements d’applications monolithiques présente des avantages.There are benefits of using containers to manage monolithic application deployments. La mise à l’échelle des instances des conteneurs est beaucoup plus rapide et facile que le déploiement de machines virtuelles supplémentaires.Scaling the instances of containers is far faster and easier than deploying additional VMs. Même si vous utilisez des groupes de machines virtuelles identiques pour mettre à l’échelle des machines virtuelles, leur instanciation prend du temps.Even when using virtual machine scale sets to scale VMs, they take time to instance. Quand une machine virtuelle est déployée en tant qu’instance de l’application, la configuration de l’application est gérée en interne par la machine virtuelle.When deployed as app instances, the configuration of the app is managed as part of the VM.

Le déploiement de mises à jour comme images Docker est beaucoup plus rapide et efficace du point de vue du réseau.Deploying updates as Docker images is far faster and network efficient. Les images Docker démarrent généralement en quelques secondes, ce qui accélère les lancements.Docker Images typically start in seconds, speeding rollouts. La suppression d’une instance Docker se fait simplement en exécutant une commande docker stop. Cette opération prend normalement moins d’une seconde.Tearing down a Docker instance is as easy as issuing a docker stop command, typically completing in less than a second.

Comme les conteneurs sont fondamentalement immuables par conception, vous n’avez jamais à vous soucier des machines virtuelles endommagées, tandis que les scripts de mise à jour peuvent oublier de tenir compte d’une configuration ou d’un fichier spécifique restant sur le disque.As containers are inherently immutable by design, you never need to worry about corrupted VMs, whereas update scripts might forget to account for some specific configuration or file left on the disk.

Vous pouvez utiliser des conteneurs d’ancrage pour un déploiement monolithique d’applications Web plus simples.You can use Docker containers for a monolithic deployment of simpler web applications. Cette approche améliore l’intégration continue et les pipelines de déploiement continu et permet de réussir le déploiement en production.This approach improves continuous integration and continuous deployment pipelines and helps achieve deployment-to-production success. Plus de « il fonctionne sur mon ordinateur, pourquoi ne fonctionne-t-il pas en production ? »No more “It works on my machine, why does it not work in production?”

Une architecture basée sur des microservices présente de nombreux avantages, mais ces avantages se payent par une complexité accrue.A microservices-based architecture has many benefits, but those benefits come at a cost of increased complexity. Dans certains cas, les coûts l’emportent sur les avantages, de sorte qu’il est préférable d’utiliser une application à déploiement monolithique s’exécutant dans un petit nombre de conteneurs, voire dans un seul conteneur.In some cases, the costs outweigh the benefits, so a monolithic deployment application running in a single container or in just a few containers is a better option.

Il n’est pas toujours évident de décomposer une application monolithique en plusieurs microservices bien distincts.A monolithic application might not be easily decomposable into well-separated microservices. Les microservices doivent fonctionner indépendamment les uns des autres pour optimiser la résilience de l’application.Microservices should work independently of each other to provide a more resilient application. Si vous ne pouvez pas proposer l’application par tranches de fonctionnalités indépendantes, la diviser ne fait qu’ajouter de la complexité.If you can't deliver independent feature slices of the application, separating it only adds complexity.

Une application n’est pas pour autant nécessairement amenée à mettre à l’échelle les fonctionnalités de façon indépendante.An application might not yet need to scale features independently. Bon nombre d’applications, quand elles ont besoin d’une mise à l’échelle qui va au-delà d’une instance unique, peuvent le faire par le biais du processus relativement simple de clonage intégral de cette instance.Many applications, when they need to scale beyond a single instance, can do so through the relatively simple process of cloning that entire instance. La tâche supplémentaire de séparer l’application en services discrets constitue un avantage minime lorsque la mise à l’échelle des instances complètes de l’application est simple et économique.The additional work to separate the application into discrete services provides a minimal benefit when scaling full instances of the application is simple and cost-effective.

Au stade initial du développement d’une application, vous n’avez peut-être pas une idée précise de là où se trouvent les limites fonctionnelles naturelles.Early in the development of an application, you might not have a clear idea where the natural functional boundaries are. Même à un stade de développement où le produit est viable, il est possible que cette séparation naturelle ne se dégage toujours pas.As you develop a minimum viable product, the natural separation might not yet have emerged. Certaines de ces conditions peuvent être passagères.Some of these conditions might be temporary. Vous pouvez commencer par créer une application monolithique et séparer par la suite certaines fonctionnalités en les développant et les déployant sous forme de microservices.You might start by creating a monolithic application, and later separate some features to be developed and deployed as microservices. D’autres conditions peuvent être essentielles à l’espace du problème de l’application, ce qui signifie que l’application peut ne jamais être divisée en plusieurs microservices.Other conditions might be essential to the application's problem space, meaning that the application might never be broken into multiple microservices.

Séparer une application en divers processus distincts induit aussi des coûts.Separating an application into many discrete processes also introduces overhead. Il est plus complexe de séparer des fonctionnalités en différents processus.There's more complexity in separating features into different processes. Les protocoles de communication deviennent plus complexes.The communication protocols become more complex. Au lieu d’appeler des méthodes, vous devez utiliser des communications asynchrones entre les services.Instead of method calls, you must use asynchronous communications between services. Quand il s’agit de déplacer une architecture de microservices, vous devez ajouter la plupart des blocs de construction implémentés dans la version de microservices de l’application eShopOnContainers : gestion du bus d’événements, résilience des messages et nouvelles tentatives, cohérence éventuelle, etc.As you move to a microservices architecture, you need to add many of the building blocks implemented in the microservices version of the eShopOnContainers application: event bus handling, message resiliency and retries, eventual consistency, and more.

L’application de référence eShopOnWeb, bien plus simple, prend en charge l’utilisation de conteneurs monolithiques uniques.The much simpler eShopOnWeb reference application supports single-container monolithic container usage. L’application inclut une application web qui inclut les vues MVC, les API web et les pages Razor traditionnelles.The application includes one web application that includes traditional MVC views, web APIs, and Razor Pages. Cette application peut être lancée à partir de la racine de la solution à l’aide des commandes docker-compose build et docker-compose up.This application can be launched from the solution root using the docker-compose build and docker-compose up commands. Cette commande configure un conteneur pour l’instance web en utilisant le Dockerfile situé à la racine du projet web, et exécute le conteneur sur un port spécifié.This command configures a container for the web instance, using the Dockerfile found in the web project's root, and runs the container on a specified port. Vous pouvez télécharger la source de cette application sur GitHub et l’exécuter localement.You can download the source for this application from GitHub and run it locally. Même cette application monolithique gagne à être déployée dans un environnement de conteneurs.Even this monolithic application benefits from being deployed in a container environment.

Tout d’abord, un déploiement en conteneur signifie que chaque instance de l’application s’exécute dans le même environnement.For one, the containerized deployment means that every instance of the application runs in the same environment. Cette approche comprend l’environnement de développement dans lequel les premiers tests et développements ont eu lieu.This approach includes the developer environment where early testing and development take place. L’équipe de développement peut exécuter l’application dans un environnement à conteneurs qui correspond à l’environnement de production.The development team can run the application in a containerized environment that matches the production environment.

En outre, les applications en conteneur évoluent à un coût inférieur.In addition, containerized applications scale out at a lower cost. L’environnement à conteneurs permet un meilleur partage des ressources que les environnements à machines virtuelles classiques.Using a container environment enables greater resource sharing than traditional VM environments.

Enfin, la mise en conteneur de l’application contraint à établir une séparation entre la logique métier et le serveur de stockage.Finally, containerizing the application forces a separation between the business logic and the storage server. À mesure que l’application monte en charge, les différents conteneurs dépendent tous d’un même support de stockage physique.As the application scales out, the multiple containers will all rely on a single physical storage medium. Il s’agit généralement d’un serveur à haute disponibilité exécutant une base de données SQL Server.This storage medium would typically be a high-availability server running a SQL Server database.

Prise en charge de DockerDocker support

Le eShopOnWeb projet s’exécute sur .net.The eShopOnWeb project runs on .NET. Par conséquent, il peut s’exécuter dans des conteneurs Linux ou Windows.Therefore, it can run in either Linux-based or Windows-based containers. Notez que pour le déploiement de Docker, vous devez utiliser le même type d’hôte pour SQL Server.Note that for Docker deployment, you want to use the same host type for SQL Server. Les conteneurs Linux offrent un plus faible encombrement et sont à privilégier.Linux-based containers allow a smaller footprint and are preferred.

Vous pouvez utiliser Visual Studio 2017 ou ultérieur pour ajouter la prise en charge de Docker à une application existante en cliquant avec le bouton droit sur un projet dans l’Explorateur de solutions et en choisissant Ajouter > Prise en charge de Docker.You can use Visual Studio 2017 or later to add Docker support to an existing application by right-clicking on a project in Solution Explorer and choosing Add > Docker Support. Cette étape ajoute les fichiers requis et modifie le projet pour les utiliser.This step adds the files required and modifies the project to use them. Ces fichiers sont déjà en place dans l’exemple eShopOnWeb actuel.The current eShopOnWeb sample already has these files in place.

Le fichier docker-compose.yml au niveau de la solution contient des informations sur les images à générer et les conteneurs à lancer.The solution-level docker-compose.yml file contains information about what images to build and what containers to launch. Ce fichier vous permet d’utiliser la commande docker-compose pour lancer plusieurs applications en même temps.The file allows you to use the docker-compose command to launch multiple applications at the same time. Dans ce cas, il lance uniquement le projet Web.In this case, it is only launching the Web project. Vous pouvez aussi l’utiliser pour configurer des dépendances, telles qu’un conteneur de base de données distinct.You can also use it to configure dependencies, such as a separate database container.

version: '3'

services:
  eshopwebmvc:
    image: eshopwebmvc
    build:
      context: .
      dockerfile: src/Web/Dockerfile
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
    ports:
      - "5106:5106"

networks:
  default:
    external:
      name: nat

Le fichier docker-compose.yml référence le Dockerfile dans le projet Web.The docker-compose.yml file references the Dockerfile in the Web project. Le Dockerfile sert à spécifier le conteneur de base qui sera utilisé et la façon dont l’application sera configurée dans ce dernier.The Dockerfile is used to specify which base container will be used and how the application will be configured on it. Voici le Dockerfile de Web :The Web' Dockerfile:

FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /app

COPY *.sln .
COPY . .
WORKDIR /app/src/Web
RUN dotnet restore

RUN dotnet publish -c Release -o out

FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS runtime
WORKDIR /app
COPY --from=build /app/src/Web/out ./

ENTRYPOINT ["dotnet", "Web.dll"]

Résolution des problèmes liés à DockerTroubleshooting Docker problems

Une fois exécutée, l’application en conteneur continue de s’exécuter jusqu’à ce que vous l’arrêtiez.Once you run the containerized application, it continues to run until you stop it. Vous pouvez identifier les conteneurs qui s’exécutent avec la commande docker ps.You can view which containers are running with the docker ps command. Vous pouvez arrêter un conteneur en cours d’exécution à l’aide de la commande docker stop et en spécifiant son ID.You can stop a running container by using the docker stop command and specifying the container ID.

Notez que les conteneurs Docker en cours d’exécution peuvent être liés à des ports que vous pouvez tenter d’utiliser dans votre environnement de développement.Note that running Docker containers may be bound to ports you might otherwise try to use in your development environment. Si vous essayez d’exécuter ou de déboguer une application en utilisant le même port qu’un conteneur Docker en cours d’exécution, vous obtiendrez une erreur indiquant que le serveur ne peut pas se lier à ce port.If you try to run or debug an application using the same port as a running Docker container, you'll get an error stating that the server can't bind to that port. Une fois encore, l’arrêt du conteneur devrait résoudre le problème.Once again, stopping the container should resolve the issue.

Si vous voulez ajouter la prise en charge de Docker à votre application à l’aide de Visual Studio, veillez à ce que Docker Desktop s’exécute pendant l’opération.If you want to add Docker support to your application using Visual Studio, make sure Docker Desktop is running when you do so. L’Assistant ne fonctionnera pas correctement si Docker Desktop n’est pas en cours d’exécution lorsque vous démarrez l’Assistant.The wizard won't run correctly if Docker Desktop isn't running when you start the wizard. Par ailleurs, l’Assistant examine votre choix de conteneur actuel pour ajouter la prise en charge appropriée de Docker.In addition, the wizard examines your current container choice to add the correct Docker support. Si vous souhaitez ajouter la prise en charge des conteneurs Windows, vous devez exécuter l’Assistant pendant que vous avez installé le Bureau de l’ordinateur de poste de travail avec des conteneurs Windows configurés.If you want to add, support for Windows Containers, you need to run the wizard while you have Docker Desktop running with Windows Containers configured. Si vous souhaitez ajouter la prise en charge des conteneurs Linux, exécutez l’Assistant pendant que l’Assistant d’ancrage est en cours d’exécution avec des conteneurs Linux configurés.If you want to add, support for Linux containers, run the wizard while you have Docker running with Linux containers configured.

Informations de référence sur les architectures web courantesReferences – Common web architectures