web-dev-qa-db-fra.com

Conseils sur la mise en correspondance d'entités avec des objets de domaine

Je travaille actuellement sur un projet où nous commençons à construire une application en utilisant une approche DDD. Nous cherchons maintenant à utiliser le code Entity Framework 6 en premier pour nous aider avec la persistance des données. Ma question est de savoir comment gérer au mieux le mappage de données entre nos objets de domaine et les entités EF?

31
mstrand

Pour garder votre application et vous-même sain d'esprit à long terme, ne démarrez JAMAIS votre application DDD avec des problèmes liés à la persistance (quel db, quel orm, etc.) et TOUJOURS (oui, toujours) touchez le db comme dernière étape du développement.

Modélisez votre domaine et en fait tout autre modèle sauf la persistance. Utilisez le modèle de référentiel pour garder l'application découplée de la persistance. Définissez l'interface de dépôt selon les besoins de l'application et non liée à la méthode d'accès db (c'est pourquoi vous implémentez la persistance plus tard afin de ne pas être tenté de coupler votre application aux détails de persistance).

Écrivez des implémentations en mémoire pour les interfaces repo, cela signifie généralement un simple wrapper sur une liste ou un dictionnaire, donc c'est TRÈS rapide à écrire et plus important à changer. Utilisez-les pour tester et développer l'application.

Une fois que les interfaces sont stables et que l'application fonctionne, il est temps d'écrire l'implémentation de persistance où vous pouvez utiliser ce que vous voulez. Dans votre cas, EF et voilà la cartographie.

Maintenant, c'est très subjectif, il n'y a pas de bonne ou de mauvaise façon, il y a la façon dont VOUS préférez faire les choses.

Personnellement, j'ai l'habitude d'utiliser des souvenirs, donc j'obtiens le souvenir de l'objet de domaine, puis je le mappe manuellement aux entités (micro) ORM. La raison pour laquelle je le fais manuellement est que mes souvenirs contiennent des objets de valeur. Si j'utilisais AutoMapper, j'aurais besoin de le confier et, en substance, j'écrirais plus de code que de le faire manuellement

Mise à jour (2015)

Ces jours-ci, je viens de Json l'objet et soit utiliser un modèle de lecture spécifique ou le stocker directement dans un modèle de lecture avec une colonne Data qui contient l'objet sérialisé. J'utilise Mementos uniquement pour des cas très spécifiques. </ mise à jour>

En fonction de l'apparence de vos objets de domaine et de l'apparence des entités EF, vous pouvez vous en sortir en utilisant automapper pour la majorité du mappage. Vous aurez cependant plus de mal à tester vos référentiels.

C'est à vous comment vous le faites, trouvez la façon dont cela convient à votre style et c'est facilement maintenable mais JAMAIS JAMAIS concevoir ou modifier vos objets de domaine pour être plus compatibles ou pour correspondre aux entités ORM. Il ne s'agit pas de changer les bases de données ou les ORM, il s'agit de découpler correctement le domaine (et le reste de l'application) des détails de persistance (l'ORM).

Résistez donc à la tentation de réutiliser des choses qui sont des détails d'implémentation d'autres couches. La raison pour laquelle l'application est structurée en couches est que vous souhaitez un découplage. Continue comme ça.

49
MikeSW

Pourquoi n'utilisez-vous pas simplement des entités EF en tant qu'objets de domaine puisque vous envisagez d'utiliser d'abord le code Entity Framework 6 ? Vous devez donc d'abord concevoir le modèle de domaine puis la structure de la base de données.

J'ai utilisé NHibernate et je crois que dans EF, vous pouvez également spécifier des règles de mappage des tables DB vers vos objets POCO, en particulier avec EF6. C'est un effort supplémentaire pour développer une autre couche d'abstraction sur les entités EF. Laissez ORM en être responsable.

Je ne suis pas d'accord avec cet article que vous pourriez lire "Entity Framework 5 avec AutoMapper et Repository Pattern" et il y a beaucoup d'autres articles où les gens utilisent simplement des entités EF comme Objets de domaine :

AutoMapper vous aidera certainement lorsque vous commencerez à créer une couche de présentation et que vous ferez face à de nombreux modèles de vue spécifiques à l'interface utilisateur. Il est utile pour construire modèles anémiques et un peu inutile avec des objets de domaine réels lorsqu'il n'y a pas de setters publics.

Il y a un vieux post de Jimmy Bogard "Le cas de la cartographie bidirectionnelle dans AutoMapper" où il dit que "There is no two-way mapping because we never need two-way mapping."

Alors, pourquoi utilisons-nous AutoMapper? Nos cinq profils comprennent:

  • Du domaine au ViewModel (modèles de vue fortement typés pour MVC)
  • Du domaine au modèle d'édition (modèles de vue fortement typés pour les formulaires dans MVC)
  • D'EditModel à CommandMessages - passer de l'EditModel vaguement typé aux messages fortement typés et éclatés. Un seul EditModel peut générer une demi-douzaine de messages.
  • Du domaine au ReportModel - rapports Telerik fortement typés
  • Du domaine à EDI Model - modèles aplatis utilisés pour générer des rapports EDI
18
Ilya Palkin

Oh non, je n'ajouterais pas du tout cette couche supplémentaire.

NHibernate et Entity Framework Code-First (j'utiliserais EF) sont conçus pour résoudre ce problème exact - mapper vos objets de domaine à votre modèle relationnel (qui n'ont pas les mêmes contraintes sur leur conception, donc, et le seront probablement, être d'une forme différente).

Il semble juste dommage de gaspiller les excellentes capacités de cartographie d'EF et de le remplacer par quelque chose d'autre, même AutoMapper.

3
Neil Barnwell