De manière générale, il est préférable de ne pas laisser vos entités (modèles de base de données) s'échapper de votre couche de base de données. Cependant, comme pour tout ce qui concerne les logiciels, cela peut avoir ses inconvénients. Un tel inconvénient est qu'il commence à augmenter la complexité de votre couche de données car il implique de cartographier vos entités à leur DTO dans votre couche de base de données, laissant finalement des dépôts qui sont pleins de méthodes similaires retournant différents types DTO. Certaines personnes pensent également que l'exposition de IQueryables à partir de votre couche de données est également une mauvaise chose lorsque vous commencez à faire couler des abstractions vers différentes couches - bien que cela ait toujours semblé un peu extrême. Personnellement, je privilégie ce que je pense être une approche plus pragmatique et je préfère utiliser un outil comme AutoMapper pour mapper automatiquement mes entités à mes DTO dans la couche logique métier.
Par exemple:
// Initial configuration loaded on start up of application and cached by AutoMapper
AutoMapper.Mapper.CreateMap<BlogPostEntity, BlogPostDto>();
// Usage
BlogPostDto blogPostDto = AutoMapper.Mapper.Map<BlogPostDto>(blogPostEntity);
AutoMapper a également la possibilité de configurer la cartographie plus complexe, bien que vous devriez essayer d'éviter cela si possible en collant à flatter DTO.
En outre, une autre grande fonctionnalité d'AutoMapper est la possibilité de projeter automatiquement vos entités aux DTO. Il en résulte beaucoup plus propre SQL où seules les colonnes dans votre DTO sont interrogeables:
public IEnumerable<BlogPostDto> GetRecentPosts()
{
IEnumerable<BlogPostDto> blogPosts = this.blogRepository.FindAll().Project(this.mappingEngine).To<BlogPostDto>().ToList();
return blogPosts;
}
De plus, parfois toutes les données sont nécessaires pour être envoyées aux clients .. Si un Dto être créé pour les cas comme bien? Ou devrais-je retourner un modèle de domaine?
Les DTO doivent être créés pour ceux-ci. En fin de compte, vous ne voulez pas que votre client dépende de votre schéma de données, ce qui est exactement ce qui se passera si vous exposez vos entités.
Alternatives: Commande/Interrogation Ségrégation
Il me appartient de souligner également qu'il existe aussi d'autres alternatives à une architecture en couches typique, comme l'approche de commande/requête Ségrégation où vous modélisez vos commandes et requêtes via un médiateur. Je ne vais pas entrer dans trop de détails car c'est un tout autre sujet, mais c'est un que je préférerais définitivement sur une approche en couches discutée ci-dessus. Cela entraînerait la mise en correspondance de vos entités avec vos DTO directement dans la commande ou la requête modélisée.
Je recommande de jeter un oeil à Mediatr pour cela. L'auteur, Jimmy Bogard qui a également créé AutoMapper a également this video talking sur le même sujet.
Mais les objets de domaine ne seraient-ils pas similaires aux objets de données? Parce que dans les modèles de tables facture aura une liste d'éléments de factures ou quelque chose de similaire, ai-je tort? –
Oui, dans la plupart des cas, les objets de domaine et de base de données seront presque similaires mais pas identiques. Nous avons quelques cas où nous modifions ou optimisons un peu les données de la couche de domaine. Par exemple, la base de données stocke le taux d'imposition d'un «produit» uniquement s'il diffère du taux d'imposition par défaut. Mais dans la couche application, nous ne voulons pas rechercher le taux de taxe par défaut à chaque fois que nous traitons un produit, donc nous ajoutons le taux de taxe par défaut dans la couche de domaine. C'est pourquoi le type de données de Product.TaxRate dans la couche de domaine est 'double 'mais dans la couche de base de données il est' double?'. – krani
Donc vos cartes sont Dto -> Domaine -> Base de données Base de données -> domaine -> Dto N'est-ce pas trop de mappings pour une simple opération get par exemple? –