1

J'essaie de comprendre le Repository Pattern, tout en développant une application ASP.NET MVC (en utilisant .NET 3.5, ASP.NET MVC 1.0 et Entity Framework). Je suis assez loin pour obtenir l'injection de dépendances et tout fonctionne avec un contrôleur et un type d'entité, mais maintenant je suis arrivé à implémenter un support pour une relation entre différents types, et je suis bloqué."Renommer" méthodes héritées dans l'interface en C#

Dans tous les exemples que j'ai vus, l'interface de référentiel s'appelle quelque chose comme IContactsRepository, et contient des méthodes (CRUD) qui sont concernées par Contact seulement. Je veux mettre en œuvre le regroupement de Contacts, donc j'ai un type d'entité appelé Group, et une interface IGroupRepository pour la gestion des opérations (CRUD) sur les groupes.

  • Où une méthode qui appartiennent concerne plus d'un type d'entité (dans ce cas, par exemple la méthode AddToGroup, qui ajoute un Contact à un Group)?

J'ai fait une tentative de structure d'héritage plus grande pour les dépôts, où je crée les interfaces suivantes:

ITypedRepository<T> 
{ 
    IEnumerable<T> GetAll(); 
    T Get(int id); 
    bool Add(T newObj); 
    bool Edit(T editedObj); 
    bool Delete(int id); 
} 

IContactsRepository : ITypedRepository<Contact> { } 

IGroupsRepository : ITypedRepository<Group> { 
    bool AddToGroup(int contactId, int groupId); 
} 

IRepository : IContactsRepository, IGroupsRepository 

J'ai ensuite essayé de créer un référentiel maître qui hérite IRepository, comme suit:

public class EntitiesRepository : IRepository 
{ 
    IEnumerable<Contact> IRepository<Contact>.Get() 
    { 
     throw new NotImplementedException(); 
    } 
    IEnumerable<Group> IRepository<Group>.Get() 
    { 
     throw new NotImplementedException(); 
    } 
    // Etc. All methods were generated by hitting [Ctrl]+[.] with the cursor on 
    // the interface inheritance reference to IRepository and selecting 
    // "Explicitly implement IRepository" 
} 

Dès que j'essaie d'appeler l'une des méthodes dans le Repository depuis mon Controller avec ce code

var contacts = _repository.Get(); 

Je reçois un message d'erreur de compilation sur les ambiguïtés entre Get<Contact>() qui a été héritée par IContactsRepository et Get<Group>() qui est venu par l'intermédiaire IGroupsRepository. J'ai compris que ceci n'est pas autorisé parce que le IRepositoryinherits the same generic interface with different types (voir l'exemple 5 dans l'article lié).

  • Maintenant, puisque je hérité par d'autres interfaces, est-il une chance que je pourrais « remplacer les noms » de ces méthodes, par exemple comme ci-dessous?

    IContactsRepository : ITypedRepository<Contact> 
    { 
        IEnumerable<Contact> GetContacts = ITypedRepository<Contact>.Get(); 
        ... 
    } 
    

De cette façon, je peux accéder à partir IRepository.Getcontacts sans aucune ambiguïté. Est-il possible, ou existe-t-il une solution de contournement à ce problème?

Et une nouvelle question, des précisions:

  • est-il de toute façon de préciser dans l'appel du contrôleur qui des Get() méthodes que je veux? Quelle est la meilleure façon de résoudre mon problème initial - le besoin d'un référentiel qui gère beaucoup de choses, au lieu d'un seul type d'entité?

EDIT: exemple de code ajoutée de Repository classe et appeler à partir Controller.

+0

Envisagez une implémentation d'interface explicite. Pour plus d'informations, voir http://stackoverflow.com/questions/1077816/access-modifiers-on-properties-in-c –

+0

Merci pour votre réponse - J'ai essayé cela, et mis à jour avec plus de code pour plus de clarté. –

+1

Voter pour cette question d'un point pour chaque fois que je ne comprends pas –

Répondre

0

Je pense que vous n'a pas besoin de toute cette complexité. Lorsque vous ajoutez un contact à un groupe, vous modifiez le groupe. Je suppose que vous avez une collection de contacts sur la classe de groupe. Après avoir ajouté un contact dans un groupe, vous devez simplement enregistrer le groupe. Donc, vous avez vraiment besoin d'une méthode AddContactToGroup, juste une méthode Save sur l'interface Repository Group ferait le même travail. De plus, vous n'avez pas besoin d'une nouvelle méthode pour chaque nouvelle propriété relationnelle sur le groupe.

Pour l'implémentation de la méthode Save elle-même, si vous utilisez NHibernate, la seule chose que vous devez faire est d'appeler la méthode appropriée.

0

Vous aurez probablement des méthodes spécialisées sur votre IGroupRepository en plus des méthodes CRUD:

IGroupRepository : ITypedRepository<Group> 
{ 
    bool AddContactToGroup(Group g, Contact C); 
} 
+0

Merci! Ce que j'ai déjà, mais c'est la chaîne de l'héritage qui ne fonctionne pas pour moi quand j'essaye cela. –

0

Ajouter des méthodes avec des noms non ambigus qui appellent les implémentations explicites:

public class EntitiesRepository : IRepository 
{ 
    IEnumerable<Contact> IRepository<Contact>.Get() 
    { 
     // Return something 
    } 
    IEnumerable<Group> IRepository<Group>.Get() 
    { 
     // Return something 
    } 

    public IEnumerable<Contact> GetContacts() 
    { 
     return (this as IRepository<Contact>).Get(); 
    } 

    public IEnumerable<Group> GetGroups() 
    { 
     return (this as IRepository<Group>).Get(); 
    } 
} 
+0

C'est très bien, en effet! Mais cela ne résout pas vraiment mon problème: si je le fais de cette façon, je n'ai rien dans l'interface IRepository qui m'assure que cette méthode existe (sauf si je définis chaque méthode nommée, mais c'est ce que je voulais éviter dans le première place...). Cela signifie que je ne peux pas découpler le contrôleur du dépôt via l'interface, et donc je ne serai pas en mesure de le tester de manière simple ... –

+1

Pourquoi avez-vous besoin de vous assurer qu'il existe? Il n'a besoin d'exister que si vous l'appelez explicitement. Quoi qu'il en soit, la méthode Get existe toujours en tant qu'implémentation explicite de IRepository . Dans le contrôleur, vous déclarez le référentiel comme IContactsRepository ou IGroupRepository, pas comme un IRepository, il n'y aura donc aucune ambiguïté. –

Questions connexes