43 votes

Quel problème spécifique le modèle de référentiel résout-il?

(Note: Ma question est très similaire concerne que la personne qui a posé cette question il y a trois mois, mais il n'a jamais été répondu.)

J'ai récemment commencé à travailler avec MVC3 + Entity Framework et je lis que la meilleure pratique consiste à utiliser le modèle de référentiel à la centralisation de l'accès à la DAL. C'est également accompagnée par des explications que vous souhaitez conserver le DAL distinct du domaine, et en particulier la couche vue. Mais dans les exemples que j'ai vu le référentiel est (ou semble être) de retour DAL entités, c'est à dire dans mon cas, le référentiel serait de retour EF entités.

Donc ma question est, à quoi bon le référentiel si elle renvoie uniquement DAL entités? N'est-ce pas ajouter une couche de complexité qui n'élimine pas le problème du passage DAL entités autour de entre les couches? Si le modèle de référentiel crée un "point d'entrée unique dans le DAL", comment est-ce différent de l'objet de contexte? Si le référentiel fournit un mécanisme permettant de récupérer et de persister DAL objets, comment est-ce différent de l'objet de contexte?

Aussi, j'ai lu dans au moins un endroit que l'Unité de Travail modèle centralise l'accès au référentiel afin de gérer le contexte de données objet(s), mais je ne connaît pas pourquoi est-ce important que ce soit.

Je suis de 98,8% sûr que je suis absent quelque chose ici, mais à partir de mes lectures, je ne l'ai pas vu. Bien sûr, je peut tout simplement pas être en lisant les bonnes sources... :\

52voto

Eric King Points 4937

Je pense que le terme "référentiel" est communément pensé de la façon dont le "modèle de référentiel" est décrit par le livre des Modèles de l'Architecture des Applications d'Entreprise par Martin Fowler.

Un Référentiel est le médiateur entre le domaine et les données de la cartographie des couches, agissant comme un domaine de mémoire de l'objet de collection. Objets Client construire une requête spécifications de manière déclarative et de les soumettre à Référentiel pour la satisfaction. Les objets peuvent être ajoutés et supprimés à partir de le Référentiel, comme ils peuvent à partir d'une simple collection d'objets, et le mappage de code encapsulé par le Référentiel permettra de réaliser le approprié des opérations derrière les coulisses.

Sur la surface, Entity Framework accomplit tout cela, et peut être utilisé comme une simple forme d'un référentiel. Cependant, il peut y avoir plus d'un référentiel qu'une simple couche de données de l'abstraction.

Selon le livre Domain Driven Design par Eric Evans, un référentiel a ces avantages:

  • Ils présentent les clients avec un modèle simple pour l'obtention de la persistance des objets et la gestion de leur cycle de vie
  • Ils découplage de l'application et de la conception d'un domaine de la technologie de persistance, de base de données multiples stratégies, ou même de plusieurs sources de données
  • Ils communiquer les décisions de conception sur l'accès aux objets
  • Ils permettent le remplacement facile d'un mannequin de mise en œuvre, pour les tests unitaires (généralement à l'aide d'une collection en mémoire).

Le premier point équivaut approximativement à l'alinéa ci-dessus, et il est facile de voir que Entity Framework lui-même facilement parvient.

Certains diront que EF accomplit le deuxième point ainsi. Mais souvent EF est utilisé simplement pour faire de chaque table de base de données dans un EF entité, et de le transmettre par le biais de l'INTERFACE utilisateur. Il peut être abstraire le mécanisme d'accès aux données, mais il est à peine abstraction données relationnelles structure derrière les coulisses.

Dans les applications plus simples que la plupart des données orienté, cela peut ne pas sembler être un point important. Mais comme les applications des règles de domaine / une logique d'entreprise deviennent plus complexes, vous voudrez peut-être plus orienté objet. Il n'est pas rare que la structure relationnelle de données contient des particularités qui ne sont pas importantes pour le domaine des affaires, mais sont les effets secondaires du stockage de données. Dans de tels cas, il ne suffit pas de résumé le mécanisme de persistance, mais aussi de la nature de la structure de données elle-même. EF seul n'est généralement pas vous aider à le faire, mais un dépôt d'une couche de.

Comme pour le troisième avantage, EF ne rien faire (à partir d'un DDD point de vue) pour les aider. Généralement DDD utilise le référentiel qui n'est pas juste pour résumé le mécanisme de persistance des données, mais également pour fournir des contraintes autour de la façon dont certains peuvent avoir accès aux données:

Nous avons également besoin d'aucune requête d'accès pour les objets persistants, qui sont plus commode à trouver par la traversée. Par exemple, l'adresse d'une personne pourrait être demandée à partir de l'objet Personne. Et le plus important, tout objet interne pour un total est interdit d'accès, sauf par la traversée de la racine.

En d'autres termes, vous n'auriez pas un "AddressRepository' juste parce que vous avez une Adresse de la table dans votre base de données. Si votre conception choisit de gérer la façon dont l'Adresse objets sont accessibles de cette manière, le PersonRepository est l'endroit où vous permettrait de définir et de faire appliquer les choix de conception.

Aussi, un DDD référentiel serait généralement où certains concepts d'affaires relatives à des ensembles de données de domaine sont encapsulés. Un OrderRepository peut avoir une méthode appelée OutstandingOrdersForAccount qui retourne un sous-ensemble spécifique de Commandes. Ou un Client de référentiel peut contenir un PreferredCustomerByPostalCode méthode.

L'Entity Framework DataContext classes ne pas se prêtent bien à une telle fonctionnalité sans le dépôt d'une couche d'abstraction. Ils ne fonctionnent bien pour ce que DDD appels cahier des charges qui peuvent être de simples expressions booléennes envoyé à une méthode simple qui permettra d'évaluer les données à l'encontre de l'expression et de retour d'un match.

Comme pour le quatrième avantage, alors que je suis sûr qu'il ya certaines stratégies qui pourraient laisser un remplaçant pour le datacontext, en l'enveloppant dans un référentiel en fait très simple.

En ce qui concerne "Unité de Travail", voici ce que le DDD livre est-à-dire:

Le congé de contrôle de transaction pour le client. Bien que le DÉPÔT d'insérer et de supprimer de la base de données, il ne sera généralement pas commettre quoi que ce soit. Il est tentant de s'engager après l'enregistrement, par exemple, mais le client a sans doute le contexte correctement initier et commettre des unités de travail. La gestion des transactions sera plus simple si l' RÉFÉRENTIEL garde ses mains.

22voto

Dennis Traub Points 24186

L'Entity Framework DbContext essentiellement ressemble à un Référentiel (et une Unité de Travail ainsi). Vous n'avez pas nécessairement à l'abstrait loin dans les scénarios simples.

L'avantage principal de ce référentiel, c'est que votre nom de domaine peut être ignorants et indépendant du mécanisme de persistance. Dans une couche en fonction de l'architecture, les dépendances point de la couche d'INTERFACE utilisateur vers le bas à travers le domaine (ou habituellement appelé " business logic layer) pour la couche d'accès aux données. Cela signifie que l'INTERFACE utilisateur dépend de la BLL, qui lui-même dépend de la DAL.

Dans une architecture plus moderne (comme propagées par domain-driven design et d'autres orientée objet approches) le domaine doit avoir pas dirigées vers l'extérieur, dépendances. Cela signifie que l'INTERFACE utilisateur, le mécanisme de persistance et de tout le reste dépend du domaine, et non l'inverse.

Un dépôt sera alors représentée par le biais de son interface à l'intérieur du domaine mais qui ont sa mise en œuvre concrète à l'extérieur du domaine, dans le module de persistance. De cette façon, le domaine ne dépend que de l'interface abstraite, et non pas la mise en œuvre concrète.

Qui est fondamentalement l'orientation de l'objet versus programmation procédurale sur un plan architectural.

Voir aussi les Ports et les Cartes une.k.un. Hexagonal De L'Architecture.

Un autre avantage du référentiel, c'est que vous pouvez créer les mêmes mécanismes d'accès à diverses sources de données. Pas seulement pour les bases de données, mais basée sur le cloud magasins, les Api externe, les applications tierces, etc.

6voto

MikeSW Points 7100

Vous avez raison,dans ces cas simples, le référentiel est juste un autre nom pour un DAO et il apporte une seule valeur: le fait que vous pouvez passer de l'EF à l'autre l'accès aux données de la technique. Aujourd'hui, vous êtes à l'aide de MSSQL, demain vous aurez besoin d'un stockage dans le cloud. OU à l'aide d'un micro orm au lieu de EF ou la commutation de MSSQL MySql.

Dans tous ces cas, il est bon que vous utilisez un référentiel, comme le reste de l'application ne se soucient pas de stockage que vous utilisez actuellement.

Il y a aussi le peu de cas où vous obtenir des informations à partir de sources multiples (db + système de fichiers), les pensions de titres agira à titre de façade, mais il est encore un autre nom pour un DAO.

Un "vrai" référentiel est valide uniquement lorsque vous traitez avec de domaine/business objects, pour les données centrées sur les applications qui ne changera pas de stockage, l'ORM seul suffit.

2voto

Joe Enos Points 17442

Il serait utile dans les situations où vous avez plusieurs sources de données, et que vous voulez accéder à l'aide d'un uniforme de codage de la stratégie.

Par exemple, vous pouvez avoir plusieurs EF modèles de données et des données accessibles à l'aide du traditionnel ADO.NET avec stockées procs, et certaines données accessibles à l'aide d'un 3ème partie de l'API, et certains accessibles à partir d'une base de données Access de vie sur un Windows NT4 serveur assis sous une couverture de la poussière dans votre placard à balais.

Vous ne souhaitez pas que votre entreprise ou front-end couches pour se soucier de où les données proviennent de partir, si vous construisez un générique modèle de référentiel pour l'accès "data", plutôt que de l'accès "de données Entity Framework".

Dans ce scénario, votre référentiel implémentations seront différents les uns des autres, mais le code qui appelle ne sais pas la différence.

2voto

Baldy Points 2115

Compte tenu de votre scénario, je voudrais tout simplement opter pour un ensemble d'interfaces qui représentent ce que les structures de données (vos Modèles de Domaine) doivent être renvoyés à partir de votre couche de données. Votre application peut alors être un mélange de EF, Raw ADO.Net ou tout autre type de Magasin de Données/Fournisseur. La stratégie clé ici est que la mise en œuvre est rendue abstraite de l'immédiat consommateurs de Domaine de votre couche. Ceci est utile lorsque vous souhaitez unité de tester vos objets du domaine et, en moins de situations courantes, - modifier votre fournisseur de données / base de données de la plateforme tout à fait.

Vous devriez, si vous havent déjà, envisager l'utilisation d'un conteneur IOC qu'ils font le couplage de votre solution très facile par le biais de l'Injection de Dépendance. Il ya beaucoup de disponibles, personnellement, je préfère Ninject.

La couche domaine doit encapsuler tous de votre logique métier - les règles et les exigences du domaine du problème, et peut être consommée directement par votre MVC3 application web. Dans certaines situations, il est logique d'introduire une couche de services qui se trouve au-dessus de la couche domaine, mais ce n'est pas toujours nécessaire, et peut-être exagéré pour de simples applications web.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by: