Question

Je suis confus quant aux limites de ce qui est défini dans les référentiels et de ce qu’il faut laisser aux services. Le référentiel doit-il uniquement créer des entités simples correspondant à des tables à partir de la base de données ou peut-il créer un objet personnalisé complexe avec des combinaisons de ces entités?

en d'autres termes: les services doivent-ils effectuer diverses requêtes Linq to SQL sur le référentiel? Ou bien toutes les requêtes doivent-elles être prédéfinies dans le référentiel et la logique métier décide-t-elle simplement de la méthode à appeler?

Était-ce utile?

La solution

Vous avez en fait soulevé une question qui suscite actuellement de nombreuses discussions au sein de la communauté des développeurs - voir les commentaires suivants sur Mon référentiel doit-il exposer IQueryable?

Le référentiel peut - et devrait - créer des objets de combinaison complexes contenant plusieurs entités associées. Dans la conception pilotée par domaine, ils sont appelés agrégats : des collections d'objets associés organisées dans une structure cohérente. Votre code n'a pas besoin d'appeler GetCustomer () , GetOrdersForCustomer () , GetInvoicesForCustomer () séparément - vous appelez simplement myCustomerRepository. Load (customerId) , et vous récupérez un objet client profond avec ces propriétés déjà instanciées. Je devrais également ajouter que si vous renvoyez des objets individuels basés sur des tables de base de données spécifiques, il s'agit d'une approche parfaitement valide, mais ce n'est pas vraiment un référentiel per sé - c'est simplement une couche d'accès aux données.

D'un côté, il existe un argument convaincant selon lequel les objets Linq-to-SQL, avec leurs propriétés "intelligentes" et leur exécution différée (c'est-à-dire ne chargeant pas Customer.Orders tant que vous ne l'utilisez pas) sont une implémentation tout à fait valide de modèle de référentiel, car vous n’exécutez pas de code de base de données, vous exécutez des instructions LINQ (qui sont ensuite traduites en code de base de données par le fournisseur LINQ sous-jacent)

D’autre part, comme le souligne l’article de Matt Briggs, L2S est assez étroitement lié à la structure de votre base de données (une classe par table) et comporte des limites (par exemple, pas beaucoup de mappages), et vous serez peut-être mieux Désactivez l'utilisation de L2S pour accéder aux données dans votre référentiel, puis mappez les objets L2S sur vos propres objets de modèle de domaine et renvoyez-les.

Autres conseils

Un référentiel doit être le seul élément de votre application à connaître votre technologie d'accès aux données. Il ne devrait donc pas du tout renvoyer des objets générés par L2S, mais mapper ces propriétés pour modéliser vos propres objets.

Si vous utilisez ce type de modèle, vous voudrez peut-être repenser à L2S. Il génère une couche d'accès aux données pour vous, mais ne gère pas vraiment la non-concordance d'impédance, vous devez le faire manuellement. Si vous regardez quelque chose comme NHibernate, cette cartographie est faite de manière plus robuste. L2S est plutôt destiné à une application à 2 niveaux, dans laquelle vous voulez un DAL rapide et sale sur lequel vous pouvez étendre facilement.

Si vous utilisez LINQ, j’estime que le référentiel doit être un conteneur pour votre syntaxe LINQ. Cela vous donne un niveau d'abstraction des routines d'accès à la base de données à partir de l'interfaçage de votre objet modèle. Comme Dylan le mentionne ci-dessus, il existe d'autres points de vue sur le sujet. Certaines personnes aiment renvoyer IQueryable afin de pouvoir continuer à interroger la base de données plus tard après le référentiel. Il n’ya rien de mal à l’une ou l’autre de ces approches, tant que vos normes d’application sont claires. De plus amples informations sont disponibles sur les meilleures pratiques que j'utilise pour les référentiels LINQ ici.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top