86 votes

Comment utiliser le modèle de référentiel correctement?

Je me demande comment dois-je regroupe mes dépots? Comme dans les exemples que j'ai vu sur le asp.net mvc et dans mes livres, ils se sont contentés d'utiliser un référentiel par table de base de données. Mais cela ressemble à beaucoup de dépôts de vous amener à avoir à appeler beaucoup de dépôts plus tard, de se moquer et d'autres choses.

Donc je suppose que je devrais groupe. Cependant, je ne suis pas sûr de la façon de les regrouper.

Maintenant j'ai fait un enregistrement de Référentiel pour gérer tous mes enregistrement des trucs. Cependant il y a 4 tables j'ai besoin de mettre à jour et avant j'ai eu 3 référentiels pour ce faire.

Par exemple l'une des tables, une licence de la table. Lors de leur inscription, je regarde leur clé et vérifier pour voir si il existe dans la base de données. Maintenant ce qui se passe si j'ai besoin de vérifier cette clé de licence ou autre chose de ce tableau à un autre endroit, puis d'autres à l'enregistrement?

Un spot pourrait être de connexion(vérifier si la clé n'est pas expiré).

Donc, ce que je ferais dans cette situation? Réécrire le code à nouveau(pause SEC)? Essayez de merege ces 2 référentiels ensemble et espère qu'aucune des méthodes sont nécessaires dans certains autres points de temps(comme peut-être je pourrais avoir une méthode qui vérifie si le nom d'utilisateur est utilisé - peut-être que j'ai besoin que quelque part d'autre).

Aussi, si je les fusionner, j'aurais besoin de 2 couches de service qui vont dans le même référentiel, puisque je pense avoir de la logique pour les 2 parties d'un site serait long et j'aimerais avoir des noms comme ValidateLogin(), ValdiateRegistrationForm(),ValdiateLoginRetrievePassword (), etc.

Ou appelez le Dépôt de toute façon et juste avoir un nom à consonance bizarre?

Il semble difficile de faire un référentiel qui a un caractère suffisamment général pour le nom de sorte que vous pouvez l'utiliser pour de nombreuses taches de votre demande et encore un sens, et je ne pense pas que l'appel d'une autre référentiel dans un référentiel serait une bonne pratique?

41voto

Arnis L. Points 18316

Une chose que j'ai fait de mal quand il est joué autour avec un modèle de référentiel - tout comme vous, j'ai pensé que le tableau se rapporte à référentiel de 1:1. Si l'on applique quelques règles de Domain Driven Design - le groupement des référentiels de problème disparaît souvent.

Référentiel doit être conforme à la racine d'Agrégat et pas de table. Cela signifie - si l'entité ne doit pas vivre seul (c'est à dire - si vous avez un Registrant qui participe, en particulier, Registration) - c'est juste une entité, il n'a pas besoin d'un référentiel, il doit être mis à jour/création/récupéré par le biais du référentiel de l'ensemble de la racine il appartient.

Bien sûr, dans de nombreux cas, cette technique est de réduire le nombre de dépôts (en fait, c'est plutôt une technique à la structure de votre modèle de domaine) ne peut pas être appliquée parce que chaque entité est censé être un agrégat de la racine (qui dépend fortement de votre domaine, je peux vous fournir des aveugles devine seulement). Dans votre exemple - License semble être un agrégat de la racine parce que vous devez être en mesure de les vérifier avec un contexte de Registration de l'entité.

Mais cela ne veut pas nous restreindre à la cascade de dépôts (Registration dépôt est autorisé à référencer License référentiel si nécessaire). À ne pas nous restreindre à une référence License référentiel (préférable à travers Cio) directement à partir de Registration objet.

Juste essayer de ne pas conduire votre conception grâce à des complications fournis par des technologies ou d'un malentendu quelque chose. Le groupement des dépôts en ServiceX juste parce que vous ne voulez pas construire 2 dépôts n'est pas une bonne idée.

Bien mieux serait de lui donner un nom propre - RegistrationService c'est à dire

Mais les services doivent être évités en général ils sont souvent la cause qui conduit à l' anémie du modèle de domaine.

EDIT:
Commencez à utiliser le Cio. Il est vraiment à la soulage la douleur de l'injection de dépendances.
Au lieu d'écrire:

var registrationService = new RegistrationService(new RegistrationRepository(),  
      new LicenseRepository(), new GodOnlyKnowsWhatElseThatServiceNeeds());

vous serez en mesure d'écrire:

var registrationService = IoC.Resolve<IRegistrationService>();

P. s. Serait préférable d'utiliser dite commune localisateur de service , mais c'est juste un exemple.

5voto

neouser99 Points 1203

Une chose que j'ai commencé à le faire pour remédier à ce est en fait de développer des services qui enveloppent N référentiels. Nous espérons que votre DI Cio ou les cadres peuvent aider à rendre cela plus facile.

public class ServiceImpl {
    public ServiceImpl(IRepo1 repo1, IRepo2 repo2...) { }
}

Cela fait-il sens? Aussi, je comprends que le fait de parler de services dans ce manoir peut ou peut ne pas se conformer à DDD principes, je viens de le faire parce qu'il semble fonctionner.

2voto

Michael Mann Points 616

Ce que je fais c'est que j'ai une classe de base abstraite définie comme suit:

public abstract class ReadOnlyRepository<T,V>
{
     V Find(T lookupKey);
}

public abstract class InsertRepository<T>
{
     void Add(T entityToSave);
}

public abstract class UpdateRepository<T,V>
{
     V Update(T entityToUpdate);
}

public abstract class DeleteRepository<T>
{
     void Delete(T entityToDelete);
}

Vous pouvez alors déduire que vous référentiel à partir de la classe de base abstraite et prolonger votre référentiel unique tant au générique arguments diffèrent par exemple;

public class RegistrationRepository: ReadOnlyRepository<int, IRegistrationItem>,
                                     ReadOnlyRepository<string, IRegistrationItem>

etc....

J'ai besoin de le séparer des référentiels parce que nous avons des restrictions sur certains de nos référentiels et cela nous donne un maximum de flexibilité. Espérons que cette aide.

2voto

griegs Points 14142

J'ai ce que ma classe de dépôt et oui, je l'étendre dans le tableau / la zone de dépôt, mais encore j'ai parfois de briser SÈCHE.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MvcRepository
{
    public class Repository<T> : IRepository<T> where T : class
    {
        protected System.Data.Linq.DataContext _dataContextFactory;

        public IQueryable<T> All()
        {
            return GetTable.AsQueryable();
        }

        public IQueryable<T> FindAll(Func<T, bool> exp)
        {
            return GetTable.Where<T>(exp).AsQueryable();
        }

        public T Single(Func<T, bool> exp)
        {
            return GetTable.Single(exp);
        }

        public virtual void MarkForDeletion(T entity)
        {
            _dataContextFactory.GetTable<T>().DeleteOnSubmit(entity);
        }

        public virtual T CreateInstance()
        {
            T entity = Activator.CreateInstance<T>();
            GetTable.InsertOnSubmit(entity);
            return entity;
        }

        public void SaveAll()
        {
            _dataContextFactory.SubmitChanges();
        }

        public Repository(System.Data.Linq.DataContext dataContextFactory)
        {
            _dataContextFactory = dataContextFactory;
        }

        public System.Data.Linq.Table<T> GetTable
        {
            get { return _dataContextFactory.GetTable<T>(); }
        }

    }
}

MODIFIER

public class AdminRepository<T> : Repository<T> where T: class
{
    static AdminDataContext dc = new AdminDataContext(System.Configuration.ConfigurationManager.ConnectionStrings["MY_ConnectionString"].ConnectionString);

    public AdminRepository()
        : base( dc )
    {
    }

J'ai aussi un datacontext qui a été créé à l'aide de Linq2SQL.dbml classe.

Alors maintenant, j'ai un référentiel standard exécution standard des appels à l'instar de Tous et de Trouver et dans mon AdminRepository j'ai des appels spécifiques.

Ne pas répondre à la question de la SEC, mais je ne pense pas.

1voto

James Jones Points 3291

Voici un exemple d'un générique Référentiel de mise en œuvre à l'aide de FluentNHibernate. Il est capable de persister toute la classe que vous avez écrit un mappeur pour. Il est même capable de générer votre base de données basé sur le mappeur de classes.

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