Я пытаюсь понять 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
.