web-dev-qa-db-fra.com

Conventions de dénomination DAL, BAL et UI Layer

Je développe une application Web typique avec les couches suivantes

  1. Couche UI (MVC)
  2. Couche logique métier (BAL)
  3. Couche d'accès aux données (DAL)

Chaque couche a son propre objet DTO, y compris le BAL et le DAL. Mes questions à ce sujet sont les suivantes

  1. Le DTO retourné par le DAL est simplement converti en DTO correspondant dans le BAL et envoyé à la couche UI. Les attributs et la structure des objets DTO sont identiques dans certains cas. Dans de tels scénarios, il est préférable de simplement retourner le DTO dans le DAL à la couche UI sans inclure un objet intermédiaire.

  2. Quelle est la meilleure façon de nommer ces objets DTO et d'autres objets dans chaque couche. Dois-je utiliser un préfixe tel que DTOName, ServiceName? La raison pour laquelle je demande d'utiliser un préfixe est que si ce n'est pas le cas, les classes de ma solution se heurtent à d'autres classes du Framework et avec un préfixe, il est plus facile pour moi de comprendre où appartient chaque classe?

35
user3631883

Préface

J'espère que cela est évident, mais ... dans les espaces de noms suggérés ci-dessous, vous remplaceriez MyCompany et MyProject par les noms réels de votre entreprise et de votre projet.

DTO

Je recommanderais d'utiliser les mêmes classes DTO sur toutes les couches. Moins de points d'entretien de cette façon. Je les place généralement sous un espace de noms MyCompany.MyProject.Models, Dans leur propre projet VS du même nom. Et je les nomme généralement simplement d'après l'entité réelle qu'ils représentent. (Idéalement, les tables de base de données utilisent également les mêmes noms, mais il est parfois judicieux de configurer le schéma un peu différemment.)

Exemples: Person, Address, Product

Dépendances: aucune (autre que les bibliothèques .NET ou auxiliaires standard)

DAL

Ma préférence personnelle ici est d'utiliser un ensemble de classes DAL un pour un correspondant aux classes DTO, mais dans un espace de noms/projet MyCompany.MyProject.DataAccess. Les noms de classe se terminent ici par un suffixe Engine afin d'éviter les conflits. (Si vous n'aimez pas ce terme, alors un suffixe DataAccess fonctionnerait bien aussi. Soyez simplement cohérent avec ce que vous choisissez.) Chaque classe fournit des options CRUD simples frappant la base de données, en utilisant les classes DTO pour la plupart des entrées paramètres et types de retour (à l'intérieur d'un List générique lorsqu'il y en a plusieurs, par exemple, le retour d'une méthode Find()).

Exemples: PersonEngine, AddressEngine, ProductEngine

Dépendances: MyCompany.MyProject.Models

BAL/BLL

Également un mappage un pour un ici, mais dans un espace de noms/projet MyCompany.MyProject.Logic, Et avec des classes obtenant un suffixe Logic. Ce devrait être la couche seulement qui appelle le DAL! Les cours ici ne sont souvent qu'un simple passage au DAL, mais si et quand des règles métier doivent être mises en œuvre, c'est l'endroit idéal.

Exemples: PersonLogic, AddressLogic, ProductLogic

Dépendances: MyCompany.MyProject.Models, MyCompany.MyProject.DataAccess

API

S'il existe une couche d'API de services Web, j'utilise la même approche un pour un, mais dans un espace de noms/projet MyCompany.MyProject.WebApi, Avec Services comme suffixe de classe. (À moins que vous n'utilisiez l'API Web ASP.NET, auquel cas vous utiliserez bien sûr le suffixe Controller à la place).

Exemples: PersonServices, AddressServices, ProductServices

Dépendances: MyCompany.MyProject.Models, MyCompany.MyProject.Logic (Ne contournez jamais cela en appelant directement le DAL!)

ne observation sur la logique métier

Il semble de plus en plus courant que les gens omettent le BAL/BLL et mettent en place une logique métier dans une ou plusieurs des autres couches, là où cela est le plus logique. Si vous faites cela, soyez absolument certain que (1) tout le code d'application passe par les couches avec la logique métier, et (2) il est évident et/ou bien documenté où chaque règle métier particulière a été mise en œuvre. En cas de doute, n'essayez pas cela à la maison.

ne note finale sur l'architecture au niveau de l'entreprise

Si vous êtes dans une grande entreprise ou dans une autre situation où les mêmes tables de base de données sont partagées entre plusieurs applications, je recommanderais de laisser la partie MyProject hors des espaces de noms/projets ci-dessus. De cette façon, ces couches peuvent être partagées par plusieurs applications frontales (et également des utilitaires en arrière-plan comme les services Windows). Mais ne faites cela que si vous avez une communication inter-équipes solide et des tests de régression automatisés approfondis en place !!! Sinon, les modifications apportées par une équipe à un composant de base partagé risquent de casser l'application d'une autre équipe.

48
Troy Gizzi

Je construis généralement une application comme

ProjectName.Core            // "framework"/common stuff
|- Extenders
|- Gravatar.cs

ProjectName.DataProvider    // database provider layer
|- Migrations
|- ApplicationDbContext.cs  // entity framework

ProjectName.Domain          // database objects
|- Post.cs
|- Tag.cs

ProjectName.Services        // validations, database stuff
|- PostService.cs

Il est quelque peu similaire à Sharp-Lite .

À propos des préfixes, je les déteste. Microsoft's Internal Coding Guidelines les déteste aussi. Il existe également un outil appelé StyleCop qui se plaint également des préfixes.

7
BrunoLM