28 votes

Avons-nous besoin d'utiliser le modèle de référentiel lorsque nous travaillons dans ASP.NET MVC avec des solutions ORM?

Je suis un peu curieux de savoir ce que l'expérience d'autres développeurs de l'application du modèle de Référentiel lors de la programmation en ASP.NET MVC avec Entity Framework ou NHibernate. Il me semble que ce modèle est déjà mis en œuvre dans l'ORM eux-mêmes. DbContext et DbSet<T> dans le Cadre de l'Entité et par l' ISession dans NHibernate. La plupart des préoccupations mentionnés dans l' Repository modèle que catalogués dans POEE et DDD - sont assez adéquatement mises en œuvre par ces Formulaires. À savoir ces préoccupations sont,

  • La persistance
  • OO Vue des données
  • Logique D'Accès Aux Données De L'Abstraction
  • Requête D'Accès Logique

En outre, la plupart des implemententations du modèle de référentiel que j'ai vu suivre ce modèle d'implémentation - en supposant que nous sommes le développement d'une application de blog.

NHibernate mise en œuvre:

public class PostRepository : IPostRepository
{
    private ISession _session;

    public PostRepository(ISession session)
    {
        _session = session;
    }

    public void Add(Post post)
    {
        _session.Save(post);
    }

    // other crud methods. 
}

Entity Framework:

public class PostRepository : IPostRepository
{
    private DbContext _session;

    public PostRepository(DbContext session)
    {
        _session = session;
    }

    public void Add(Post post)
    {
        _session.Posts.Add(post);
        -session.SaveChanges();
    }

    // other crud methods. 
}

Il me semble que lorsque nous utilisons l'Orm - tels que Nhibernate ou Entity Framework pour la création de ces référentiel de mise en œuvre sont redondantes. De plus, depuis ces patron des implémentations ne fait pas plus que ce qui est déjà là dans le ORM, ceux-ci agissent plus que le bruit qu'utile OO abstractions. Il semble en utilisant le modèle de référentiel dans la situation mentionnée ci-dessus n'est rien de plus que développeur d'auto glorification et la plus faste et cérémonie, sans aucune réalisation technique des prestations. Quelles sont vos pensées ??

12voto

jgauffin Points 51913

La réponse est non si vous n'avez pas besoin d'être en mesure de passer l'ORM ou être en mesure de tester toute la classe qui a une dépendance à l'ORM/base de données.

Si vous voulez être en mesure de passer l'ORM ou être en mesure de tester facilement vos classes qui utilise la base de données de la couche: Oui vous avez besoin d'un référentiel (avec une spécification d'interface).

Vous pouvez également passer une mémoire référentiel (ce que je fais dans mes tests unitaires), un fichier XML ou quoi que si vous utilisez un modèle de référentiel.

Mise à jour

Le problème avec la plupart des modèle de référentiel implémentations que vous pouvez trouver par une recherche sur Google, c'est qu'ils ne fonctionnent pas très bien dans la production. Ils manque des options pour limiter le résultat (la pagination) et la commande d'un résultat qui est assez extraordinaire.

Modèle de référentiel vient de la gloire quand il est combiné avec un UnitOfWork mise en œuvre et l'a prise en charge de la Spécification du modèle.

Si vous en trouvez un d'avoir tout cela, laissez-moi savoir :) (j'ai mon propre, d'exception pour un travail de spécification de la partie)

Mise à jour 2

Le référentiel est donc beaucoup plus que le simple accès à la base de données abstraites, telles que peut être fait par l'ORM est. Normal Référentiel de mise en œuvre doit gérer la totalité des entités (par exemple, Order et OrderLine). Bu de la manipulation dans le même référentiel de classe, vous pouvez toujours s'assurer que ceux qui sont construits correctement.

Mais bon vous le dire: C'est fait automatiquement pour moi par l'ORM. Eh bien, oui et non. Si vous créez un site web, vous plus susceptibles de vouloir modifier une seule ligne de commande. Avez-vous chercher de l'exécution de la commande, de la boucle au travers pour trouver l'ordre, puis l'ajouter à la vue?

En faisant ainsi vous présenter la logique de votre contrôleur qui n'appartiennent pas là. Comment voulez-vous faire quand un webservice veulent la même chose? Dupliquez votre code?

Par l'utilisation d'un ORM, c'est assez facile de chercher une entité à partir de n'importe où, myOrm.Fetch<User>(user => user.Id == 1) le modifier et l'enregistrer. Cela peut être très pratique, mais également ajouter des odeurs de code depuis la duplication de code et n'avons aucun contrôle sur la façon dont les objets sont créés, s'ils ont obtenu un permis valide de l'état ou de corriger les associations.

La prochaine chose qui vient à l'esprit est que vous pourriez être en mesure de s'inscrire sur des événements comme Créées, mises à Jour et Supprimées de manière centralisée. C'est facile si vous avez un dépôt.

Pour moi un ORM fournit une correspondance entre les classes de tableaux et rien de plus. J'aime toujours les envelopper dans des référentiels d'avoir le contrôle sur eux et obtenir un seul point de la modification.

2voto

MeF Corvi Points 167

Je pense qu'il a de sens que si vous voulez diminuer le niveau de dépendance. En résumé, vous pouvez avoir IPostRepository dans votre paquet infrastructures et de plusieurs implémentations de cette interface construite au-dessus de EF ou NH, ou quelque chose d'autre. Utile pour le TDD.

Dans la pratique, NH session (et contexte EF) met en œuvre quelque chose comme l ' "Unité de Travail" modèle. En outre, avec NH et le modèle de Référentiel, vous pouvez obtenir un grand nombre de bugs et questions architecturales.

Par exemple, NH entité peut être enregistré en contournant le Référentiel de mise en œuvre. Vous pouvez l'obtenir à partir de la session (Référentiel.Charge), changer l'une de ses propriétés, et de session d'appel.Flush (à la fin de la demande, par exemple, parce que Référentiel modèle ne suppose pas que le rinçage) - et vos modifications seront traitées avec succès en db.

1voto

James Morcom Points 679

Vous n'avez qu'à base de CRUD actions. Faire ces directement signifie que vous devez être au courant de transactions, de rinçage et d'autres choses qu'un référentiel peut conclure, mais je suppose que la valeur des dépôts devient plus évident quand vous pensez à ce sujet complexe requêtes d'extraction.

Imaginez alors que vous décidez d'utiliser les NHibernate session directement dans votre application de la couche.

Vous aurez besoin de faire l'équivalent des clauses where et ORDER BYs etc, en utilisant les requêtes HQL ou NHibernate critères. Cela signifie que votre code a pour référence NHibernate, et contient des idées spécifiques à NHibernate. Cela permet à votre application de dur à tester et plus difficile pour d'autres pas familier avec NH à suivre. Un appel à référentiel.GetCompletedOrders est beaucoup plus descriptif et réutilisables que celui qui comprend quelque chose comme "où IsComplete = true et IsDeleted = false..." etc.

Vous pouvez utiliser Linq to NHibernate au lieu de cela, mais vous avez maintenant la situation où l'on peut facilement oublier que vous travaillez sur un IQueryable. Vous pourriez vous retrouver chaînage des expressions Linq qui génèrent d'énormes requêtes lorsqu'ils exécutent, sans s'en rendre compte (je parle d'expérience)! Mike Hadlow a déclenché une conversation essentiellement sur ce sujet dans son post de mon référentiel exposer IQueryable.

N. b. Si vous n'aimez pas avoir beaucoup de méthodes sur des référentiels pour les requêtes différentes (comme GetCompletedOrders), vous pouvez utiliser la spécification des paramètres (Get(spécification)), qui vous permettent de spécifier des filtres, rangements etc. sans l'aide de données d'accès de la langue.

Retour à la liste des prestations de référentiel que vous avez donné:

  • La persistance
  • OO Vue des données
  • Logique D'Accès Aux Données De L'Abstraction
  • Requête D'Accès Logique

Vous pouvez voir que les points 3 et 4 ne sont pas fournis par l'aide de la persistance de classes directement, en particulier dans le monde réel, les scénarios d'extraction.

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:

X