Я пытаюсь понять Repository Pattern
при разработке приложения ASP.NET MVC (с использованием .NET 3.5, ASP.NET MVC 1.0 и Entity Framework). Я зашел достаточно далеко, чтобы внедрить зависимость и все работало с одним контроллером и одним типом сущности, но теперь я дошел до реализации поддержки связи между разными типами, и я застрял.
Во всех примерах, которые я видел, интерфейс репозитория называется что-то вроде IContactsRepository
и содержит (CRUD) методы, которые относятся только к Contact
элементам. Я хочу реализовать группировку Contacts
, поэтому у меня есть тип сущности Group
и интерфейс IGroupRepository
для обработки (CRUD) операций с группами.
- Куда относится метод, связанный с более чем одним типом сущности (в данном случае, например, метод
AddToGroup
, который добавляетContact
кGroup
)?
Я попытался создать более крупную структуру наследования для репозиториев, где создал следующие интерфейсы:
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
Затем я попытался создать главный репозиторий, наследующий IRepository
, следующим образом:
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"
}
Как только я пытаюсь вызвать один из методов в репозитории из моего контроллера с помощью этого кода
var contacts = _repository.Get();
Я получаю сообщение об ошибке сборки о двусмысленности между Get<Contact>()
, унаследованным через IContactsRepository
, и Get<Group>()
, пришедшим через IGroupsRepository
. Я понял, что это запрещено, потому что IRepository
наследует тот же общий интерфейс с разные типы (см. пример 5 в связанной статье).
Теперь, поскольку я наследую через другие интерфейсы, есть ли шанс, что я могу «переопределить имена» этих методов, например, как показано ниже?
IContactsRepository : ITypedRepository<Contact> { IEnumerable<Contact> GetContacts = ITypedRepository<Contact>.Get(); ... }
Таким образом, я могу получить к нему доступ из IRepository.Getcontacts
без какой-либо двусмысленности. Возможно ли это или есть ли способ решения этой проблемы?
И новый вопрос для уточнения:
Есть ли способ указать в вызове контроллера, какой из
Get()
методов мне нужен?Как лучше всего решить мою первоначальную проблему - потребность в репозитории, который обрабатывает множество вещей, а не только один тип сущности?
РЕДАКТИРОВАТЬ: Добавлен пример кода класса Repository
и вызова из Controller
.